目录
- 非文件组件使用步骤
- 定义组件
- 示例(第一部分):使用Vue.extend函数创建三个组件
- 注册组件
- 示例(第二部分):组件的全局和局部注册
- 组件使用
- 示例(第三部分):编写组件标签
- 最终结果
- 组件注意事项
- 组件嵌套
- 组件定义
- 组件注册
- 组件使用
- 其他需要注意的地方
本博客参考尚硅谷官方课程,详细请参考
- 【尚硅谷bilibili官方】
本博客以vue2作为学习目标(请勿混淆v2与v3的代码规范,否则可能出现报错),详细教程请参考
- 【 v2.x 官方文档】
非文件组件使用步骤
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
定义组件
使用Vue.extend(options)
创建组件,其中options和new Vue(options)时传入的那个options几乎一样,但也有区别
区别:
- 组件中el配置项不要写,为什么? ——— 最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。
- 组建中data配置项必须写成函数,为什么? ———— 避免组件被复用时,数据存在引用关系。
示例(第一部分):使用Vue.extend函数创建三个组件
<script>
//创建学校组件
const school = Vue.extend({
template: `
<div class="demo">
<h2>学校名称:{{schoolName}}(school组件)</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showName">点我提示学校名</button>
</div>
`,
data() {
return {
schoolName: "尚硅谷",
address: "北京昌平",
};
},
methods: {
showName() {
alert(this.schoolName);
},
},
});
//创建student组件
const student = Vue.extend({
template: `
<div>
<h2>学生姓名:{{studentName}}(student组件)</h2>
<h2>学生年龄:{{age}}</h2>
</div>
`,
data() {
return {
studentName: "张三",
age: 18,
};
},
});
//创建hello组件
const hello = Vue.extend({
template: `
<div>
<h2>你好啊!{{name}}(hello组件)</h2>
</div>
`,
data() {
return {
name: "Tom",
};
},
});
</script>
注册组件
- 局部注册:
new Vue
时传入components选项 - 全局注册:
Vue.component('组件名',组件)
注意:
- 组件必须先创建后注册,否则会发生报错: “Uncaught ReferenceError: Cannot access ‘school’ before initialization”
- 完成组件创建和注册后,创建Vue实例指向某个DOM容器是必要的,也就是说组件最外层需要Vue实例包裹,否则vue自定义组件无法渲染,组件无法显示
示例(第二部分):组件的全局和局部注册
<script>
//全局注册组件
Vue.component("hello", hello);
//创建Vue实例vm
new Vue({
el: "#root",
data: {
msg: "此处位于root节点!",
},
//注册组件(局部注册)
components: {
school,
student,
},
});
// 创建Vue实例vm
new Vue({
el: "#root2",
data() {
return {
msg: "此处位于root2节点!",
};
},
});
</script>
组件使用
示例(第三部分):编写组件标签
<body>
<div id="root">
<!--编写组件标签-->
<hello></hello>
<h1>{{msg}}</h1>
<!--编写组件标签 -->
<school></school>
<!--编写组件标签 -->
<student></student>
</div>
<hr />
<div id="root2">
<h1>{{msg}}</h1>
<hello></hello>
</div>
</body>
最终结果
组件注意事项
- 命名规则
(1)一个单词组成时:
第一种写法(首字母小写):school
第二种写法(首字母大写):School
(2)多个单词组成:
第一种写法(kebab-case命名):my-school
第二种写法(CamelCase命名):MySchool (需要Vue脚手架支持)- 组件名尽可能回避HTML中已有的元素名称,例如:h2、H2都不行。
- 可以使用name配置项指定组件在开发者工具中呈现的名字。
- 编写组件标签
第一种写法:<school></school>
第二种写法:<school/>(这种写法在没有使用脚手架的时候会造成标签没有办法渲染)- 注册组件的简写方法
const school = Vue.extend(options) //简写为 const school = options
组件嵌套
组件定义
下面我们将先定义一个student组件,然后再定义一个school组件,在后者注册student组件
<script>
//定义student组件
const student = Vue.extend({
name: "student",
template: `
<div>
<h2>学生姓名:{{name}}(学生组件)</h2>
</div>
`,
data() {
return {
name: "张三",
};
},
});
//定义school组件
const school = Vue.extend({
name: "school",
template: `
<div>
<h2>学校名称:{{name}}(学校组件)</h2>
<student></student>
</div>
`,
data() {
return {
name: "尚硅谷",
};
},
//在school组件中注册组件(局部)
components: {
student,
},
});
</script>
组件注册
<script>
// 全局组件注册
Vue.component("school", school);
// 创建Vue实例vm,用于包裹组件
new Vue({
el: "#root",
});
</script>
组件使用
<body>
<div id="root">
<school></school>
</div>
</body>
效果
浏览器开发者工具
其他需要注意的地方
关于VueComponent组件函数
上面代码中我们曾经定义个多个组件,实际上这些组件本质是一个名为VueComponent的构造函数,由Vue.extend生成。我们只需要写<school/>或<school></school>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行了:new VueComponent(options)
。
每次调用Vue.extend,返回的都是一个全新的VueComponent。
关于this指向的问题
- 在组件配置中(生成一个新组件),data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】
- 在new Vue(options)配置中(生成一个Vue实例对象),data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
关于VueComponent与Vue实例对象的关系
一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype,这样组件实例对象(vc)可以访问到 Vue原型上的属性、方法。