Vue 笔记-动态组件(component+is 关键字切换组件

2023-11-26  本文已影响0人  lmao94

创建组件 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,且控制台提示误节点

image.png

解决:
1.查看官方演练场中的示例代码发现差别:

image.png
通过打印,可以看到,这里的 <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.然而官方文档之中,是可以通过组件名设置进行使用的,那么问题在哪?


image.png

参考这篇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 的编写风格时,需要先用选项式引入并且注册组件

上一篇 下一篇

猜你喜欢

热点阅读