一个场景大家都会遇到过,就是tab切换,那这个其实在原生js里就是属性对应什么的,稍微啰嗦。那在在框架里就简单一些了。不过框架了的写法也有不一样的。
1. 一组件 + 判断
什么意思呢,就是都写在一个组件了,没有父组件子组件的说法,用v-if来判断渲染。
<div class="page">
<Nav :active="active" :list="list"></Nav>
<main class="main">
<template v-if="active === 0">
<img src="https://picsum.photos/500/400" alt="" />
</template>
<template v-else-if="active === 1">
<div>你好</div>
</template>
<template v-else>
<div>
<input type="text" placeholder="请输入" />
</div>
</template>
</main>
</div>
就是这么一个结构,当数据量少的时候,还能写一写,但当数据量一多,几千行代码的时候,那是既不利于阅读,也不利于维护。所以这种是非常不建议使用的。
2. 子组件 + 判断
这是比较普遍了,或者说我之前见到的部分同事是这么写的,就是写在不同子组件里,然后v-if渲染。
<template>
<div class="page">
<Nav :active="active" :list="list" @onTab="changeTab"></Nav>
<A v-if="active === 0"></A>
<B v-else-if="active === 1"></B>
<C v-else></C>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import Nav from "@/components/nav/index.vue";
import A from "./components/a.vue";
import B from "./components/b.vue";
import C from "./components/c.vue";
const active = ref(0);
const list = ref([
{ title: "首页", id: 0 },
{ title: "分类", id: 1 },
{ title: "标签", id: 2 },
]);
const changeTab = (val) => {
active.value = val.id;
};
</script>
动态组件
这么写起来就比较方便了,不像之前需要在template里动态渲染,这个动态渲染的步骤由动态组件来完成。
<div class="page">
<Nav :active="active" :list="list" @onTab="changeTab"></Nav>
<keep-alive>
<component :is="currentComputent"></component>
</keep-alive>
</div>
使用动态组件,并且把状态缓存,下一次切换是从缓存里拿,这就不像上面的需要v-if然后动态创建dom,那在性能上也是有了提高。
const currentComputent = shallowRef(A); //不需要 响应式 用 shallowRef 代替 ref
const changeTab = (val) => {
active.value = val.id;
const obj = {
0: A,
1: B,
2: C,
};
currentComputent.value = obj[val.id];
};