局部
一、认识
全局注册往往是不够理想的。比如,如果你使用一个像 webpack
这样的构建系统,全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript
的无谓的增加。
二、语法
2.1 同步
import ComponentA from './ComponentA.vue'
export default {
components: {
"component-a": ComponentA
},
// ...
}
对于 components
对象中的每个 property
来说,其 property
名就是自定义元素的名字,其 property
值就是这个组件的选项对象。或者如果你通过 Babel
和 webpack
使用 ES2015
模块,那么代码看起来更像:
import ComponentA from './ComponentA.vue'
export default {
components: {
ComponentA
},
// ...
}
注意在 ES2015+
中,在对象中放一个类似 ComponentA
的变量名其实是 ComponentA: ComponentA
的缩写,即这个变量名同时是:
-
用在模板中的自定义元素的名称
-
包含了这个组件选项的变量名
2.2 异步
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue
允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue
只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。
-
方式一、工厂函数
import
: 在工厂函数中返回一个Promise
。import()
入会返回一个Promise
对象。这个特殊的import()
语法将会告诉webpack
。自动将你的构建代码切割成多个包,这些包会通过Ajax
请求加载export default {
name: 'App',
components: {
A: ()=> import("./components/A.vue")
}
} -
方式二、工厂函数调用
resolve
回调: 工厂函数会收到一个resolve
回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用reject(reason)
来表示加载失败。这个特殊的require
语法将会告诉webpack
。自动将你的构建代码切割成多个包,这些包会通过Ajax
请求加载export default {
name: "App",
components: {
A: (resolve) => {
setTimeout(() => {
require(["./components/A"], resolve);
},3000);
},
},
}; -
方式三、工厂函数配置加载状态
components: {
A: () => {
return {
component: import("./components/A.vue"),
loading: "加载中",
error: "加载失败",
delay: 3000,
timeout: 3000,
};
},
}
三、自动化注册
3.1 Vite 自动化注册
3.2 Webpack 自动化注册
<template>
<div>
<HelloWorld msg="Welcome to Your Vue.js App"/>
<A/>
<B/>
</div>
</template>
<script>
const getComponentName = (fileName) => {
return fileName
.split("/")
.pop()
.replace(/\.\w+$/, "");
};
const components = {};
const requireComponent = require.context("./components", false, /\w+\.(vue)$/);
requireComponent.keys().forEach((fileName) => {
const componentConfig = requireComponent(fileName);
const componentName = getComponentName(fileName);
components[componentName] = componentConfig.default || componentConfig
});
export default {
name: 'App',
components,
}
</script>