简体   繁体   English

可选地在 Vue 中导入组件

[英]Optionally import Component in Vue

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我有几种菜单类型,想配置要在.env.local 中使用的菜单类型,例如: VUE_APP_MENU_TYPE=2

In my javascript file I have the following:在我的 javascript 文件中,我有以下内容:

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;

This will result in an error Failed to mount component: template or render function not defined.这将导致错误Failed to mount component: template or render function not defined.

I can do the following:我可以执行以下操作:

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;

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.这将起作用,但所有菜单都在代码中编译,包括永远不会使用的菜单,因为 VUE_APP_MENU_TYPE 在编译时是已知的,并且在您重新编译之前永远不会改变。

Is it possible to import a component dynamically at compile time?是否可以在编译时动态导入组件?

Try menu = require("./type2/Type2.vue").default;试试menu = require("./type2/Type2.vue").default;

Explanation taken from this answer来自这个答案的解释

when dealing with ES6 imports ( export default MyComponent ), the exported module is of the format {"default": MyComponent} .在处理 ES6 导入( export default MyComponent )时,导出模块的格式为{"default": MyComponent} The import statement correctly handles this assignment for you, however, you have to do the require("./mycomponent").default conversion yourself. import语句为您正确处理此分配,但是,您必须自己进行require("./mycomponent").default转换。 If you want to avoid that, use module.exports instead of export default如果您想避免这种情况,请使用module.exports而不是export default

Fort second part of question...堡垒第二部分问题...

Is it possible to import a component dynamically at compile time?是否可以在编译时动态导入组件?

Really never tried but I have my doubts.真的从未尝试过,但我有疑问。 Webpack is not executing the code when building. Webpack 在构建时没有执行代码。 It just scans it for some patterns.它只是扫描它的一些模式。

  1. It scans for require() so it know what modules should be included in the bundle它扫描require()以便知道应该在包中包含哪些模块
  2. DefinePlugin is replacing strings like process.env.VUE_APP_MENU_TYPE with values from env files so it make code look like if ("3" === "2") { DefinePlugin正在用env文件中的值替换诸如process.env.VUE_APP_MENU_TYPE之类的字符串,因此它使代码看起来像if ("3" === "2") {
  3. Other plugins are able to detect that if ("3" === "2") { is never true and eliminate "the death code"其他插件能够检测到if ("3" === "2") {永远不会为true并消除“死亡代码”

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.真正的问题是先发生什么 - 如果在消除死亡代码之前发生require扫描,您最终将获得捆绑包中所有可能的菜单组件。 But unfortunately I don't know - You'l have to try但不幸的是我不知道 - 你必须尝试

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).是的,Webpack 将构建所有可能的菜单组件,但每个组件都有自己的 js 块( dist文件夹中的 js 文件)。 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)如果应用程序只加载其中一个,对我来说似乎没问题(请注意,加载将是异步的 - 在运行时 - 所以这意味着多了一个服务器请求)

I think that loading the component dynamically is the best option you have.我认为动态加载组件是您拥有的最佳选择。 https://v2.vuejs.org/v2/guide/components-dynamic-async.html https://v2.vuejs.org/v2/guide/components-dynamic-async.html

I could have solved this with a webpack setting.我可以通过 webpack 设置解决这个问题。

In vue.config.js在 vue.config.js 中

const path = require("path");

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        MENU: path.resolve(
          __dirname,
          (() => {
            if (process.env.VUE_APP_MENU_TYPE === "2") {
              return "src/components/header/CategoriesMenu/Type2/Type2.vue";
            }
            return "src/components/header/CategoriesMenu/Default/Default.vue";
          })()
        ),
      },
    },
  },
};

In src/components/header/CategoriesMenu/index.js在 src/components/header/CategoriesMenu/index.js

import menu from "MENU";
export default menu;

But to be honest, I like the require better.但老实说,我更喜欢require

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM