Vue | 12 组件深入-组件注册

内容提要:

  1. 横线分割的组件命名
  2. 全局注册组件的方式
  3. 局部注册组件的方式
  4. 模块系统:在模块系统中本地注册组件的方式、全局自动创建基本组件的方式

这页假设你已经读了组件基础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.jsComponentB.vue文件:

import ComponentA from './ComponentA'
import ComponentC form './ComponentC'

export default {
    components: {
        ComponentA,
        ComponentC
    },
    // ...
}

现在ComponentAComponentCComponentB的模板里都能被使用。

基本组件的自动全局注册

许多组件将是相对通用的,可能仅仅封装一个元素像一个输入框或一个按钮。我们有时称这些为 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

猜你喜欢

转载自blog.csdn.net/wudizhanshen/article/details/84592097
今日推荐