# 组件注册
# 组件名
注册组件的时候,需要取一个名字,是Vue.component函数的第一个参数,当直接在dom中使用时,组件(而不是字符串模板或单文件文件.vue)的时候,需要遵循W3C自定义组件名命名规范:字母全小写且必须包含一个连字符,可避免和当前以及未来的HTML元素相冲突
Vue.component('my-component-name', { /* ... */ })
# 组件名大小写
定义组件名有两种方式:
- kebab-case 短横线隔开
Vue.component('my-component-name', {})
- PascalCase 首字母大写命名, 这种写法 <my-component-name> 和 <MyComponentName> 都是可接受的,注意DOM里还是要使用kebab-case写法
Vue.component('MyComponentName', {})
# 全局注册
Vue.component()创建的组件都是全局注册的。可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。
# 局部注册
全局注册往往是不够理想的。比如,如果你使用一个像 webpack 这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。
可以通过普通的JS对象来定义组件
var ComponentA = {};
var ComponentB = {};
var ComponentC = {};
var vm = new Vue({
el: '#app',
components: {
'component-a': ComponentA,
'component-b': ComponentB
}
})
注意局部注册的组件在其子组件中不可用,如果需要使用,在创建子组件实例时用components引入该组件即可。
如果通过webpack或Babel使用ES6(ES2015)模块,那么代码看起来像这样
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA // 也可以写为 'component-a': ComponentA
}
// ....
}
# 模块系统
# 在模块系统中局部注册
推荐创建一个components目录,并将每个组件放置在其各自的文件中。然后在局部注册之前导入需要的组件。例如,在一个假设的 ComponentB.js 或 ComponentB.vue 文件中:
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}
ComponentA 和 ComponentC 就可以在 ComponentB 的模板中使用了。
# 基础组件全局注册
注意下面的代码需要在 new Vue创建之前触发。
如果你使用了 webpack (或在内部使用了 webpack 的 Vue CLI 3+),那么就可以使用 require.context 只全局注册这些非常通用的基础组件。这里有一份可以让你在应用入口文件 (比如 src/main.js) 中全局导入基础组件的示例代码:
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
const requireComponent = require.context(
// 其组件目录的相对路径
'./components',
// 是否查询其子目录
false,
// 匹配基础组件文件名的正则表达式
/Base[A-Z]\w+\.(vue|js)$/
)
requireComponent.keys().forEach(fileName => {
// 获取组件配置
const componentConfig = requireComponent(fileName)
// 获取组件的 PascalCase 命名
const componentName = upperFirst(
camelCase(
// 获取和目录深度无关的文件名
fileName
.split('/')
.pop()
.replace(/\.\w+$/, '')
)
)
// 全局注册组件
Vue.component(
componentName,
// 如果这个组件选项是通过 `export default` 导出的,
// 那么就会优先使用 `.default`,
// 否则回退到使用模块的根。
componentConfig.default || componentConfig
)
})