初始简洁版:
<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