可选地在 Vue 中导入组件
我有几种菜单类型,想配置要在 .env.local 中使用的菜单类型,例如:VUE_APP_MENU_TYPE=2
I have several menu types and want to configure the type of menu to be used in .env.local for example: VUE_APP_MENU_TYPE=2
在我的 javascript 文件中,我有以下内容:
In my javascript file I have the following:
let menu = false;
if (process.env.VUE_APP_MENU_TYPE === "2") {
menu = require("./type2/Type2.vue");
}
if (menu === false) {//default menu if env is missing
menu = require("./default/Default.vue");
}
export default menu;
这将导致一个错误Failed to mount component: template or render function not defined.
我可以做到以下几点:
import Default from "./default/Default.vue";
import Type2 from "./type2/Type2.vue";
let menu = Default;
if (process.env.VUE_APP_MENU_TYPE === "2") {
menu = Type2;
}
export default menu;
这将起作用,但所有菜单都在代码中编译,包括永远不会使用的菜单,因为 VUE_APP_MENU_TYPE 在编译时是已知的,并且在您重新编译之前永远不会改变.
This will work but all menus are compiled in the code, including menus that will never be used since VUE_APP_MENU_TYPE is known at compile time and will never change until you recompile.
是否可以在编译时动态导入组件?
Is it possible to import a component dynamically at compile time?
推荐答案
试试 menu = require("./type2/Type2.vue").default;
来自此答案
在处理 ES6 导入时(export default MyComponent
),导出的模块格式为 {"default";:我的组件}
.import
语句为您正确处理此分配,但是,您必须自己进行 require("./mycomponent").default
转换.如果您想避免这种情况,请使用 module.exports
而不是 export default
when dealing with ES6 imports (
export default MyComponent
), the exported module is of the format{"default" : MyComponent}
. Theimport
statement correctly handles this assignment for you, however, you have to do therequire("./mycomponent").default
conversion yourself. If you want to avoid that, usemodule.exports
instead ofexport default
问题的第二部分...
是否可以在编译时动态导入组件?
Is it possible to import a component dynamically at compile time?
真的从未尝试过,但我有疑问.Webpack 在构建时不执行代码.它只是扫描它的一些模式.
Really never tried but I have my doubts. Webpack is not executing the code when building. It just scans it for some patterns.
- 它会扫描
require()
以便知道应该在包中包含哪些模块 - DefinePlugin 正在替换像
process.env.VUE_APP_MENU_TYPE<这样的字符串/code> 带有来自
env
文件的值,因此它使代码看起来像if ("3" === "2") {
- 其他插件能够检测到
if ("3" === "2") {
永远不是true
并消除死亡密码".
- It scans for
require()
so it know what modules should be included in the bundle - DefinePlugin is replacing strings like
process.env.VUE_APP_MENU_TYPE
with values fromenv
files so it make code look likeif ("3" === "2") {
- Other plugins are able to detect that
if ("3" === "2") {
is nevertrue
and eliminate "the death code"
真正的问题是先发生什么 - 如果 require
扫描发生在消除死亡代码之前,您将在捆绑包中获得所有可能的菜单组件.但不幸的是我不知道 - 你必须尝试
Real question if what happens first - if require
scanning happens before death code elimination, you will end up with all possible menu components in the bundle. But unfortunately I don't know - You'l have to try
另一方面,使用 动态异步组件(如前所述在其他答案中)是肯定的.是的,Webpack 将构建所有可能的菜单组件,但每个组件都有自己的 js 块(dist
文件夹中的 js 文件).如果应用程序只加载其中一个,对我来说似乎没问题(请注意,加载将是异步的 - 在运行时 - 所以这意味着多了一个服务器请求)
On the other hand using dynamic async components (as mentioned in other answers) is sure bet. Yes, Webpack will build all possible menu components but each with it's own js chunk (js file in dist
folder). If the app loads just one of them, it's seems fine to me (note that the loading will be async - at runtime - so it means one more server request)
相关文章