【问题标题】:Dynamic component in Vue3Vue3 中的动态组件
【发布时间】:2021-05-03 03:32:28
【问题描述】:

Vue2 动态组件的简单工作示例


<template>
    <div>
        <h1>O_o</h1>
        <component :is="name"/>
        <button @click="onClick">Click me !</button>
    </div>
</template>

<script>
    export default {
        data: () => ({
            isShow: false
        }),
        computed: {
            name() {
                return this.isShow ? () => import('./DynamicComponent') : '';
            }
        },
        methods: {
            onClick() {
                this.isShow = true;
            }
        },
    }
</script>

一切正常,一切都很好。我开始尝试如何使用 Composition API。

<template>
    <div>
        <h1>O_o</h1>
        <component :is="state.name"/>
        <button @click="onClick">Click me !</button>
    </div>
</template>

<script>
    import {ref, reactive, computed} from 'vue'

    export default {
        setup() {
            const state = reactive({
                name: computed(() => isShow ? import('./DynamicComponent.vue') : '')
            });

            const isShow = ref(false);

            const onClick = () => {
                isShow.value = true;
            }

            return {
                state,
                onClick
            }
        }
    }
</script>

我们启动,组件没有出现在屏幕上,虽然没有显示错误。

【问题讨论】:

    标签: vuejs3


    【解决方案1】:

    您可以在此处了解有关“defineAsyncComponent”的更多信息 https://labs.thisdot.co/blog/async-components-in-vue-3

    或在官方网站上 https://v3.vuejs.org/api/global-api.html#defineasynccomponent

    import { defineAsyncComponent, defineComponent, ref, computed } from "vue"
    
    export default defineComponent({
    setup(){
    const isShow = ref(false);
    const name = computed (() => isShow.value ? defineAsyncComponent(() => import("./DynamicComponent.vue")): '')
    
    const onClick = () => {
        isShow.value = true;
      }
     }
    })
    

    【讨论】:

      【解决方案2】:

      这是在 Vue 3 中加载动态组件的方法。从 /icons 文件夹中以“icon-”为前缀的图标集合的动态导入示例。

      BaseIcon.vue

      <script>
      import { defineComponent, shallowRef } from 'vue'
      
      export default defineComponent({
        props: {
          name: {
            type: String,
            required: true
          }
        },
        setup(props) {
          // use shallowRef to remove unnecessary optimizations
          const currentIcon = shallowRef('')
      
          import(`../icons/icon-${props.name}.vue`).then(val => {
            // val is a Module has default
            currentIcon.value = val.default
          })
      
          return {
            currentIcon
          }
        }
      })
      </script>
      
      <template>
          <svg v-if="currentIcon" width="100%" viewBox="0 0 24 24" :aria-labelledby="name">
            <component :is="currentIcon" />
          </svg>
      </template>
      

      您不需要使用计算或监视。但是在它加载和解析之前没有什么要渲染的,这就是使用v-if 的原因。

      UPD 因此,如果您需要通过更改道具来更改组件(在我的情况下为图标),请使用 watchEffect 作为 import 函数的包装器。

      watchEffect(() => {
        import(`../icons/icon-${props.name}.vue`).then(val => {
          currentIcon.value = val.default
        })
      })
      

      别忘了从 vue 导入它 =)

      【讨论】:

        【解决方案3】:

        组件应添加到components 选项,然后使用基于ref 属性isShow 的计算属性返回它的名称:

        components:{
           MyComponent:defineAsyncComponent(() => import("./DynamicComponent.vue"))
        },
        setup(){
        const isShow = ref(false);
        const name = computed (() => isShow.value ? 'MyComponent': '')
        
        const onClick = () => {
            isShow.value = true;
        }
        }
        

        【讨论】:

          【解决方案4】:

          Async Component.

          一些答案​​显示了如何在computed 中加载异步组件。我最喜欢的方式,我认为它更好,是像这样使用components 属性:

          <template>
            <div class="home">
              <component :is="activeComponent"></component>
            </div>
          </template>
          
          <script>
          import { computed, defineAsyncComponent } from 'vue'
          
          export default {
            components: {
              MyComp: defineAsyncComponent(() => import('./MyComp.vue')),
              MyComp2: defineAsyncComponent(() => import('./MyComp2.vue'))
            },
          
            setup() {
              const activeComponent = computed(() => {
                if (/* condition */) return 'MyComp'
                return 'MyComp2'
              })
          
              return { activeComponent }
            }
          }
          </script>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-04-27
            • 2022-11-05
            • 2022-10-19
            • 2021-10-30
            • 2020-08-13
            • 2022-12-14
            • 1970-01-01
            • 2021-08-03
            相关资源
            最近更新 更多