如何在Laravel-Mix+Webpack环境下自动全局注册Vue组件
问题场景与需求
我目前在基于Laravel-Mix/Webpack的Vue项目中,通过import+Vue.extend手动逐个注册组件,编译后在HTML中引用。现在需要迁移一个包含100+组件的NuxtJS项目到该环境,手动注册效率太低。参考Vue官方的基础组件自动全局注册示例后,我理解它能遍历组件文件夹生成PascalCase命名的组件列表,但不清楚怎么结合Vue.extend导出这些组件、通过webpack.mix.js正确编译,以及在HTML脚本中引用后直接使用组件。另外还有两个疑问:
- 手动注册时组件在HTML中用kebab-case引用,自动注册后能不能继续用?
- 我的组件存在子文件夹,已经把
require.context的第二个参数设为true,是否需要其他调整?
现有手动注册代码示例
import BaseButton from './components/BaseButton.vue' import BaseIcon from './components/BaseIcon.vue' import BaseInput from './components/BaseInput.vue' window.base = Vue.extend({ components: { BaseButton, BaseIcon, BaseInput } })
现有webpack.mix.js配置示例
const mix = require('laravel-mix'); mix.vue({ version: 2 }) .js('src/js/base.js', 'dist/base_rendered.js')
现有HTML引用示例
<script src="base_rendered.js"></script> <script> new base({ el: '#base', }); </script>
Vue官方自动注册示例代码
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) const componentName = upperFirst( camelCase( fileName .split('/') .pop() .replace(/\.\w+$/, '') ) ) Vue.component( componentName, componentConfig.default || componentConfig ) })
解决方案
1. 改造自动注册逻辑,结合Vue.extend导出
不需要全局注册组件,而是遍历组件后收集到对象中,再传入Vue.extend:
import Vue from 'vue' import upperFirst from 'lodash/upperFirst' import camelCase from 'lodash/camelCase' // 遍历components文件夹及子文件夹,匹配Base开头的组件文件 const requireComponent = require.context( './components', true, // 开启子文件夹遍历 /Base[A-Z]\w+\.(vue|js)$/ ) const components = {} requireComponent.keys().forEach(fileName => { const componentConfig = requireComponent(fileName) // 生成PascalCase的组件名 const componentName = upperFirst( camelCase( fileName .split('/') .pop() .replace(/\.\w+$/, '') ) ) // 将组件存入对象,键为PascalCase名称 components[componentName] = componentConfig.default || componentConfig }) // 导出Vue.extend创建的构造函数到window window.base = Vue.extend({ components })
2. 子文件夹遍历的适配
你已经将require.context的第二个参数设为true,这已经开启了子文件夹遍历。正则表达式/Base[A-Z]\w+\.(vue|js)$/会匹配所有子文件夹中以Base开头的组件文件,无需额外调整。
3. kebab-case引用兼容性
完全可以继续沿用kebab-case引用组件。Vue会自动处理组件名的大小写转换:PascalCase的组件名在HTML模板中可以用kebab-case(比如BaseButton对应<base-button>),这和你手动注册时的用法完全一致,不需要修改HTML中的组件引用方式。
4. 编译与引用验证
- webpack.mix.js的配置不需要修改,保持你原来的配置即可,Laravel-Mix会正常编译改造后的
base.js文件。 - HTML引用方式也和之前完全一样,编译后直接引用
dist/base_rendered.js,然后通过new base({el: '#base'})初始化实例,所有自动注册的组件都可以直接在模板中使用。
内容的提问来源于stack exchange,提问作者Isabelle May
相关产品推荐
相关产品推荐

