局部注册
在Vue-多人博客项目中,该单页应用依赖的是模块系统以及局部注册组件。比方说Home.vue
这一组件是怎么局部注册的呢:
- 通过一个普通的 JavaScript 对象来定义组件
- 然后在
components
选项中定义你想要使用的组件
在codesandbox中HelloWorld组件也是如此局部注册使用的,只是它同时还是一个单文件组件,一时没察觉罢了。
局部组件内部想用局部注册组件?
其注意事项为:局部注册的组件在其子组件中不可用
它的意思是如若都是局部注册的组件,需要再次声明components才可使用:
在下例中必须把components这段注释去掉,否则会报图中的第一个错。
<template>
<div id="hello">
<p>{{ message }}</p>
<p>{{ reversedMessage }}</p>
<New/>
</div>
</template>
<script>
import New from './new'
export default {
// components: {
// New
// },
data() {
return {
message: "hello",
};
},
computed: {
reversedMessage: function () {
console.log(this);
// return 1
return this.message.split("").reverse().join("");
},
}
};
</script>
<style>
#hello {
box-shadow: 0 0 2px 0;
}
</style>
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
此设计直接要求我们在/components文件夹中写局部注册的组件,要使用组件的时候就需要在父组件老实写components选项中定义你想要使用的组件,如果是文件夹里一大把公共组件都要慢慢定义,那可不行...
批量注册
由上述,会出现的状况是:很多组件里都会有一个包含基础组件的长列表。
批量注册的思路是:使用 require.context
只全局注册这些非常通用的基础组件,喊你相对注册的基础组件都放components里,在Vue实例被创建之前照抄这段代码(这是全局注册的要求)。
此外,抄这个代码要用到lodash~
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
)
})
最后,批量注册之后的所有全局注册组件自由使用。
<BaseInput
v-model="searchText"
@keydown.enter="search"
/>
<BaseButton @click="search">
<BaseIcon name="search"/>
</BaseButton>