微信小程序写一个树型组件

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.效果展示

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值