1.现在components新建一个tree文件夹(放置树形组件)
2.再把我们的树声明在app.json里,全局使用
3.开始造树(就是拿到树形结构数据,然后回调自身,拿到每一个自身的值重新赋值到一个新的数组内,在数组内的数据与树的值相等的时候就选中否则就取消)
tree.wxml
<view wx:for="{{tree}}" wx:key="index" class="tree">
<!-- 第一层 -->
<view class="name" style="background-color: white;padding: 10rpx;" wx:if="{{item.extend.hide !=true && item.dictType !=305}}">
<text>{{ item.dictName }}<text style="color: #FE3434" wx:if="{{ item.extend.required }}">(必填)</text><text wx:else></text><text wx:if="{{ item.extend.single }}"></text><text wx:else>(多选项)</text></text>
</view>
<!-- 单选框 -->
<view style="background-color: white;padding: 10rpx;padding-left: 0;" wx:if="{{item.extend.single == true}}">
<van-radio-group value="{{ item.valueIds[0]}}" data-index="{{ topIndex }}" direction="horizontal">
<view wx:for="{{item.children}}" wx:for-item="items" wx:key="index" class="flex-vertical flex-between post-option-item">
<van-radio style="margin-left: 25rpx;margin-top: 20rpx;" name="{{ items.dictId }}" bind:tap="selectOne" data-item="{{items}}" data-index="{{index}}">
{{ items.dictName }}
<input wx:if="{{items.extend.input}}" class="weui-inputs" maxlength="{{items.extend.lengths}}" bindblur="selectinput" value="{{items.text}}" data-item="{{items}}" data-index="{{index}}"/>
</van-radio>
</view>
</van-radio-group>
</view>
<!-- 多选框 -->
<view style="background-color: white;padding: 10rpx;padding-left: 30rpx;" wx:if="{{item.extend.single == false}}">
<van-checkbox-group value="{{ item.valueIds || [] }}" direction="horizontal">
<!-- 第二层 -->
<view wx:for="{{item.children}}" wx:for-item="items" wx:key="index" class="flex-vertical flex-between post-option-item">
<van-checkbox style="margin:10rpx 0 20rpx 0;" bind:tap="select" name="{{ items.dictId }}" data-item="{{items}}" data-index="{{index}}">
{{ items.dictName}}
</van-checkbox>
</view>
</van-checkbox-group>
</view>
<-- 带进来的树干 -->
<z-tree wx:if="{{item.children && item.children.length > 0 && item.open}}" dataTree='{{item.children}}' selectKey="{{selectKey}}" isSelectLastNode="{{isSelectLastNode}}" isOpenAll="{{isOpenAll}}" bindnodechanged="_handleChildNodeChanged">
</z-tree>
</view>
tree.js
Component({
/**
* 组件的属性列表
*/
properties: {
dataTree: {
type: Array,
value: [],
observer: function (newVal, oldVal, changedPath) {
}
},
old: {
type: Array,
value: []
},
selectKey: { // 选中的节点id
type: String,
value: ''
},
parentId: { // 工种id
type: String,
value: ''
},
isSelectLastNode: { //是否必须选中最后一节点
type: Boolean,
value: false
},
isOpenAll: { //是否展开全部节点
type: Boolean,
value: false
}
},
observers: {
'dataTree': function(params) {
params.forEach(v => {
v.open = this.properties.isOpenAll // 是否展开
})
this.setData({
tree: params
})
},
},
/**
* 组件的初始数据
*/
data: {
tree: [],
oldTree:[],
showtree:true,
requiredTool:true,
},
/**
* 组件的方法列表
*/
methods: {
isOpen(e) {
const open = 'tree[' + e.currentTarget.dataset.index + '].open'
this.setData({
[open]: !this.data.tree[e.currentTarget.dataset.index].open
})
},
onChangeRequiredTool(e) {
this.setData({
requiredTool: e.detail,
});
this.triggerEvent('bring',this.data.requiredTool)
},
// 刷新树
_refreshTree:function(nodes){
// console.log(nodes)
this.setData({
tree : nodes,
});
// 然后向父结点抛出一个nodeChanged事件
var myEventDetail = {
nodes: nodes
} // detail对象,提供给事件监听函数
var myEventOption = {} // 触发事件的选项
this.triggerEvent('nodechanged', myEventDetail, myEventOption)
this.triggerEvent('comclick',this.data.tree)
},
_handleChildNodeChanged:function(e){
// 处理子结点抛出的nodeChanged事件
var nodes = this.data.tree;
var detail=e.detail.nodes;
// console.log(detail);
// console.log(nodes)
for (var i = 0; i < nodes.length; i++) {
if(nodes[i].children) {
for(var k=0;k<nodes[i].children.length;k++) {
for(var j=0;j<detail.length;j++) {
if (nodes[i].children[k].dictId == detail[j].dictId) {
nodes[i].children[k] = detail[j];
}
}
}
}
}
this.setData({
tree: nodes,
});
this._refreshTree(this.data.tree);
},
//单选框
selectOne(e) {
const item = e.currentTarget.dataset.item
this.setData({
tree: this.fnOne(this.data.tree,item.dictId),
})
this._refreshTree(this.data.tree);
},
//多选框
select(e) {
const item = e.currentTarget.dataset.item
this.setData({
tree: this.fn2(this.data.tree,item.dictId),
})
this._refreshTree(this.data.tree);
},
//单选添加,删除值
fnOne(arr,dictId) {
var flag=false;
arr.forEach((item) => {
if(item.children&&item.depth%2==0){
item.children.forEach((element) => {
if(element.dictId==dictId) {
item.valueIds=[];
item.value=[];
// item.valueIds.length = 0;
// item.value.length = 0;
flag=true;
item.valueIds.push(dictId);
item.value.push(element)
}
})
if(flag) {
item.children.forEach((element) => {
if(element.children&&element.dictId==dictId){
element.children.forEach((elements) => {
elements.show = true
});
}
if(element.children&&element.dictId!=dictId){
element.children.forEach((elements) => {
elements.show = false;
});
}
});
flag=false;
}
// 先判断当前项是否是对象。 当前项是否存在你想要的数据。都符合,把数据push到新数组里
item.children && item.children instanceof Array && this.fn2(item.children,dictId)
// 当前项是否还有子节点,子节是否是数组, 如果是继续调用自己。再循环遍历一次.
}
})
return arr
},
//输入框
selectinput(e){
const item = e.currentTarget.dataset.item
this.setData({
tree: this.fn3(this.data.tree,item.dictId,e.detail.value),
})
this._refreshTree(this.data.tree);
},
//输入框添加,删除值
fn3(arr,dictId,value){
arr.forEach((item)=>{
if(item.children&&item.depth%2==0){
item.children.forEach((element) => {
if(element.dictId==dictId) {
var valueIds=[];
var values=[];
var flag=true;
if(item.value) {
item.value.forEach((obj) =>{
if(obj.dictId==dictId) {
flag=false;
obj.dictName=value;
obj.showName=element.extend.unit?element.dictName+value+element.extend.unit:value
valueIds.push(obj.dictId);
values.push(obj)
}else {
valueIds.push(obj.dictId);
values.push(obj)
}
})
}
if(flag) {
valueIds.push(dictId);
values.push({
dictId:dictId,
dictName:value,
showName:element.extend.unit?element.dictName+value+element.extend.unit:value
})
}
element.text=value;
item.valueIds=valueIds;
item.value=values;
}
})
item.children && item.children instanceof Array && this.fn2(item.children,dictId,value)
}
})
return arr
},
//多选添加删除值
fn2(arr,dictId) {
var flag=true;
var flagTwo=false;
arr.forEach((item) => {
if(item.children&&item.depth%2==0){
item.children.forEach((element) => {
if(element.dictId==dictId) {
if(item.valueIds){
var newValueIds=[];
var value=[];
item.valueIds.forEach((res =>{
if(res == dictId){
flag=false;
}else {
newValueIds.push(res);
}
}))
if(item.value){
item.value.forEach((resx=>{
if(resx.dictId != dictId){
value.push(resx)
}
}))
}
// console.log(value)
// console.log(newValueIds)
if(!flag) {
item.value = value
item.valueIds=newValueIds;
flagTwo=false;
}else {
item.value.push(element)
item.valueIds.push(dictId);
flagTwo=true;
}
}
}
})
item.children.forEach((element) => {
if(flagTwo) {
if(element.children&&element.dictId==dictId){
element.children.forEach((elements) => {
elements.show = true
});
}
}else {
if(element.children&&element.dictId==dictId){
element.children.forEach((elements) => {
elements.show = false;
});
}
}
});
// 先判断当前项是否是对象。 当前项是否存在你想要的数据。都符合,把数据push到新数组里
item.children && item.children instanceof Array && this.fn2(item.children,dictId)
// 当前项是否还有子节点,子节是否是数组, 如果是继续调用自己。再循环遍历一次.
}
})
return arr
},
},
})
4.在页面上使用树的结构
<z-tree
dataTree="{{reszero}}"
selectKey="{{selectKey}}"
bindcomclick="returndatas"
isSelectLastNode="true"
isOpenAll="true"
bindbring="requiredTool"
></z-tree>
5.操作树返回过来的数据
//树的返回
returndatas(e:any){
var how = {};
var extend=[];
var money =[];
var moneyname = []
how = this.arrz(e.detail,extend,money,moneyname);
extend = how.extend
this.setData({extends:extend})
},
//回调树拿到其中的值
arrz(arr:any,extend:[],money:[],moneyname:[]){
arr.forEach((item:any) => {
if(item.value) {
if(item.show){
extend.push({dictId:item.dictId,dictName:item.dictName,showName:item.showName?item.showName:item.dictName,extend:item.extend,value:item.value})
item.value.forEach(elements => {
money.push(elements.dictId)
});
moneyname.push(item)
}
}
item.children && item.children instanceof Array && this.arrz(item.children,extend,money,moneyname)
})
return {extend:extend,money:money,moneyname:moneyname};
},
//计算其中的价格
sunmoney(money,moneyname){
moneyname.forEach(element => {
if(element.value[0].dictName == ""){
jobApi.queryDictPrice(money).then((data:any)=>{
this.setData({dayPricex:data.dayPrice,nightPricex:data.nightPrice,dayOvertimePrice:data.dayOvertimePrice,nightOvertimePrice:data.nightOvertimePrice})
})
}
if(element.value[0].dictName == ""){
jobApi.queryDictPrice(money).then((data:any)=>{
this.setData({dayPricex:parseFloat(data.dayPrice) + 20,nightPricex:parseFloat(data.nightPrice) + 20,dayOvertimePrice:data.dayOvertimePrice,nightOvertimePrice:data.nightOvertimePrice})
})
}
});
},
6.效果展示