先看看是不是你想要的:
当有层级去渲染的时候,嵌套的层级不明确,这时只能通过递归组件去渲染。
数据如下:
通过判断subCatalog这个字段的长度是否大于0来确定是否有下级。
上代码:(代码是使用uniapp开发的,view标签可进行更换)
父组件
<template>
<view>
<my-tree
v-for="(item, index) in list"
:key="index"
:item="item"
:open="openFirst[index]"
@toggleOpen="toggleOpenFirst(index)"
/>
</view>
</template>
<script setup>
import myTree from './components/myTree.vue';
import { ref, watch } from 'vue';
const props = defineProps({
list: { // 展示的层级数据
type: Array,
default: []
}
})
const openFirst = ref([]); // 控制第一级的展开状态
watch(() => props.list, (val) => {
if (val.length > 0) {
openFirst.value = new Array(val.length).fill(false);
}
})
const toggleOpenFirst = (index) => {
openFirst.value[index] = !openFirst.value[index]; // 切换第一级的展开状态
};
子组件:
<template>
<view class="link">
<view class="linkbg">
<view class="links">
// 1、item是父组件传递过来的数据
<view class="links-title" @click="goList(item)">{{ item.name }}</view>
<uv-icon :class="isOpen ? 'arrow-down' : 'arrow-right'" name="arrow-down" v-if="item.subCatalog.length" @click="toggleOpen(item)"></uv-icon>
</view>
<Transition>
<view v-if="isOpen">
<view v-for="(subItem, index) in item.subCatalog" :key="subItem.id">
// 调用自身,1处的item便是subItem了
<my-tree
:item="subItem"
:open="openTwo[index]"
@toggleOpen="toggleSubOpen(index)"
/>
</view>
</view>
</Transition>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
const props = defineProps({
item: {
type: Object,
required: true,
},
open: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['toggleOpen']);
const isOpen = ref(props.open); // 根据 props.open 初始化
const openTwo = ref(new Array(props.item.subCatalog.length).fill(false)); // 初始化子项的展开状态
const goList = (val) => {
}
const toggleOpen = (val) => {
isOpen.value = !isOpen.value; // 切换当前项的展开状态
emit('toggleOpen', props.item); // 触发事件
};
const toggleSubOpen = (index) => {
openTwo.value[index] = !openTwo.value[index]; // 切换子项的展开状态
};
</script>
递归组件的思想,便是和使用递归方法一样,自身去调用自身,以达到遍历每一项的数据。