Vue3 Tabs 动态组件

Posted 安果移不动

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue3 Tabs 动态组件相关的知识,希望对你有一定的参考价值。

效果

 

 A.vue

<template>
  <div class="com">
    你说不会在爱情里犯错

  </div>
</template>
<script lang="ts" setup>

</script>


<style lang="less" scoped>
.com 
  height: 300px;
  border: 2px solid #CCC;
  font-size: 20px;
  display: flex;
  justify-content: center;
  align-items: center;


</style>

B

<template>
  <div class="com">
    也说过会永远的爱我

  </div>
</template>

<script lang="ts" setup>

</script>

<style lang="less" scoped>
  .com
    height: 300px;
    border:2px solid #CCC;
    font-size: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    
  
</style>

C

<template>
  <div class="com">
    才发现只剩下虚伪的承诺
  </div>
</template>

<script lang="ts" setup>

</script>

<style lang="less" scoped>
  .com
    height: 300px;
    border:2px solid #CCC;
    font-size: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    
  
</style>

App

<template>
  <div style="display: flex">
    <div :class="[active === index?'active':'']" class="tabs" v-for="(item,index) in data"
         :key="item.name"
         @click="switchCom(item,index)">
       item.name 
    </div>

  </div>
  <component :is="comId"></component>

</template>

<style scoped>
#app, html, body 

  height: 100%;


* 
  padding: 0;
  margin: 0;


.tabs 
  border: 1px solid #CCC;
  padding: 5px 10px;
  margin: 10px;
  cursor: pointer;


.active 
  background: skyblue;


</style>

<script setup lang="ts">

import AVue from "./components/A.vue";
import BVue from "./components/B.vue";
import CVue from "./components/C.vue";
import reactive, ref from "vue";

const data = reactive([
  
    name: "A组件",
    com: AVue
  ,
  
    name: "B组件",
    com: BVue
  ,
  
    name: "C组件",
    com: CVue
  

])
const comId = ref(AVue)
const active = ref(0)

const switchCom = (item: any, index: number) => 
  comId.value = item.com
  console.log( comId.value)
  active.value = index


</script>

这里控制台会报错

runtime-core.esm-bundler.js:40 [Vue warn]: Vue received a Component which was made a reactive object. This can lead to unnecessary performance overhead, and should be avoided by marking the component with `markRaw` or using `shallowRef` instead of `ref`. 
Component that was made reactive:  __hmrId: '65097ce7', __scopeId: 'data-v-65097ce7', __file: 'H:/develop/project/web/learn/vite-demo/src/components/A.vue', render: ƒ 
  at <App>

不过没关系 我们可以按照建议使用 markRaw 和 shallowRef 来避免报错 来正确应用这些组件

 

 最后代码

<template>
  <div style="display: flex">
    <div :class="[active === index?'active':'']" class="tabs" v-for="(item,index) in data"
         :key="item.name"
         @click="switchCom(item,index)">
       item.name 
    </div>

  </div>
  <component :is="comId"></component>

</template>

<style scoped>
#app, html, body 

  height: 100%;


* 
  padding: 0;
  margin: 0;


.tabs 
  border: 1px solid #CCC;
  padding: 5px 10px;
  margin: 10px;
  cursor: pointer;


.active 
  background: skyblue;


</style>

<script setup lang="ts">

import AVue from "./components/A.vue";
import BVue from "./components/B.vue";
import CVue from "./components/C.vue";
import markRaw, reactive, ref, shallowRef from "vue";

const data = reactive([
  
    name: "A组件",
    com: markRaw(AVue)
  ,
  
    name: "B组件",
    com: markRaw(BVue)
  ,
  
    name: "C组件",
    com: markRaw(CVue)
  

])
const comId = shallowRef(AVue)
const active = ref(0)

const switchCom = (item: any, index: number) => 
  comId.value = item.com
  console.log(comId.value)
  active.value = index


</script>

还有一种比较类似vue2的写法。先引入组件再使用字符串就行啦

<template>
  <div style="display: flex">
    <div :class="[active === index?'active':'']" class="tabs" v-for="(item,index) in data"
         :key="item.name"
         @click="switchCom(item,index)">
       item.name 
    </div>

  </div>
  <component :is="comId"></component>

</template>

<style scoped>
#app, html, body 

  height: 100%;


* 
  padding: 0;
  margin: 0;


.tabs 
  border: 1px solid #CCC;
  padding: 5px 10px;
  margin: 10px;
  cursor: pointer;


.active 
  background: skyblue;


</style>

<script setup lang="ts">


import markRaw, reactive, ref, shallowRef from "vue";

const data = reactive([
  
    name: "A组件",
    com: 'AVue'
  ,
  
    name: "B组件",
    com: 'BVue'
  ,
  
    name: "C组件",
    com: 'CVue'
  

])
const comId = shallowRef("AVue")
const active = ref(0)

const switchCom = (item: any, index: number) => 
  comId.value = item.com
  console.log(comId.value)
  active.value = index


</script>
<script lang="ts">
import AVue from "./components/A.vue";
import BVue from "./components/B.vue";
import CVue from "./components/C.vue";
export default 
  components: 
    AVue,
    BVue,
    CVue
  
;
</script>

以上是关于Vue3 Tabs 动态组件的主要内容,如果未能解决你的问题,请参考以下文章

如何通过选定的道具动态地更改 vue js 2 中的选项卡?

Vue.js Vue3 子组件的不同模板

vue3.0js局部组件注册案例

vue3.0js局部组件注册案例

Vue3@cli项目结构

Vue3 从控制台访问组件数据属性