tree递归组件

本文介绍了如何在Vue.js中创建一个递归组件来展示树形结构数据,包括初始简洁版和带复选框的功能增强版。通过list.vue文件的代码示例,展示了组件的实现,同时提到了在list.scss中进行的样式调整。对于复杂逻辑,可以参考group_flag.vue中的复选框逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初始简洁版:
<template>
  <li v-for="(item,index) in list" :key="index" @click.stop="openUl(item)">
    {
  { item.title }}
    <ul v-if="item.children&&item.children.length" v-show="item.isOpen">
      <d-tree :options="item.children" />
    </ul>
  </li>
</template>

<script setup lang="ts">
import {
      ref } from "vue"
const prop = defineProps<{
     
    data: any
}>()
const list = ref(prop.data)
const openUl = (item:any) => {
     
  item.isOpen = !item.isOpen
}
</script>

带复选框版:

使用:

<template>
  <d-list :data="list" :value="value" shadow line bg multiple hover recursion icon checkbox />
  <!-- <d-list :data="list" :value="value" shadow line bg multiple tick hover /> -->
</template>

<script setup lang="ts">
import {
      ref } from "vue"

const value = ref("1,2,3")

const list = [
  {
     
    title: "列表一",
    value: "1",
    icon: "caret-right",
    children: [
      {
     
        title: "子级1",
        value: "1",
        icon: "caret-right",
        children: [
          {
     
            title: "子级2",
            value: "1",
            icon: "caret-right",
            children: [
              {
     
                title: "子级3",
                value: "1",
                icon: "caret-right",
                children: [
                  {
      title: "子级4", value: "2" },
                  {
      title: "子级44", value: "2" }
                ]
              }
            ]
          }, {
     
            title: "子级22",
            value: "1",
            icon: "caret-right"
          }
        ]
      },
      {
     
        title: "子级11",
        value: "1",
        icon: "caret-right",
        children: [
          {
     
            title: "子级2",
            value: "1",
            icon: "caret-right",
            children: [
              {
      title: "子级3", value: "2" }
            ]
          }
        ]
      }
    ]
  },
  {
      title: "列表二", value: "2" }/* ,
  { title: "列表3", value: "3", icon: "info", disabled: true }*/
]
</script>

list.vue
<template>
  <ul class="d-list" :class="css">
    <li class="d-list__item" v-for="(item,index) in list" :key="index" :class="{ 'is-selected': getSelected(item) >= 0 && !recursion, 'is-disabled': item.disabled , 'is-follow': recursion,'is-color': item.isOpen}" @click.stop="onSelected(item)">
      <div class="d-item">
        <d-icon :name="item.icon" class="d-list__icon" v-if="icon && item.icon" />
        <span class="d-list__checkbox" v-if="checkbox" @click.stop>
          <input v-model="item.isChecked" class="d-input" type="checkbox" @change="doSelect(item, item.isChecked), doReverse(item, parentData)">
        </span>
        <span class="d-title" :class="{'is-last': !item.icon && !checkbox}">{
  { item.title }}</span>
        <d-icon name="arrow-right" class="d-list__icon" v-if="!center && !tick && (arrow || icon) && item.children" />
        <d-icon name="tick" class="d-list__current" v-if="!center && !arrow && tick && getSelected(item) >= 0" />
      </div>
      <d-list v-if="item.children&&item.children.length" v-show="showChild?item.isOpen=showChild:item.isOpen" :data="item.children" :parent-data="item" @change="handleParentChange" :icon="props.icon" :checkbox="props.checkbox" :recursion="props.recursion" :show-child="props.showChild" />
    </li>
    <li class="d-list__item is-disabled" v-if="none && data.length == 0">
      {
  { $t("select-none") }}
    </li>
  </ul>
</template>

<script setup lang="ts">
import {
      ref, computed, watch, onMounted } from "vue"

const emits = defineEmits(["update", "change"])
const props = withDefaults(
  defineProps<{
     
    data: any, // 数据
    value?: string, // 选中值,多选时用英文,分隔
    striped?: boolean, // 斑马线
    shadow?: boolean, // 显示阴影
    center?: boolean, // 居中显示
    bg?: boolean, // 背景色
    border?: boolean, // 边框
    line?: boolean, // 线分隔
    size?: string, // 列表尺寸
    scroll?: boolean, // 溢出滚动
    hover?: boolean, // 悬浮变色
    icon?: boolean, // 图标列表
    arrow?: boolean, // 显示箭头
    tick?: boolean, // 显示打勾
    multiple?: boolean, // 是否可多选
    none?: boolean, // 无内容时提示
    parentData?: any, // 上层数据
    recursion?:boolean, // 递归子级(纵向)
    showChild?:boolean, // 显示递归子级
    checkbox?:boolean, // 复选框
  }>(),
  {
     
    striped: false,
    shadow: false,
    center: false,
    bg: false,
    border: false,
    line: false,
    icon: false,
    scroll: false,
    hover: false,
    multiple: false,
    size: "",
    value: ""
  }
)
const list = ref(props.data)
const
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值