uniapp 异步加载 级联选择器
根组件使用thorUI效果使用参数color选中颜色optionsuniapp插槽选项popupTitle弹窗标题placeholderonpopupclosed弹窗关闭popupopened弹窗打开change节点改变readonly只读clearIcon清除按钮border边框地区请求写在组件内了,可以按需调整数据需要处理为互相学习,有问题及时沟通......
·
根组件使用thorUI的级联选择器
效果
<template>
<view class="tui-cascade-selection">
<scroll-view scroll-x scroll-with-animation :scroll-into-view="scrollViewId"
:style="{ backgroundColor: headerBgColor }" class="tui-bottom-line"
:class="{ 'tui-btm-none': !headerLine }">
<view class="tui-selection-header" :style="{ height: tabsHeight, backgroundColor: backgroundColor }">
<view class="tui-header-item" :class="{ 'tui-font-bold': idx === currentTab && bold }"
:style="{ color: idx === currentTab ? activeColor : color, fontSize: size + 'rpx' }"
:id="`id_${idx}`" @tap.stop="swichNav" :data-current="idx" v-for="(item, idx) in selectedArr"
:key="idx">
{{ item.text }}
<view class="tui-active-line" :style="{ backgroundColor: lineColor }"
v-if="idx === currentTab && showLine"></view>
</view>
</view>
</scroll-view>
<swiper class="tui-selection-list" :current="defTab" duration="300" @change="switchTab"
:style="{ height: height, backgroundColor: backgroundColor }">
<swiper-item v-for="(item, index) in selectedArr" :key="index">
<scroll-view scroll-y :scroll-into-view="item.scrollViewId" class="tui-selection-item"
:style="{ height: height }">
<view class="tui-first-item" :style="{ height: firstItemTop }"></view>
<view class="tui-selection-cell" :style="{ padding: padding, backgroundColor: backgroundColor }"
:id="`id_${subIndex}`" v-for="(subItem, subIndex) in item.list" :key="subIndex"
@tap.stop="change(index, subIndex, subItem)">
<icon type="success_no_circle" v-if="item.index === subIndex" :color="checkMarkColor"
:size="checkMarkSize" class="tui-icon-success"></icon>
<image :src="subItem.src" v-if="subItem.src" class="tui-cell-img"
:style="{ width: imgWidth, height: imgHeight, borderRadius: radius }"></image>
<view class="tui-cell-title"
:class="{ 'tui-font-bold': item.index === subIndex && textBold, 'tui-flex-shrink': nowrap }"
:style="{ color: item.index === subIndex ? textActiveColor : textColor, fontSize: textSize + 'rpx' }">
{{ subItem.text }}
</view>
<view class="tui-cell-sub_title" :style="{ color: subTextColor, fontSize: subTextSize + 'rpx' }"
v-if="subItem.subText">{{ subItem.subText }}</view>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
export default {
name: 'tuiCascadeSelection',
emits: ['change', 'complete', 'update'],
props: {
/**
* 如果下一级是请求返回,则为第一级数据,否则所有数据
* 数据格式
[{
src: "",
text: "",
subText: "",
value: 0,
children:[{
text: "",
subText: "",
value: 0,
children:[]
}]
}]
* */
itemList: {
type: Array,
default: () => {
return [];
}
},
/*
初始化默认选中数据
[{
text: "",//选中text
subText: '',//选中subText
value: '',//选中value
src: '', //选中src,没有则传空或不传
index: 0, //选中数据在当前layer索引
list: [{src: "", text: "", subText: "", value: 101}] //当前layer下所有数据集合
}];
*/
defaultItemList: {
type: Array,
default () {
return []
}
},
defaultKey: {
type: String,
default: 'text'
},
//是否显示header底部细线
headerLine: {
type: Boolean,
default: true
},
//header背景颜色
headerBgColor: {
type: String,
default: '#FFFFFF'
},
//顶部标签栏高度
tabsHeight: {
type: String,
default: '88rpx'
},
//默认显示文字
text: {
type: String,
default: '请选择'
},
//tabs 文字大小
size: {
type: Number,
default: 28
},
//tabs 文字颜色
color: {
type: String,
default: '#555'
},
//选中颜色
activeColor: {
type: String,
default: '#5677fc'
},
//选中后文字加粗
bold: {
type: Boolean,
default: true
},
//选中后是否显示底部线条
showLine: {
type: Boolean,
default: true
},
//线条颜色
lineColor: {
type: String,
default: '#5677fc'
},
//icon 大小
checkMarkSize: {
type: Number,
default: 15
},
//icon 颜色
checkMarkColor: {
type: String,
default: '#5677fc'
},
//item 图片宽度
imgWidth: {
type: String,
default: '40rpx'
},
//item 图片高度
imgHeight: {
type: String,
default: '40rpx'
},
//图片圆角
radius: {
type: String,
default: '50%'
},
//item text颜色
textColor: {
type: String,
default: '#333'
},
textActiveColor: {
type: String,
default: '#333'
},
//选中后字体是否加粗
textBold: {
type: Boolean,
default: true
},
//item text字体大小
textSize: {
type: Number,
default: 28
},
//text 是否不换行
nowrap: {
type: Boolean,
default: false
},
//item subText颜色
subTextColor: {
type: String,
default: '#999'
},
//item subText字体大小
subTextSize: {
type: Number,
default: 24
},
// item padding
padding: {
type: String,
default: '20rpx 30rpx'
},
//占位高度,第一条数据距离顶部距离
firstItemTop: {
type: String,
default: '20rpx'
},
//swiper 高度
height: {
type: String,
default: '300px'
},
//item swiper 内容部分背景颜色
backgroundColor: {
type: String,
default: '#FFFFFF'
},
//子集数据是否请求返回(默认false,一次性返回所有数据)
request: {
type: Boolean,
default: false
},
//子级数据(当有改变时,默认当前选中项新增子级数据,request=true时生效)
receiveData: {
type: Array,
default: () => {
return [];
}
},
//改变值则重置数据
reset: {
type: [Number, String],
default: 0
}
},
watch: {
itemList(val) {
this.initData(val, -1);
},
receiveData(val) {
this.subLevelData(val, this.currentTab);
},
reset() {
this.initData(this.itemList, -1);
},
defaultItemList(val) {
this.setDefaultData(val)
}
},
created() {
this.setDefaultData(this.defaultItemList)
},
data() {
return {
currentTab: 0,
defTab: 0,
//tab栏scrollview滚动的位置
scrollViewId: 'id__1',
selectedArr: [],
valueText: ''
};
},
methods: {
setDefaultData(val) {
let defaultItemList = JSON.parse(JSON.stringify(val || []));
if (defaultItemList.length > 0) {
if ((typeof defaultItemList[0] === 'string' || typeof defaultItemList[0] === 'number') && !this
.request) {
let subi = -1
let selectedArr = []
for (let j = 0, len = defaultItemList.length; j < len; j++) {
let item = defaultItemList[j]
let list = []
let obj = {}
if (j === 0) {
list = this.getItemList(-1)
} else {
list = this.getItemList(j - 1, subi, selectedArr)
}
subi = this.getDefaultIndex(list, item)
if (subi !== -1) {
obj = list[subi]
selectedArr.push({
text: obj.text || this.text,
value: obj.value || '',
src: obj.src || '',
subText: obj.subText || '',
index: subi,
scrollViewId: `id_${subi}`,
list: list
})
}
if (subi === -1) break;
}
this.selectedArr = selectedArr;
this.defTab = this.currentTab;
this.$nextTick(() => {
setTimeout(() => {
this.currentTab = selectedArr.length - 1;
this.defTab = this.currentTab;
this.checkCor();
}, 20)
});
} else {
defaultItemList.map(item => {
item.scrollViewId = `id_${item.index}`;
});
this.selectedArr = defaultItemList;
this.defTab = this.currentTab;
this.$nextTick(() => {
setTimeout(() => {
this.currentTab = defaultItemList.length - 1;
this.defTab = this.currentTab;
this.checkCor();
}, 20)
});
}
} else {
this.initData(this.itemList, -1);
}
},
getDefaultIndex(arr, val) {
if (!arr || arr.length === 0 || val === undefined) return -1;
let index = -1;
let key = this.defaultKey || 'text'
for (let i = 0, len = arr.length; i < len; i++) {
if (arr[i][key] == val) {
index = i;
break;
}
}
return index;
},
initData(data, layer) {
if (!data || data.length === 0) return;
if (this.request) {
//第一级数据
this.subLevelData(data, layer);
} else {
let selectedValue = this.selectedValue || {};
if (selectedValue.type) {
this.setDefaultData(selectedValue);
} else {
this.subLevelData(this.getItemList(layer, -1), layer);
}
}
},
removeChildren(data) {
let list = data.map(item => {
delete item['children'];
return item;
});
return list;
},
getItemList(layer, index, selectedArr) {
let list = [];
let arr = JSON.parse(JSON.stringify(this.itemList));
selectedArr = selectedArr || this.selectedArr
if (layer == -1) {
list = this.removeChildren(arr);
} else {
let value = selectedArr[0].index;
value = value === undefined || value == -1 ? index : value;
if (arr[value] && arr[value].children) {
list = arr[value].children;
}
if (layer > 0) {
for (let i = 1; i < layer + 1; i++) {
let val = layer === i ? index : selectedArr[i].index;
list = val === -1 ? [] : (list[val].children || []);
if (list.length === 0) break;
}
}
list = this.removeChildren(list);
}
return list;
},
//滚动切换
switchTab: function(e) {
this.currentTab = e.detail.current;
this.checkCor();
},
//点击标题切换当
swichNav: function(e) {
let cur = e.currentTarget.dataset.current;
if (this.currentTab != cur) {
this.defTab = this.currentTab;
setTimeout(() => {
this.currentTab = cur;
this.defTab = this.currentTab;
}, 20)
}
},
checkCor: function() {
let item = this.selectedArr[this.currentTab];
item.scrollViewId = 'id__1';
this.$nextTick(() => {
setTimeout(() => {
let val = item.index < 2 ? 0 : Number(item.index - 2);
item.scrollViewId = `id_${val}`;
}, 20);
});
if (this.currentTab > 1) {
this.scrollViewId = `id_${this.currentTab - 1}`;
} else {
this.scrollViewId = `id_0`;
}
},
change(index, subIndex, subItem) {
let item = this.selectedArr[index];
if (item.index == subIndex) {
this.$emit('update', this.valueText);
}
item.index = subIndex;
item.text = subItem.text;
item.value = subItem.value;
item.subText = subItem.subText || '';
item.src = subItem.src || '';
this.$emit('change', {
layer: index,
subIndex: subIndex, //layer=> Array index
...subItem
});
if (!this.request) {
let data = this.getItemList(index, subIndex);
this.subLevelData(data, index);
}
},
//新增子级数据时处理
subLevelData(data, layer) {
if (!data || data.length === 0) {
if (layer == -1) return;
//完成选择
let arr = this.selectedArr;
if (layer < arr.length - 1) {
let newArr = arr.slice(0, layer + 1);
this.selectedArr = newArr;
}
let result = JSON.parse(JSON.stringify(this.selectedArr));
let lastItem = result[result.length - 1] || {};
let text = '';
result.map(item => {
text += item.text+'/';
delete item['list'];
//delete item['index'];
delete item['scrollViewId'];
return item;
});
this.$emit('complete', {
result: result,
value: lastItem.value,
text: text.replace(/[&\/]$/,''),
subText: lastItem.subText,
src: lastItem.src
});
} else {
//重置数据( >layer层级)
let item = [{
text: this.text,
subText: '',
value: '',
src: '',
index: -1,
scrollViewId: 'id__1',
list: data
}];
if (layer == -1) {
this.selectedArr = item;
} else {
let retainArr = this.selectedArr.slice(0, layer + 1) || [];
this.selectedArr = retainArr.concat(item);
}
let current = this.selectedArr.length - 1;
if (current >= this.currentTab) {
this.defTab = this.currentTab
}
this.$nextTick(() => {
setTimeout(() => {
this.defTab = current;
this.currentTab = current;
this.scrollViewId = `id_${this.currentTab > 1?this.currentTab - 1:0}`;
}, 50)
});
let result = JSON.parse(JSON.stringify(this.selectedArr));
let lastItem = result[result.length>2?result.length - 2:0] || {};
let text = '';
result.map(item => {
text += item.text+'/';
delete item['list'];
//delete item['index'];
delete item['scrollViewId'];
return item;
});
this.valueText = text.replace('/请选择/', '')
this.$emit('update', {
value: lastItem.value,
text: this.valueText
});
}
},
clear() {
this.initData(this.itemList, -1);
}
}
};
</script>
<style scoped>
.tui-cascade-selection {
width: 100%;
box-sizing: border-box;
}
.tui-selection-header {
width: 100%;
display: flex;
align-items: center;
position: relative;
box-sizing: border-box;
}
.tui-bottom-line {
position: relative;
}
.tui-bottom-line::after {
width: 100%;
content: '';
position: absolute;
border-bottom: 1rpx solid #eaeef1;
-webkit-transform: scaleY(0.5) translateZ(0);
transform: scaleY(0.5) translateZ(0);
transform-origin: 0 100%;
bottom: 0;
right: 0;
left: 0;
}
.tui-btm-none::after {
border-bottom: 0 !important;
}
.tui-header-item {
max-width: 240rpx;
padding: 15rpx 30rpx;
box-sizing: border-box;
flex-shrink: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
position: relative;
}
.tui-font-bold {
font-weight: bold;
}
.tui-active-line {
width: 60rpx;
height: 6rpx;
border-radius: 4rpx;
position: absolute;
bottom: 0;
right: 0;
left: 50%;
transform: translateX(-50%);
}
.tui-selection-cell {
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
}
.tui-icon-success {
margin-right: 12rpx;
}
.tui-cell-img {
margin-right: 12rpx;
flex-shrink: 0;
}
.tui-cell-title {
word-break: break-all;
}
.tui-flex-shrink {
flex-shrink: 0;
}
.tui-font-bold {
font-weight: bold;
}
.tui-cell-sub_title {
margin-left: 20rpx;
word-break: break-all;
}
.tui-first-item {
width: 100%;
}
</style>
<template>
<view class="uni-data-tree">
<view class="uni-data-tree-input" @click="handleInput">
<slot :options="options" :data="gridValue" :error="errorMessage">
<view class="input-value" :class="{'input-value-border': border}">
<text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
<view v-else-if="loading && !isOpened" class="selected-area">
<uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
</view>
<scroll-view v-else-if="gridValue" class="selected-area" scroll-x="true">
<view class="selected-list">
<view class="selected-item" >
<text>{{gridText}}</text>
</view>
</view>
</scroll-view>
<text v-else class="selected-area placeholder">{{placeholder}}</text>
<view v-if="clearIcon && !readonly && gridValue" class="icon-clear" @click.stop="clear">
<uni-icons type="clear" color="#e1e1e1" size="14"></uni-icons>
</view>
<view class="arrow-area" v-if="(!clearIcon || !gridValue) && !readonly ">
<view class="input-arrow"></view>
</view>
</view>
</slot>
</view>
<view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
<view class="uni-data-tree-dialog" v-show="isOpened">
<view class="uni-popper__arrow"></view>
<view class="dialog-caption">
<view class="title-area">
<text class="dialog-title">{{popupTitle}}</text>
</view>
<view class="dialog-close" @click="handleClose">
<view class="dialog-close-plus" data-id="close"></view>
<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
</view>
</view>
<tui-cascade-selection
ref="gridSelet"
height="280px"
:activeColor="color"
:lineColor="color"
:checkMarkColor="color"
:itemList="parentDept"
request
:receiveData="receiveData"
@complete="complete"
@change="change"
@update="update"
></tui-cascade-selection>
</view>
</view>
</template>
<script>
import tuiCascadeSelection from "@/components/thorui/tui-cascade-selection/tui-cascade-selection"
import {departMent} from "@/api/deptList.js"
export default {
name: "grid-cascade-selection",
data() {
return {
parentDept: [],
receiveData: [],
isOpened: false,
gridValue: null,
gridText: ''
};
},
components: {
tuiCascadeSelection
},
emits: ['popupopened', 'popupclosed', 'input', 'change', 'update:modelValue'],
created() {
this.getDeptList(1).then((res)=>{
this.parentDept = res
}).catch((err)=>{
})
},
props: {
color: {
type: String,
default: '#007aff'
},
options: {
type: [Object, Array],
default () {
return {}
}
},
placeholder: {
type: String,
default: '请选择'
},
popupTitle: {
type: String,
default: '请选择'
},
heightMobile: {
type: String,
default: ''
},
readonly: {
type: Boolean,
default: false
},
clearIcon: {
type: Boolean,
default: true
},
border: {
type: Boolean,
default: true
}
},
methods: {
clear() {
this.gridText = ''
this.gridValue = null
this.$emit('input', this.gridValue)
this.$emit('update:modelValue', this.gridValue)
this.$refs.gridSelet.clear()
},
getDeptList(id) {
return departMent({id:id}).then((res)=>{
return res.data.list.map((item)=>{
return {
text: item.deptName,
value: item.ID
}
})
}).catch((err)=>{
})
},
change(e) {
/**
* layer: 0 第几级 index
src: '/static/images/basic/color.png'
subIndex: 2 //当前层级下选中项index
subText: '30人' //选中项数据
text: '高一(3)班'
value: 103 //选中项value数据
* */
// 模拟请求
let value = e.value;
let layer = e.layer;
if (layer === 3) {
//实际中以请求数据为准,无下级数据则传空数组
this.receiveData = [];
} else {
uni.showLoading({
title: '请稍候...'
});
this.getDeptList(value).then((res)=>{
this.receiveData =res.length?res:[]
uni.hideLoading();
}).catch((err)=>{
})
}
},
complete(e) {
this.gridText = e.text
this.gridValue = e.value
this.isOpened = false
this.$emit('input', this.gridValue)
this.$emit('update:modelValue', this.gridValue)
this.$emit('popupclosed')
},
update(value) {
this.gridText = value.text
this.gridValue = value.value
this.$emit('input', this.gridValue)
this.$emit('update:modelValue', this.gridValue)
},
show() {
this.isOpened = true
this.$emit('popupopened')
},
hide() {
this.isOpened = false
this.$emit('popupclosed')
},
handleInput() {
if (this.readonly) {
return
}
this.show()
},
handleClose(e) {
this.hide()
}
}
}
</script>
<style>
.uni-data-tree {
position: relative;
font-size: 14px;
}
.error-text {
color: #DD524D;
}
.input-value {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
flex-wrap: nowrap;
font-size: 14px;
line-height: 38px;
padding: 0 5px;
overflow: hidden;
/* #ifdef APP-NVUE */
height: 40px;
/* #endif */
}
.input-value-border {
border: 1px solid #e5e5e5;
border-radius: 5px;
}
.selected-area {
flex: 1;
overflow: hidden;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.load-more {
/* #ifndef APP-NVUE */
margin-right: auto;
/* #endif */
/* #ifdef APP-NVUE */
width: 40px;
/* #endif */
}
.selected-list {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: nowrap;
padding: 0 5px;
}
.selected-item {
flex-direction: row;
padding: 0 1px;
/* #ifndef APP-NVUE */
white-space: nowrap;
/* #endif */
}
.placeholder {
font-size: 24rpx;
color: #bbbbbb;
}
.input-split-line {
opacity: .5;
}
.arrow-area {
position: relative;
width: 20px;
/* #ifndef APP-NVUE */
margin-bottom: 5px;
margin-left: auto;
display: flex;
/* #endif */
justify-content: center;
transform: rotate(-45deg);
transform-origin: center;
}
.input-arrow {
width: 7px;
height: 7px;
border-left: 1px solid #999;
border-bottom: 1px solid #999;
}
.uni-data-tree-cover {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .4);
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 100;
}
.uni-data-tree-dialog {
position: fixed;
left: 0;
top: 20%;
right: 0;
bottom: 0;
background-color: #FFFFFF;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 102;
overflow: hidden;
/* #ifdef APP-NVUE */
width: 750rpx;
/* #endif */
}
.dialog-caption {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
/* border-bottom: 1px solid #f0f0f0; */
}
.title-area {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
align-items: center;
/* #ifndef APP-NVUE */
margin: auto;
/* #endif */
padding: 0 10px;
}
.dialog-title {
/* font-weight: bold; */
line-height: 44px;
}
.dialog-close {
position: absolute;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 0 15px;
}
.dialog-close-plus {
width: 16px;
height: 2px;
background-color: #666;
border-radius: 2px;
transform: rotate(45deg);
}
.dialog-close-rotate {
position: absolute;
transform: rotate(-45deg);
}
.picker-view {
flex: 1;
overflow: hidden;
}
/* #ifdef H5 */
@media all and (min-width: 768px) {
.uni-data-tree-cover {
background-color: transparent;
}
.uni-data-tree-dialog {
position: absolute;
top: 55px;
height: auto;
min-height: 400px;
max-height: 50vh;
background-color: #fff;
border: 1px solid #EBEEF5;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
border-radius: 4px;
overflow: unset;
}
.dialog-caption {
display: none;
}
.icon-clear {
margin-right: 5px;
}
}
/* #endif */
/* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
/* #ifndef APP-NVUE */
.uni-popper__arrow,
.uni-popper__arrow::after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 6px;
}
.uni-popper__arrow {
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
top: -6px;
left: 10%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
.uni-popper__arrow::after {
content: " ";
top: 1px;
margin-left: -6px;
border-top-width: 0;
border-bottom-color: #fff;
}
/* #endif */
</style>
使用
<grid-cascade-selection class="right" placeholder="请选择行政区划" popup-title="请选择行政区划"
v-model="areaId" @change="onchange" @popupopened="onpopupopened"
@popupclosed="onpopupclosed" style="width: 470rpx;"></grid-cascade-selection>
参数 | |
---|---|
color | 选中颜色 |
options | uniapp插槽选项 |
popupTitle | 弹窗标题 |
placeholder | |
onpopupclosed | 弹窗关闭 |
popupopened | 弹窗打开 |
change | 节点改变 |
readonly | 只读 |
clearIcon | 清除按钮 |
border | 边框 |
地区请求写在组件内了,可以按需调整
getDeptList(id) {
return departMent({id:id}).then((res)=>{
return res.data.list.map((item)=>{
return {
text: item.deptName,
value: item.ID
}
})
}).catch((err)=>{
})
},
change(e) {
/**
* layer: 0 第几级 index
src: '/static/images/basic/color.png'
subIndex: 2 //当前层级下选中项index
subText: '30人' //选中项数据
text: '高一(3)班'
value: 103 //选中项value数据
* */
// 模拟请求
let value = e.value;
let layer = e.layer;
// 数据层级
if (layer === 3) {
//实际中以请求数据为准,无下级数据则传空数组
this.receiveData = [];
} else {
uni.showLoading({
title: '请稍候...'
});
this.getDeptList(value).then((res)=>{
this.receiveData =res.length?res:[]
uni.hideLoading();
}).catch((err)=>{
})
}
}
数据需要处理为
[{
src: "", //图标地址
text: "",//主文本
subText: "",//副文本
value: 0, //value值
children:[{
text: "",//主文本
subText: "",//副文本
value: 0,//value值
children:[] //子级数据 如果数据长度为0则表示没有下一级数据了
}] //子级数据
}]
互相学习,有问题及时沟通
更多推荐
已为社区贡献2条内容
所有评论(0)