• 模块系统
    • 在模块系统中局部注册
    • 基础组件的自动化全局注册

    模块系统

    如果你没有通过 import/require 使用一个模块系统,也许可以暂且跳过这个章节。如果你使用了,那么我们会为你提供一些特殊的使用说明和注意事项。

    在模块系统中局部注册

    如果你还在阅读,说明你使用了诸如 Babel 和 webpack 的模块系统。在这些情况下,我们推荐创建一个 components 目录,并将每个组件放置在其各自的文件中。

    然后你需要在局部注册之前导入每个你想使用的组件。例如,在一个假设的 ComponentB.jsComponentB.vue 文件中:

    1. import ComponentA from './ComponentA'
    2. import ComponentC from './ComponentC'
    3. export default {
    4. components: {
    5. ComponentA,
    6. ComponentC
    7. },
    8. // ...
    9. }

    现在 ComponentAComponentC 都可以在 ComponentB 的模板中使用了。

    基础组件的自动化全局注册

    可能你的许多组件只是包裹了一个输入框或按钮之类的元素,是相对通用的。我们有时候会把它们称为基础组件,它们会在各个组件中被频繁的用到。

    所以会导致很多组件里都会有一个包含基础组件的长列表:

    1. import BaseButton from './BaseButton.vue'
    2. import BaseIcon from './BaseIcon.vue'
    3. import BaseInput from './BaseInput.vue'
    4. export default {
    5. components: {
    6. BaseButton,
    7. BaseIcon,
    8. BaseInput
    9. }
    10. }

    而只是用于模板中的一小部分:

    1. <BaseInput
    2. v-model="searchText"
    3. @keydown.enter="search"
    4. />
    5. <BaseButton @click="search">
    6. <BaseIcon name="search"/>
    7. </BaseButton>

    幸好如果你使用了 webpack (或在内部使用了 webpack 的 Vue CLI 3+),那么就可以使用 require.context 只全局注册这些非常通用的基础组件。这里有一份可以让你在应用入口文件 (比如 src/main.js) 中全局导入基础组件的示例代码:

    1. import Vue from 'vue'
    2. import upperFirst from 'lodash/upperFirst'
    3. import camelCase from 'lodash/camelCase'
    4. const requireComponent = require.context(
    5. // 其组件目录的相对路径
    6. './components',
    7. // 是否查询其子目录
    8. false,
    9. // 匹配基础组件文件名的正则表达式
    10. /Base[A-Z]\w+\.(vue|js)$/
    11. )
    12. requireComponent.keys().forEach(fileName => {
    13. // 获取组件配置
    14. const componentConfig = requireComponent(fileName)
    15. // 获取组件的 PascalCase 命名
    16. const componentName = upperFirst(
    17. camelCase(
    18. // 获取和目录深度无关的文件名
    19. fileName
    20. .split('/')
    21. .pop()
    22. .replace(/\.\w+$/, '')
    23. )
    24. )
    25. // 全局注册组件
    26. Vue.component(
    27. componentName,
    28. // 如果这个组件选项是通过 `export default` 导出的,
    29. // 那么就会优先使用 `.default`,
    30. // 否则回退到使用模块的根。
    31. componentConfig.default || componentConfig
    32. )
    33. })

    记住全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生。这里有一个真实项目情景下的示例。