• Vue3 动态组件 component:is= 失效


    错误代码

    Vue3,组件无需注册,所以就会提示“注册了不不使用”的报错,
    于是用了异步注册,甚至直接为了不报错就在下面使用3个组件,有异步加载,但还是实现不了预期效果

    <script setup>
    import { ref, defineAsyncComponent, computed } from 'vue'
    const Son1 = defineAsyncComponent(() => import('./components/BaseSon1.vue'));  
    const Son2 = defineAsyncComponent(() => import('./components/BaseSon2.vue'));  
    const Son3 = defineAsyncComponent(() => import('./components/BaseSon3.vue'));  
    const list = ref([  
        { id: 1, name:'Son1', active: true },
        { id: 2, name:'Son2', active: false },
        { id: 3, name:'Son3', active: false },
    ])  
    let componentName = ref('Son1') 
    const getComponentName = computed(() => {
      return componentName.value;
    }); 
    const handleClick = (item,index) => {
        console.log('item,index',item,index);
        list.value.forEach((i) => {
            i.active = false
        })
        list.value[index].active = true 
        componentName.value = list.value[index].name
        console.log('componentName.value',componentName.value);
    }
    </script>
    <template>
      <div class="app">  
        <component :is="getComponentName"></component>  
        <ul>  
                <li v-for="(item, index) in list" :key="item.id"
                    @click="handleClick(item, index)"
                    :class="{active: item.active}">
            {{ item.name }}  
          </li>  
        </ul>  
      </div>  
      <Son3></Son3>  
      <Son1></Son1>  
      <Son2></Son2>  
    
    </template>
    
    
      
    <style scoped> 
    .active{
      color: red;  
    }  
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    组件已经有了,但是component宽高为0
    在这里插入图片描述
    就上面这个代码,除了没用2个script剩下的没啥大差别了,就不知道为啥上面的不行,可能是预编译啥的吧,求大佬指点

    参看项目代码

    所以,就用两个script
    需要注册,component还有了宽高

    <script>
    import Son1 from './components/BaseSon1.vue'
    import Son2 from './components/BaseSon2.vue'
    import Son3 from './components/BaseSon3.vue'
    export default {
        components: { Son1, Son2, Son3 }
    }
    </script>
    <script setup>
    import { ref, computed } from 'vue'
     
    const list = ref([  
        { id: 1, name:'Son1', active: true },
        { id: 2, name:'Son2', active: false },
        { id: 3, name:'Son3', active: false },
    ])  
    let componentName = ref('Son1') 
    const getComponentName = computed(() => {
      return componentName.value;
    }); 
    const handleClick = (item,index) => {
        console.log('item,index',item,index);
        list.value.forEach((i) => {
            i.active = false
        })
        list.value[index].active = true 
        componentName.value = list.value[index].name
        console.log('componentName.value',componentName.value);
    }
    </script>
    <template>
      <div class="app">  
        <component :is="getComponentName"></component>  
        <ul>  
                <li v-for="(item, index) in list" :key="item.id"
                    @click="handleClick(item, index)"
                    :class="{active: item.active}">
            {{ item.name }}  
          </li>  
        </ul>  
      </div>  
    
    
    </template>
    
    
      
    <style scoped> 
    .active{
      color: red;  
    }  
    </style>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    computed属性

    就是说,还必须用computed属性,单用ref数据给:is还不行,下面是失败案例

    <script>
    import Son1 from './components/BaseSon1.vue'
    import Son2 from './components/BaseSon2.vue'
    import Son3 from './components/BaseSon3.vue'
    export default {
        components: { Son1, Son2, Son3 }
    }
    </script>
    <script setup>
    import { ref } from 'vue'
     
    const list = ref([  
        { id: 1, name:'Son1', active: true },
        { id: 2, name:'Son2', active: false },
        { id: 3, name:'Son3', active: false },
    ])  
    let componentName = ref('Son1') 
    // const getComponentName = computed(() => {
    //   return componentName.value;
    // }); 
    const handleClick = (item,index) => {
        console.log('item,index',item,index);
        list.value.forEach((i) => {
            i.active = false
        })
        list.value[index].active = true 
        componentName.value = list.value[index].name
        console.log('componentName.value',componentName.value);
    }
    </script>
    <template>
      <div class="app">  
        <component :is="ComponentName"></component>  
        <ul>  
                <li v-for="(item, index) in list" :key="item.id"
                    @click="handleClick(item, index)"
                    :class="{active: item.active}">
            {{ item.name }}  
          </li>  
        </ul>  
      </div>  
    
    
    </template>
    
    
      
    <style scoped> 
    .active{
      color: red;  
    }  
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    原因

    在Vue中,使用特定的字符串来动态引入组件是一种常见的方法。这是因为在编译阶段,Vue会解析模板,找到对应字符串的组件并进行渲染。例如,中的字符串"Son2"会被解析为对应的组件并进行渲染。

    然而,当你尝试使用一个变量(如componentName)作为动态组件的名称时,并不能直接使用该变量,因为Vue编译器无法在编译阶段确定要渲染的组件。

    为了解决这个问题,你可以使用Vue的异步组件和动态组件的结合。在这种情况下,你可以将动态组件的名称作为异步组件的引用,然后通过动态绑定的方式将其传递给动态组件。

    你可以修改模板部分的代码如下:

    <component :is="getComponentName">component>
    
    • 1

    然后,在脚本部分添加一个计算属性getComponentName来返回组件名称,代码如下:

    const getComponentName = computed(() => {
      return componentName.value;
    });
    
    • 1
    • 2
    • 3

    这样修改后,当componentName的值发生变化时,动态组件将根据新的组件名称进行更新和渲染。

    请注意,为了让动态组件正常工作,确保组件名称正确且与相应组件的导入路径匹配。

  • 相关阅读:
    《机器人SLAM导航核心技术与实战》第1季:第6章_机器人底盘
    openssl 之 RSA加密数据设置OAEP SHA256填充方式
    DVWA 靶场之 Command Injection(命令执行)middle&high
    GO语言篇之交叉编译
    Python文件读写案例——复制大小文件
    CMU 15-213 CSAPP. Ch11. Dynamic Memory Allocation
    ElasticSearch-数据查询
    JavaScrip 学习笔记
    联合投稿其乐融融 抖音共创助你大显身手
    OpenCV实战完美实现眨眼疲劳检测!!
  • 原文地址:https://blog.csdn.net/weixin_63681863/article/details/133281801