vue 组件
一. 组件基础
1. 组件中的data选项必须是一个函数
组件是可复用的 Vue 实例,且带有一个名字。
一个组件的 data 选项必须是一个函数,这样每个实例就可以维护一份被返回对象的独立的拷贝,多次复用的组件之间的数据才相互隔离,不互相影响
data: function () {
return {
//...
}
}
2. 在组件上使用v-model
自定义事件也可以用于创建支持 v-model 的自定义输入组件。
<input v-model="searchText">
等价于:
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
当用在组件上时,v-model 则会这样:
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
为了让它正常工作,这个组件内的 <input> 必须:
- 将其 value 特性绑定到一个名叫 value 的 prop 上
- 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
写成代码之后是这样的:
Vue.component('custom-input', {
props: ['value'],
template: `<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)">`
})
现在 v-model 就应该可以在这个组件上完美地工作起来了:
<custom-input v-model="searchText"></custom-input>
二. 组件注册
1. 组件名
组件名取决于它的功能。当直接在 DOM 中使用一个组件 (而不是在字符串模板或单文件组件) 的时候,我们强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会避免和 HTML 元素相冲突。
定义组件名的两种方式:
- 使用kebab-case(短横线分隔命名)
如:
当使用 kebab-case 定义一个组件时,在引用这个自定义元素时也必须使用 kebab-case,例如 <my-component-name>。Vue.component('my-component-name', { /* ... */ })
- 使用PascalCase(首字母大写命名)
如:
当使用 PascalCase定义一个组件时,引用这个自定义组件时两种命名法都可以。也就是说 <my-component-name> 和 <MyComponentName> 都是可接受的。Vue.component('MyComponentName', { /* ... */ })
注意:直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。
2. 全局注册(通过Vue.component来创建并注册组件)
Vue.component('my-component-name', {
// ... 选项 ...
})
通过全局注册的组件在注册之后可以在任何新创建的 Vue 根实例 (new Vue) 的模板中使用。在所有子组件中也可以互相使用。
3. 局部注册(通过components选项来注册,在局部注册之前导入需要使用的组件)
import ComponentA from './ComponentA'
import ComponentB from './ComponentB'
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
三. 动态组件
1. component元素 + is
有的时候,在不同组件之间进行动态切换是非常有用的
实现组件之间的切换可以通过 Vue 的 <component> 元素加一个特殊的 is 特性来实现:
<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component :is="currentTabComponent"></component>
在上述示例中,currentTabComponent 可以包括
已注册组件的名字 或 一个组件的选项对象
2. keep-alive
<component v-bind:is="currentTabComponent"></component>
上述实现,当这些组件相互切换时,无法保持这些组件的状态,因为你每次切换新标签的时候,Vue 都创建了一个新的 currentTabComponent 实例
若想在组件切换时候,保持组件的状态,以避免反复重渲染导致的性能问题,可用<keep-alive>元素
<!-- 失活的组件将会被缓存!-->
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
注意: <keep-alive> 要求被切换到的组件都有自己的名字,无论是通过组件的 name 选项还是局部/全局注册。