前面系列文章:
Vue的有有两大特性
渐进式是Vue底层的设计,我们不先关心,第三章着重介绍组件(component )的使用。和指令,过滤器一样,组件可以分为局部组件和全局组件,定义方式也都大同小异。
在真正介绍component
之前,先介绍 Vue.extend({Object} options) 。Vue.extend()
使用基础 Vue 构造器,创建一个“子类”,参数是一个包含组件选项的对象。data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数。 后面会介绍到这里的data为什么不是对象而是一个函数。
<body>
<div id="app">div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
// 创建构造器
var Profile = Vue.extend({
template: '{{firstName}} {{lastName}} aka {{alias}}
',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
new Profile().$mount('#app')
script>
body>
在上面建立了一个Vue.extend()
并把它通过$mount
挂载到DOM上,但是通过这种方式好像只能使用一次,如果使用组件就不会有这种问题,因为组件是可以复用的。
<body>
<div id="app">
<my-component>my-component>
<my-component>my-component>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
// 创建构造器
var Profile = Vue.extend({
template: '{{firstName}} {{lastName}} aka {{alias}}
',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
// 创建 Profile 实例,并挂载到一个元素上。
// new Profile().$mount('#app')
Vue.component("my-component",Profile)
// 创建Vue实例
var app = new Vue({
el: '#app'
})
script>
body>
以上就是一个使用Vue.component
创建最基本的组件,也就是说它们在注册之后可以用在任何新创建的 Vue 根实例new Vue()
的模板中。首先,第一个参数就是我们所需要的定义的组件名,这个可以使用短横线命名(如实例中的),也可以使用“驼峰命名”,如果使用“驼峰命名”,那么在使用的过程中就必须改成成短横线的形式,当然如果是在字符串模板(反引号``选中的,如上面的template)中是没有这个限制的,如下:
<body>
<div id="app">
<p>+++++++++++p>
<myComponent>myComponent>
<p>+++++++++++p>
<my-component>my-component>
<p>+++++++++++p>
<test>test>
<p>+++++++++++p>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
var Profile = Vue.extend({
template: '{{firstName}} {{lastName}} aka {{alias}}
',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
alias: 'Heisenberg'
}
}
})
Vue.component("myComponent",Profile)
// 简写
Vue.component("test",{
template: ' ',
})
new Vue({
el: '#app',
})
script>
body>
在div中声明了三个组件,第一个是“驼峰命名”,第二个短横线命名,第三个是在字符串模板中使用“驼峰命名”。根据结果我们可以看到,第一个没有显示,其他都能正常显示。在新定义的test组件中,没有再声明Vue.extand()
而是用对象代替,其实后者是前者的简写,熟悉以后大家就可以这样声明一个全局组件:
Vue.component('my-component-name', { /* ... */ })
<body>
<div id="app">
<profile>profile>
<my-com>my-com>
div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
new Vue({
el: '#app',
components:{
profile:{
template:`profile
`
},
"my-com":{
template:`myComponent
`
}
}
})
script>
body>
在Vue实例中,定义了一个components
属性对象,和Vue,extand()
一样,我们只需要以对象的形式在里面实现组件就好。需要注意的是短横线命名需要用引号包裹。
可能大家也看出来了,使用字符串模板编写html实在有些一言难尽吗,Vue中也给我们提供了一个新的标签,我们只需要指明template标签的id,直接引用就好:
<template id="html">
<div>
<p>大风起兮云飞扬p>
<p>维加海内西归故乡p>
div>
template>
Vue.component("my-template",{
template: "#html"
})
值得注意的是,如果template里面需要有多个标签的话,需要用一个标签进行包裹,然后在里面书写,如上面的。
如果想要控制两个组件的切换(显示|消失)的话,怎么办那?肯定下意识就会想到用if和show这两条指令,这样当然可以,不过Vue还为组件提供了一个is属性,来实现这个效果。当然光有is属性还不够,需要和
标签搭配使用:
<body>
<div id="app">
<button @click="myButton">切换button>
<keep-alive>
<component :is="componentName">component>
keep-alive>
div>
<template id="template">
<div class="temp">
<h1>雕栏玉砌应犹在h1>
<h2>雕栏玉砌应犹在h2>
<h3>雕栏玉砌应犹在h3>
div>
template>
<template id="footer">
<div>
<h1>只是朱颜改h1>
<h2>只是朱颜改h2>
<h3>只是朱颜改h3>
<input type="checkbox">
div>
template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
<script>
Vue.component("my-component",{
template:"#template"
})
var app = new Vue({
el: '#app',
data: {
componentName:"my-component"
},
methods: {
myButton(){
this.componentName = this.componentName == "my-component" ? "my-footer" : "my-component"
}
},
components:{
"my-footer":{
template:"#footer"
}
}
})
script>
body>
上面的案例可以帮助我们实现组件之间的切换,也就是说is指向的是想要显示的组件名称。
<keep-alive>
<component :is="componentName">component>
keep-alive>
不过上面可以看出,在
标签之外还有一层标签
,它的作用就是保存状态。在footer组件中定义了一个checkbox,选中这个单选框,在切换的组件时候,如果没有keep-alive标签的话,单选框就不会是选中状态。想要保持选中就需要在外层加个
标签。
组件其实就是一个Vue()
实例,不过这个实例是一个大组件。实例既然是组件,那么实例中的属性对象在组件中也是可以使用的,比如之前的methods,computed,watch……,data除外,data在组件中是一个函数,而非一个对象。因为组件的可复用性,如果声明的多个组件都对data中的同一条数据进行操作的话,那么数据就会混乱。而使用函数的话,那么声明的多个组件就只会对自己的数据进行操作。比如有一个苹果(data中的数据),有多个人(多个组件),之前是多个人抢这一个苹果,后来改成函数了,就相当于一个人给了一个苹果,而且为了防止眼红,还把一个人专门放到一个屋子中了,这样这个苹果到底怎么处理只有自己知道。