目前存在问题
- 依赖关系混乱,不好维护。
- 代码复用率不高。
定义
实现应用中局部功能代码和资源的集合(css\js\html mp3\mp4\字体…)
作用
复用编码、简化项目编码、提高运行效率
示意图
种类
- 非单文件组件:一个文件中含有n个组件。
- 单文件组件:一个文件中含有1个组件。
使用组件步骤
- 定义组件(创建组件)
如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样 ,但也有点区别如下:
(1)el不要写,为什么?——最终所有组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
(2)data必须写成函数,为什么?——避免组件被复用时,数据存在引用关系。
备注:使用template可以配置组件结构。
- 注册组件
如何注册组件? 局部注册:靠new Vue的时候传入components选项
全局注册:靠Vue.component(‘组件名’,组件)
- 使用组件(写组件标签)
<div id="root"> <school></school><student></student><animal></animal> </div> <script> /* 全局注册 */ const animal = Vue.extend({ template: ` <div> <div>动物名:{{name}}</div> </div> `, data() { return { name: "小狗", }; }, }); Vue.component("animal",animal); /* 局部注册 */ const school = Vue.extend({ template: ` <div> <div>学校名:{{name}}</div> <div>学校地址:{{address}}</div> </div> `, data() { return { name: "xxx大学", address: "北京", }; }, }); const student = Vue.extend({ template: ` <div> <div>学生名:{{name}}</div> <div>性别:{{sex}}</div> </div> `, data() { return { name: "张三", sex: "男", }; }, }); const vm = new Vue({ el: "#root", components: { school, student, }, }); </script> ```
几个注意点
-
关于组件名:
(1)一个单词组成:第一种写法(首字母小写):school
第二种写法(首字母大写):School(2) 多个单词组成:
第一种写法(kebab-case):my-school
第二种写法(Camel-cse):MySchool(需要Vue脚手架支持) -
关于组件标签:
第一种写法:
<school></school>
第二种写法:<school/>
备注:不能使用脚手架时,会导致后续组件不能渲染 -
一个简写方式:
const shcool = Vue.extend(options)可简写为:const shool = options
备注
(1)组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
(2)可以使用name配置项目指定组件在开发工具中呈现的名字。
组件案例
name:'xiaodongwu', template: ` <div> <div>动物名:{{name}}</div> </div> `, data() { return { name: "小狗", }; }, }); ```
<div id="root">
<animal></animal>
</div>
<script>
/* 全局注册 */
const animal ={
name:'xiaodongwu',
template: `
<div>
<div>动物名:{{name}}</div>
</div>
`,
data() {
return {
name: "小狗",
};
},
};
Vue.component("animal",animal);
const vm = new Vue({
el: "#root",
});
</script>
组件嵌套
<div id="root"></div>
<script>
const Student = {
template: `<div>
学生名称:{{name}}-学生年龄:{{age}}
</div>`,
data() {
return {
name: "张三",
age: 18,
};
},
};
const School = {
template: `<div>
学校名称:{{name}}-学校地址:{{address}}
<Student></Student>
</div>`,
data() {
return {
name: "大学",
address: "北京",
};
},
components: {
Student,
},
};
const Animal = {
template: `<div>
动物名称:{{name}}
</div>`,
data() {
return {
name: "小狗",
};
},
};
const App = {
template: `<div>
<School></School>
<Animal></Animal>
</div>`,
components: {
School,
Animal,
},
};
const vm = new Vue({
template: ` <App></App>`,
el: "#root",
components: {
App,
},
});
</script>
关于VueComponent
- School组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的
- 我们只需要写
<school/>
或<school></school>
,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)- 特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent
- 关于this的指向:
(1)组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】
(2)new Vue(options)配置中:data函数、methods中的函数、watch中的函数、computed中的函数它们的this均是【Vue实例对象】- VueComponent的实例对象,以后简称vc(也可以称之为:组件实例对象)Vue的实例对象,以后称之为vm
内置关系
一个重要的内置关系:VueComponent.prototype.__proto__ == Vue.prototype
Vue.prototype.x = 99;
原理图:
为什么要有这个关系
让组件实例对象(vc)可以访问到Vue原型上的属性、方法。
prototype原理