「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」。
17. 非单文件组件
1. 定义组件
使用Vue.extend(options)创建,其中,对象options和new Vue(options)传入的options几乎一致,但也有一些区别。
Vue.extend(options)中的options对象:
- 没用
el属性,最终所有的组件都经过vm管理,由vm中的el决定服务哪个容器。 data必须写成函数,返回一个对象。避免组件被复用时,数据存在引用关系。
const name = Vue.extend({
template: `
<div class="demo">
<h2>姓名:{{name}}</h2>
<button @click="showName">打印姓名</button>
</div>
`,
data() {
return {
name: 'Jack',
};
},
methods: {
showName() {
console.log(this.name);
},
},
});
2. 注册组件
1. 全局注册
Vue.component('name', name);
其中,第一个参数'name'是组件名,第二个参数name是组件对象。
2. 局部注册
可以在new Vue中,定义想要使用的组件:
new Vue({
el: '#app',
components: {
'name': name,
'component-b': ComponentB
}
})
其中,'component-a'代表组件名字,ComponentA是组件对象。
3. 使用组件
根据组件的姓名,组件标签即可:
<div id="root">
<name></name>
</div>
也可以使用单个标签:
<div id="root">
<name/>
</div>
4. 注意点
1. 组件名
(1)一个单词
schoolSchool
(2)多个单词
my-schoolMySchool(需要 Vue 脚手架)
组件名不能与 HTML 已有的标签元素重名,如strong、div等。
另外,可以使用name属性指定组件在开发者工具中呈现的名字:
const school = Vue.extend({
name: 'my-component', // 指定在开发者工具中显示的名字
template: `
<div class="demo">
<h2>姓名:{{name}}</h2>
<button @click="showName">打印姓名</button>
</div>
`,
data() {
return {
name: 'Jack',
};
},
methods: {
showName() {
console.log(this.name);
},
},
});
2. 组件标签
<school></school><school/>(需要使用 Vue 脚手架)
3. 简写方式
const school = Vue.extend(options)
其中,可以直接简写为options对象:
const school = { ... }
5. 嵌套组件
//定义hello组件
const hello = Vue.extend({
template: `<h1>{{msg}}</h1>`,
data() {
return {
msg: 'Hello!',
};
},
});
//定义app组件
const app = Vue.extend({
template: `
<div>
<hello></hello>
</div>
`,
components: {
hello,
},
});
//创建vm
new Vue({
template: '<app></app>',
el: '#root',
components: { app },
});
6. VueComponent
定义了一个school组件,但是school组件本质是一个名为VueComponent的构造函数,是Vue.extend自动生成的。
每次解析<school></school>时,Vue 会创建school组件的实例对象,即 Vue 自动执行:new VueComponent(options)。
另外,每次调用Vue.extend,返回的都是一个全新的VueComponent。
VueComponent和Vue有一条重要的关系:
VueComponent.prototype.__proto__ === Vue.prototype
这样,我们定义的组件实例对象,就可以访问到 Vue 原型链上的属性、方法了。