内容提要:
- 横线分割的组件命名
- 全局注册组件的方式
- 局部注册组件的方式
- 模块系统:在模块系统中本地注册组件的方式、全局自动创建基本组件的方式
这页假设你已经读了组件基础Components Basics,如果你不了解组件先读它
组件名称
在注册组件的时候我们必须给一个名字,它是组件的第一给参数:
Vue.componnet('my-component-name', {/* ... */})
命名要见名知意,为了避免和HTML元素冲突,建议遵守W3C( W3C rules ) 原则去自定义一个tag名字:全部小写,并且用连字符链接每一个词。其他建议看代码规范指导 Style Guide.
名称用例
定义组件名有两种方式:
// 方式一:短横线命名法
Vue.component('my-component-name', { /* ... */ })
// 方式二:驼峰命名法
Vue.component('MyComponentName', { /* ... */})
定义时用哪种方式,引用就用哪种方式。然而,自己在DOM中使用,仅能使用方式一的命名方式(eg:非字符串模板)。
全局注册
使用Vue.component
注册的组件为全局注册,可在所有new Vue
创建的实例内使用。
Vue.component('component-a',{ /* ... */ })
Vue.component('component-b',{ /* ... */ })
Vue.component('component-c',{ /* ... */ })
new Vue({ el: '#app' })
<div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
这甚至应用于所有的子组件,这意味着所有这三个组件互相之间也可用的。
本地注册
为什么需要本地注册?
全局注册常常并不完美,例如,如果你使用像Webpack之类的构建系统,全局注册所有组件意味着即使你停止使用组件,它仍然会被包含在最后的发布包中。这些JS代码的下载对用户是没有必要的。
在这些例子中,你能使用纯JS对象定义你的组件:
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
然后在你想使用的地方在一个components
操作项下定义你的组件:
new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
对于在components对象的每一个属性,Key是自定义对象的名字,如component-a,value是组件的操作对象,如:ComponentA。
注意本地注册的组件不可以用在子组件内。例如,如果你想让ComponentA在ComponentB可用,你必须这样用:
var ComponentA = { /* ... */ }
var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
或如果你通过Babel和Webpack使用的是ES2015模块,它看起来更像这样:
import ComponentA from './ComponentA.vue'
exprot default {
components: {
ComponentA
}
// ...
}
注意在ES2015+,在对象内部用一个变量名像ComponentA
其实是ComponentA:ComponentA的简称,意味着该变量名:
- 是用在模板内部的自定义元素名
- 变量名包含了该组件的操作选项
模块系统
如果你并没有使用import/require导入模块系统用,你可以跳过这节,否则,有一些具体的说明和建议给到你。
在一个模块系统里进行本地注册
如果你到这了,那么说明你正在使用一个模块系统,如Babel和Webpack。在这些例子中,我们建议你创建一个components
目录。每一个component
在他自己的文件。
然后在你本地注册它之前,在使用的地方导入组件,例如:假设在一个ComponentB.js
或ComponentB.vue
文件:
import ComponentA from './ComponentA'
import ComponentC form './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
现在ComponentA
和ComponentC
在ComponentB
的模板里都能被使用。
基本组件的自动全局注册
许多组件将是相对通用的,可能仅仅封装一个元素像一个输入框或一个按钮。我们有时称这些为 base components,他们通常在组件之间使用非常频繁。
结果是许多组件可能包含很长的基本组件:
import BaseButton form './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput form './BaseInput.vue'
export default {
components: {
BaseButton,
BaseIcon,
BaseInput
}
}
只是为了在模板中支持较少的标记:
<BaseInput v-model="searchText"
@keydown.enter="search"
/>
<BaseButton @click="search">
<BaseIcon name="search">
</BaseButton>
如果使用Webpack(或 Vue CLI 3+,内部使用Webpack)可以使用require.context
去全局注册这些基本组件。这有一个案例代码你可能使用它去全局import基本组件在你的实体文件(e.g. src/main.js
):
import Vue form 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
// components的相对路径
'./components',
// 是否在子文件夹中查找
false,
// 用于匹配基本组件名的正则表达式
/Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName =>{
// 获取组件配置
const componentConfig = requireComponent(fileName)
// 获取组件的PascalCase名字
const componentName = upperFirst(
camelCase(
// 去掉头的‘./’和文件名的拓展
fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
)
)
// 全局注册组件
Vue.component(
componentName,
// 查找组件操作项用‘.default’,如果组件存在使用‘export default’导出,否则返回一个模块的根节点。
componentConfig.default || componentConfig
)
})
记住:全局注册的组件必须被替换在根Vue实例被创建之前(new Vue
)。这里有一个在真实工程上下文的例子: Here’s an example 。