vue3使用递归组件渲染层级结构

先看看是不是你想要的:

当有层级去渲染的时候,嵌套的层级不明确,这时只能通过递归组件去渲染。

数据如下:

通过判断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>

递归组件的思想,便是和使用递归方法一样,自身去调用自身,以达到遍历每一项的数据。

相关推荐
一个处女座的程序猿O(∩_∩)O几秒前
完成第一个 Vue3.2 项目后,这是我的技术总结
前端·vue.js
mubeibeinv1 分钟前
项目搭建+图片(添加+图片)
java·服务器·前端
逆旅行天涯7 分钟前
【Threejs】从零开始(六)--GUI调试开发3D效果
前端·javascript·3d
m0_7482552628 分钟前
easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层
前端·excel
长风清留扬1 小时前
小程序毕业设计-音乐播放器+源码(可播放)下载即用
javascript·小程序·毕业设计·课程设计·毕设·音乐播放器
web147862107231 小时前
C# .Net Web 路由相关配置
前端·c#·.net
m0_748247801 小时前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖1 小时前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案11 小时前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl