# 组件注册

# 组件名

注册组件的时候,需要取一个名字,是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
  )
})
上次更新: 2020/10/29 22:59:19