创建组件 BoxA
<template>
<div>
<input type="text" placeholder="A"/>
</div>
</template>
<script>
</script>
<style>
</style>
创建组件 BoxB
<template>
<div>
<button>test B</button>
</div>
</template>
<script>
</script>
<style>
</style>
在 App.vue 中编写的示例
<script setup>
import { ref } from 'vue';
import BoxAVue from './views/BoxA.vue';
import BoxBVue from './views/BoxB.vue';
const componentName = ref('BoxAVue');
function change() {
if (componentName.value == 'BoxAVue') {
componentName.value = 'BoxBVue';
} else {
componentName.value = 'BoxAVue';
}
}
</script>
<template>
<div>
<div>name: {{ componentName }}</div>
<component :is="componentName"></component>
<button @click="change">change</button>
</div>
</template>
<style>
</style>
结果会发现组件 BoxAVue 并没有渲染出来,打开控制台会看到,组件是存在的,但是大小为 0,且控制台提示误节点
解决:
1.查看官方演练场中的示例代码发现差别:
通过打印,可以看到,这里的
<component :is="tabs[componentName]"></component>
之中的 :is=""
传入的是组件对象,而不是组件名,修改 App.vue 中的代码如下,组件运行正常
<script setup>
import { ref } from 'vue';
import BoxAVue from './views/BoxA.vue';
import BoxBVue from './views/BoxB.vue';
const tabs = {
BoxAVue,
BoxBVue
};
const componentName = ref('BoxAVue');
function change() {
if (componentName.value == 'BoxAVue') {
componentName.value = 'BoxBVue';
} else {
componentName.value = 'BoxAVue';
}
}
</script>
<template>
<div>
<div>name: {{ componentName }}</div>
<component :is="tabs[componentName]"></component>
<button @click="change">change</button>
</div>
</template>
<style>
</style>
2.然而官方文档之中,是可以通过组件名设置进行使用的,那么问题在哪?
参考这篇Vue3 动态组件 component:is= 失效,新增一个 <script></script>
标签,在其中导入组件,并且通过 export default{ components:{} }
进行注册,正常通过组件名的方式运行动态组件,修改代码如下:
<script>
import BoxAVue from './views/BoxA.vue';
import BoxBVue from './views/BoxB.vue';
export default {
components: {
BoxAVue,
BoxBVue
}
}
</script>
<script setup>
import {
RouterLink,
RouterView
} from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
import { ref } from 'vue';
const componentName = ref('BoxAVue');
function change() {
if (componentName.value == 'BoxAVue') {
componentName.value = 'BoxBVue';
} else {
componentName.value = 'BoxAVue';
}
}
</script>
<template>
<div>
<div>name: {{ componentName }}</div>
<component :is="componentName"></component>
<button @click="change">change</button>
</div>
</template>
<style>
</style>
也就是说,如果是使用 选项式 API 的风格进行代码编写,正常注册组件的情况下应该不会碰到这个问题吧
总结:使用导入的组件名作为 <component :is=""></component>
的参数,在使用组合式API 的编写风格时,需要先用选项式引入并且注册组件