vue3 移动端 实现树形结构 tree(支持多选 全选)
实现效果:
)
版本号:
1、需求是支持全选功能,网上找了许多 这里做个记录
这里使用的是vue-virtual-tree 感觉作者写的很详细 可以跳转查看 git地址
2、使用方法
(1)npm i @ysx-libs/vue-virtual-tree
(2)main.js中引入
import '@ysx-libs/vue-virtual-tree/style.css';
(3)页面中使用
点击查看代码
<template>
<!-- 白名单 页面 -->
<div class="content">
<nut-popup :close-on-click-overlay="false" round class="popup_con" position="bottom" :style="{ height: '80%' }"
v-model:visible="showBottom">
<div class="demo">
<div class="check_all_box" >
<nut-checkbox @click="checkAllFun(list)" v-model="checkRadio" checked-color="#ee0a24">
<div class="check_all">全选</div>
</nut-checkbox>
</div>
<!-- <section> -->
<vir-tree ref="virTreeOne" show-checkbox :source="list" :render-node="renderNode"
:default-checked-keys="defaultCheckedKeys" @checkChange=checkChangeHandle()>
</vir-tree>
<!-- </section> -->
</div>
<div class="footer_btn">
<nut-button @click="handleCancel" class="cancel_btn" type="default">取消</nut-button>
<nut-button @click="handleSubmit" class="submit_btn" type="primary">提交</nut-button>
</div>
</nut-popup>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue'
import { VirTree } from '@ysx-libs/vue-virtual-tree';
// 弹窗是否展示
const showBottom = ref(true)
let list = ref([]);
const virTreeOne = ref(null);
let defaultCheckedKeys = ref([]);
let checkRadio = ref(false)
onMounted(() => {
list.value = recursion();
getListLength(list.value)
});
// tree 组件开始
const recursion = () => {
const listData = [
{
nodeKey: '1',
name: '1',
children: [
{
nodeKey: '1.1',
name: '1.1',
children: [
{
nodeKey: '1.11',
name: '1.11',
children: [],
},
],
},
{
nodeKey: '1.2',
name: '1.2',
children: [],
}
],
},
{
nodeKey: '2',
name: '2',
children: [
{
nodeKey: '2.1',
name: '2.1',
children: [],
},
{
nodeKey: '2.2',
name: '2.2',
children: [],
}
],
}, {
nodeKey: '3',
name: '3',
children: [
{
nodeKey: '3.1',
name: '3.1',
children: [],
},
{
nodeKey: '3.2',
name: '3.2',
children: [],
}, {
nodeKey: '3.3',
name: '3.3',
children: [],
}
],
}
];
return listData;
}
// 获取tree 数据总条数
let listLength = ref(0)
let getListLength = (row) => {
row.forEach(ele => {
listLength.value++
if (ele.children) {
getListLength(ele.children)
}
});
}
// 获取选中数据
const checkedNodes = () => {
const checks = virTreeOne.value.getCheckedNodes();
console.log('获取选中', checks);
}
//定义树形结构样式
const renderNode = node => {
return <div style="padding: 0 4px;"><b style=" { color: '#333333',fontSize: '1rem'}">{node.name}</b></div>
};
// 提交按钮
const handleSubmit = () => {
console.log(defaultCheckedKeys.value);
checkedNodes()
}
// 取消按钮
const handleCancel = () => {
showBottom.value = false
}
// 属性组件选中复选框事件
const checkChangeHandle = () => {
if (virTreeOne.value.getCheckedNodes().length == listLength.value) {
checkRadio.value = true
}
if (virTreeOne.value.getCheckedNodes().length != listLength.value) {
checkRadio.value = false
}
}
// 全选按钮
const checkAllFun = (row) => {
console.log('全选按钮',checkRadio.value);
if (checkRadio.value) {
row.forEach(ele => {
defaultCheckedKeys.value = defaultCheckedKeys.value.concat([ele.nodeKey])
if (ele.children) {
checkAllFun(ele.children)
}
});
} else {
defaultCheckedKeys.value = []
}
}
// tree 组件结束
</script>
<style scoped lang='scss'>
.content {
position: relative;
height: 100vh;
}
.up_img {
width: 12px;
height: 12px;
margin-right: 2%;
}
.down_img {
width: 12px;
height: 16px;
margin-right: 2%;
}
::v-deep .vir-tree-wrap .vir-tree-node .node-arrow {
position: absolute !important;
right: 0 !important;
}
::v-deep .nut-popup {
padding: 16px 16px 64px 16px;
box-sizing: border-box;
}
::v-deep .check_all_box {
height: 48px;
display: flex;
align-items: center;
.nut-checkbox__label {
margin-left: 4px !important;
}
.check_all {
font-size: 16px;
font-weight: 600;
letter-spacing: 0px;
line-height: 16px;
color: rgba(51, 51, 51, 1);
}
}
.footer_btn {
position: fixed;
left: 0px;
bottom: 0px;
right: 0px;
width: 100%;
background: rgba(255, 255, 255, 1);
display: flex;
box-shadow: 0px -20px 10px #f8f8f8;
.cancel_btn {
width: 164px;
height: 36px;
font-size: 14px;
color: rgba(153, 153, 153, 1);
border-radius: 51px;
margin: 6px 16px 6px 15px;
}
.submit_btn {
width: 164px;
height: 36px;
font-size: 14px;
border-radius: 51px;
margin: 6px 16px 6px 0px;
}
}
::v-deep .vir-tree {
max-height: calc(80% - 80px) !important;
.vir-tree-node {
border-bottom: 1px solid #ECECEC;
min-height: 32px;
line-height: 32px;
}
.iconzhankai:before {
font-size: 16px;
}
.vir-checkbox .inner {
border-radius: 50% !important;
width: 14px;
height: 14px;
}
.vir-checkbox.checked .inner {
border-color: #DE1627;
background-color: #DE1627;
}
.vir-checkbox.half-checked .inner:after {
background-color: #DE1627 !important;
}
}
</style>
</vir-tree>
(4)问题记录
取消全选:defaultCheckedKeys.value = []
全选:
defaultCheckedKeys.value.push(ele.nodeKey)
// 不生效 使用为下面的方法
defaultCheckedKeys.value = defaultCheckedKeys.value.concat([ele.nodeKey])
// 使用这种方法