错误代码
用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].nameconsole.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
就上面这个代码,除了没用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].nameconsole.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].nameconsole.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的值发生变化时,动态组件将根据新的组件名称进行更新和渲染。
请注意,为了让动态组件正常工作,确保组件名称正确且与相应组件的导入路径匹配。