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>

组件已经有了,但是component宽高为0
Vue3 动态组件 component:is= 失效_第1张图片就上面这个代码,除了没用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>

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>

原因

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

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

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

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

<component :is="getComponentName">component>

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

const getComponentName = computed(() => {
  return componentName.value;
});

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

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

你可能感兴趣的:(vue.js,javascript,前端)