Vue笔记02-Vue组件化编程
原创
©著作权归作者所有:来自51CTO博客作者qq59ce45caba461的原创作品,请联系作者获取转载授权,否则将追究法律责任
模块与组件、模块化与组件化
在早期的前端开发中,HTML,CSS,JavaScript的引用关系是混乱的,给维护带来难度。
Vue中有一个组件的概念:用来实现局部(特定)功能效果的代码集合。
在Vue中,使用组件分为3步:定义组件、注册组件、使用组件。
在定义组件的时候,使用Vue.extend(option)
传入组件的配置,注意这里不要指定el,因为所有组件都被Vue实例对象管理,由实例对象中的el指明模板。组件中的data必须写成函数的形式,避免a组件修改data.x,影响到b组件中data.x的值。
在注册组件的时候,由分为局部注册和全局注册两种。
局部注册:在new Vue()
的时候传入components参数。
全局注册:在Vue实例化之前,使用Vue.component('组件名', 组件);
即可。
在使用组件的时候,直接通过标签即可引入组件。
非单文件组件
一个文件中,定义了多个组件。
<div id="root">
<hello></hello>
<hr>
<h1>{{msg}}</h1>
<hr>
<school></school>
<hr>
<student></student>
</div>
<div id="root2">
<hello></hello>
</div>
const school = Vue.extend({
template:`
<div class="demo">
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
data(){
return {
schoolName:'尚硅谷',
address:'北京昌平'
}
},
methods: {
showName(){
alert(this.schoolName);
}
},
});
const student = Vue.extend({
template:`
<div>
<h2>学生姓名:{{studentName}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
studentName:'张三',
age:18
}
}
});
const hello = Vue.extend({
template:`
<div>
<h2>你好啊!{{name}}</h2>
</div>
`,
data(){
return {
name:'Tom'
}
}
});
// 全局注册组件
Vue.component('hello',hello);
new Vue({
el:'#root',
data:{
msg:'你好啊!'
},
// 局部注册组件
components:{
school,
student
}
});
new Vue({
el:'#root2',
});
组件名如果只有一个单词,使用全小写或者首字母大写都可以。
组件名如果有多个单词,需要使用kebab-case的方式或者CamelCase方式(需要Vue脚手架,否则会报错),自定义组件名不能和现有的HTML元素重名,否则组件是不起作用的。在没有Vue脚手架的时候,不要写自闭合单标签,会导致后续组件无法渲染,这里先采用双标签写法。
组件是允许嵌套的,a组件包含b组件,那么需要先定义b组件,再定义a组件,将a组件放在b组件定义的components中。Vue中有一个习惯写法:定义一个app组件,通过app组件包括所有的自定义组件。
const student = Vue.extend({
name:'student',
template:`
<div>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data(){
return {
name:'尚硅谷',
age:18
}
}
});
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<student></student>
</div>
`,
data(){
return {
name:'尚硅谷',
address:'北京'
}
},
// school组件嵌套student组件
components:{
student
}
});
const hello = Vue.extend({
template:`<h1>{{msg}}</h1>`,
data(){
return {
msg:'欢迎来到尚硅谷学习!'
}
}
});
const app = Vue.extend({
template:`
<div>
<hello></hello>
<school></school>
</div>
`,
// app组件嵌套student组件和school组件
components:{
school,
hello
}
});
定义好一个组件之后,我们尝试在方法里输出this,看看组件里面的this是什么。
const person = Vue.extend({
name:'person',
template:`
<div>
<h2>姓名:{{name}}</h2>
<h2>地址:{{address}}</h2>
</div>
`,
data(){
return {
name:'王劭阳',
address:'山东济南'
}
}
});
console.log(person);
通过输出,我们看到this是VueComponent的构造函数,这个函数是Vue.extend
生成的,在页面上只需要写<person></person>
,Vue解析的时候,会帮助我们创建Person组件的实例对象,Vue会帮我们执行new VueComponent(options)
。每次调用Vue.extend()
,返回的都是一个全新的VueComponent。
在组件配置中的this指向VueComponent实例对象,在Vue配置中this指向Vue实例对象。
关于VueComponent和Vue,这里存在一个关系:VueComponent.prototype.__proto__ === Vue.prototype
,为了让VueComponent可以访问到Vue原型上的属性和方法。
prototype
是显式原型属性,__proto__
是隐式原型属性。
VueComponent在访问属性的时候,先在自身查找,自身查找不到再去原型里查找,原型里也查找不到,再去__proto__
里查找,也就是去Vue的原型里查找。
// 给Vue添加一个属性
Vue.prototype.x = 99;
//定义school组件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>名称:{{name}}</h2>
<h2>地址:{{address}}</h2>
<button @click="showX">点我输出x</button>
</div>
`,
data(){
return {
name:'王劭阳',
address:'山东济南'
}
},
methods: {
showX(){
// 组件里访问x属性,一直找到Vue里才找到x的值
console.log(this.x);
}
},
});
单文件组件
单文件组件就是一个*.vue的文件,一个*.vue文件就是一个组件,一个组件又分为3部分:template
、script
、style
,分别表示模板、脚本、样式。
Vue文件在命名的时候也有规范:一个单词的,直接首字母大写,比如Person.vue
,多个单词的使用大驼峰,比如MySchool.vue
。这样的好处是和Vue开发者工具里保持一致。
首先定义一个Person
组件。
<template>
<div class="demo">
<h2>名称:{{name}}</h2>
<h2>地址:{{address}}</h2>
<button @click="showName">点我提示名称</button>
</div>
</template>
<script>
// Vue.extend可以省略,要想让其他地方可以使用这个组件,需要用export default将组件进行暴露
export default {
name:'Person',// 指定这个组件的名称
data(){
return {
name:'王劭阳',
address:'山东济南'
}
},
methods: {
showName(){
alert(this.name);
}
},
}
</script>
<style>
.demo{background-color: orange;}
</style>
前面提到,所有的组件都由App.vue来管理,创建一个App.vue。
<template>
<!--如果template里有多个根节点,需要用div包裹一下,让这个div做根节点-->
<div>
<Person></Person>
<Person></Person>
</div>
</template>
<script>
//引入组件
import School from './Person.vue'
export default {
name:'App',
components:{
Person
}
}
</script>
有了App.vue,再往上就是Vue实例了,通过一个main.js
实现Vue的实例化,并把组件也加进去。
import App from './App.vue'
new Vue({
el:'#root',
// template:`<App></App>`,
components:{App},
});
还差一个模板文件:index.html。
<div id="root">
<App></App>
</div>
此时的项目是运行不起来的,需要有Vue脚手架才能运行。