【问题标题】:Vue/Nuxt: How to make a component be truly dynamic?Vue/Nuxt:如何让组件真正动态化?
【发布时间】:2020-01-24 08:03:22
【问题描述】:

为了使用动态定义的单页组件,我们使用component标签,因此:

<component v-bind:is="componentName" :prop="someProperty"/>

...

import DynamicComponent from '@/components/DynamicComponent.vue';

...
components: {
    DynamicComponent
},

props: {
    componentName: String,
    someProperty: null,
}

问题是,这根本不是非常动态的,因为我们可能想要在这里使用的每个组件不仅需要静态导入,还需要在components 中注册。

我们尝试这样做,至少是为了避免需要导入所有内容:

created() {
    import(`@/components/${this.componentName}.vue`);
},

但这当然会失败,因为似乎必须在到达 created() 之前定义 DynamicComponent

我们如何才能使用真正动态的组件,即在运行时导入和注册,只给出它的名称?

【问题讨论】:

    标签: vue.js dynamic nuxt.js vue-dynamic-components


    【解决方案1】:

    你说的是async components。您只需使用以下语法即可返回带有承诺的组件定义。

    Vue.component('componentName', function (resolve, reject) {
      requestTemplate().then(function (response) {
        // Pass the component definition to the resolve callback
        resolve({
          template: response
        })
      });
    })
    

    【讨论】:

    • requestTemplate 未定义。顺便说一句,我们正在使用 Nuxt。什么是请求模板?谷歌快速搜索一无所获。
    • 另外:我假设这段代码应该放在 created() 中?对吗?
    • 没有。它只是组件定义。您可以将其写入外部文件并将其导入或仅将其写入顶部。但真正的模板在另一个文件中,仅在需要时加载。您只需在任何带有 v-bind:is 的模板中使用它,一旦需要该组件,vue 就会启动一个 ajax 请求并初始化该组件。
    • 如果你使用 vue-cli,你可以使用我发送的文章中提到的不同语法,它会自动编译成一个版本,其中组件是异步加载的。否则需要定义自己的 api(requestTemplate 函数)来返回组件。它是你自己的函数,它从你自己的 api 请求所需的模板。
    • 抱歉,我没有看到对任何 vue CLI 命令的任何引用。哦,还有一件事:我们渲染 SSR。这有什么改变吗?
    【解决方案2】:

    来自documentation强调我的

    <!-- Component changes when currentTabComponent changes -->
    <component v-bind:is="currentTabComponent"></component> 
    

    在上面的示例中,currentTabComponent 可以包含:

    • 已注册组件的名称,
    • 组件的选项对象

    如果currentTabComponent 是组件的数据属性,您可以简单地导入组件定义并将其直接传递给组件标记,而无需在当前模板上定义它。

    Here is an example 如果单击 Vue 徽标,组件内容将发生变化。

    像这样:

    <component :is="dynamic" />
    

    ...

    setComponentName() {
        this.dynamic = () => import(`@/components/${this.componentName}.vue`);
    },
    

    【讨论】:

    • 哇,刚刚成功了!我们甚至看到异步组件是从服务器动态加载的。如此简单,当你知道怎么做的时候!我将编辑您的答案以包含您示例中的神奇之处。
    【解决方案3】:

    根据官方Documentation:从 v2.13 开始,Nuxt 可以在模板中使用时自动导入您的组件,要激活此功能,请在您的配置中设置 components: true

    【讨论】:

      【解决方案4】:

      仅适用于 Nuxt 的解决方案

      目前可以在 Nuxt (nuxt/components) 中自动导入组件。如果你这样做了,当你在你的 vue 模板中使用它们时,你就有一堆组件可以注册,例如:

      <MyComponent some-property="some-value" />
      

      如果您想将真正的动态组件与nuxt/components 结合使用,您可以利用 Nuxt 自动准备组件的方式。我创建了一个包,它为自动导入的组件启用动态组件(您可以在这里查看:@blokwise/dynamic)。

      长话短说:使用该包,您可以像这样动态导入组件:

      <NuxtDynamic :name="componentName" some-property="some-value" />
      

      componentName 可能是'MyComponent'。该名称可以静态存储在变量中,甚至可以通过对后端/CMS 的某些 API 调用动态创建。

      如果您对底层魔法的工作原理感兴趣,可以查看这篇文章:Crank up auto import for dynamic Nuxt.js components

      【讨论】:

      • 这应该是公认的答案!这个包做得很好,就像一个魅力
      猜你喜欢
      • 2020-12-21
      • 2021-12-24
      • 2020-09-27
      • 1970-01-01
      • 2020-02-25
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      • 2021-04-12
      相关资源
      最近更新 更多