element-ui tree form, check on the left, and display the selected data-function on the right (such as animation)

The function is as shown in the figure

Functional Requirements

The table tree table checks the data, and the corresponding checked data content is displayed on the right. When the customer is selected, all stores (child levels) are automatically checked. When one of the stores is selected, the customer (parent level) is automatically checked. At the same time, there will be only Customer (if there are no sub-levels below), this function also involves selecting all (not going into details), searching for a check, searching for one of the stores, or searching for customers to display all stores with a check (as shown in the dynamic picture above)

Functional ideas

The first step is to confirm whether it is a check action or an uncheck action.

In the second step, we confirm which data is currently selected.

In the third step, we confirm whether the checked type is a customer or a store.

The fourth step is to perform different logical operations based on the check action and check type.

1. This is the selected state---the store is selected at this time. By comparing the store data under the customer data on the current page with our currently selected data, we can find the currently selected customer data (leftParent). There are two types Condition

  • At this time, the customers mounted in the store do not exist on the right side. You need to check the customers at the same time and add data to the right side.
  • At this time, the customers mounted by the store exist on the right side. You only need to add the store data to the right side.

If the customer is selected at this time, there are two situations:

  • If there is a store, (checking the customer will automatically select the store and trigger the following operation of clicking the store)
  • There is a situation where there is no store but only customers (rewrite a situation where there is no store, that is, the currently clicked target.shopList has no value or is an empty array)

2. This is the unchecked state - this is the selected store. First, compare the store data under the customer data on the current page with our currently selected data to find the currently selected customer data (leftParent), and then When you know, all the data on the right is looped and compared with the currently selected customer data on the left, and you can find the same data on the right and left at this time (rightParent)

  • At this time, find the length of the shopList under the same data rightParent is greater than 0, find the subscript of the current store, and then cancel the check
  • When the length of rightParent's shopList is equal to 0, it means that all store data at this time are unchecked. At this time, the customer's check box must be unchecked at the same time.

At this time, the check is unchecked - the customer is selected at this time, two situations

  • The clicked customer does not have a store (cancel the customer directly)
  • The clicked customer has a store (click the customer, trigger the click event and uncheck all stores, and go to the above store to uncheck the event)

data structure

[
  {
    "custId": "460860740775766666",
    "custCode": "ZT10009999",
    "custName": "邵阳县永民雄新置业有限公司",
    "labels": null,
    "labelnames": "智屏传统(剔除福州),乐华代理商",
    "shopCodes": null,
    "shopList": [
      {
        "shopId": "460861654907518976",
        "shopCode": "DP20230625366666",
        "shopName": "智能家庭京东专卖店1号店",
        "labels": null,
        "labelnames": null
      },
      {
        "shopId": "460864194063667200",
        "shopCode": "DP202306258888888",
        "shopName": "酷友天猫优品旗舰店1号店",
        "labels": null,
        "labelnames": null
      },
      {
        "shopId": "460865727429906432",
        "shopCode": "DP20230625188888",
        "shopName": "酷友天猫优品旗舰店2号店",
        "labels": null,
        "labelnames": null
      },
      {
        "shopId": "460888467817926656",
        "shopCode": "DP20230625179999",
        "shopName": "智能家庭京东专卖店2号店",
        "labels": null,
        "labelnames": null
      }
    ]
  },
  {
    "custId": "470195685059002368",
    "custCode": "ZT10006888",
    "custName": "邵阳县大山贸易有限公司",
    "labels": null,
    "labelnames": null,
    "shopCodes": null,
    "shopList": null
  }
]

Part of the code is as follows

            <el-table
              ref="filterCusTable"
              v-loading="leftLoading"
              :data="customerList"
              :show-header="true"
              tooltip-effect="dark"
              :header-cell-class-name="cellClass"
              default-expand-all
              :tree-props="{ children: 'shopList' }"
              row-key="custCode"
              max-height="600"
              min-height="400"
              @select="selectChange"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="30"></el-table-column>
              <el-table-column
                label="客户名称"
                prop="custName"
              ></el-table-column>
              <el-table-column
                label="客户编码"
                prop="custCode"
              ></el-table-column>
              <el-table-column
                label="客户标签"
                prop="labelnames"
              ></el-table-column>
            </el-table>

/**
       * 用于树形表格多选,单选的封装
       * @param selection
       * @param row
       */
      selectChange(selection, row) {
        console.log('selection', selection, row)
        const isCust = Array.isArray(row.shopList)
        //勾选的客户把以下的店铺全部带上勾选
        if (isCust) {
          const isAdd = !this.leftSelectedList.some(
            (cust) => cust.custCode === row.custCode
          )
          console.log('isAdd', isAdd)
          // 这里得 nextTick
          this.$nextTick(() => {
            row.shopList.forEach((shop) =>
              this.$refs.filterCusTable.toggleRowSelection(shop, isAdd)
            )
          })
        }
      },


      //左侧客户选择
      handleSelectionChange(selections) {
        console.log('selections2', selections)
        if (this.initializing == true) return
        //selections是当前页勾选的数据 包含了客户和店铺
        //this.leftSelectedList 一开始进来页面此时左边已经勾选上的数据(切换分页的时候会跟着变化是当前页所勾选的数据)
        // 判断是新增还是减少
        let isAdd = false
        //当前选中的数据
        let target = null
        //选中的方法
        const toggleSelection = (row, selected) =>
          this.$refs.filterCusTable.toggleRowSelection(row, selected)
        console.log('selections2', selections)
        console.log('this.leftSelectedList', this.leftSelectedList)
        if (
          //可能会存在重复的数据
          selections.length > uniqBy(this.leftSelectedList, 'custCode').length
        ) {
          isAdd = true
          //创建一个具有唯一array值的数组,每个值不包含在其他给定的数组中
          target = difference(selections, this.leftSelectedList)[0]
        } else {
          // 取消选择
          target = difference(this.leftSelectedList, selections)[0]
        }

        this.leftSelectedList = selections
        //知道当前target点击的值是什么,就能区分我们当前勾选的是店铺还是客户
        //shopCode可能是null undefined和""
        const isShop = !!target.shopCode //此时就能知道点击的是店铺
        let parent = null
        //如果点击了店铺 通过当前页的数据循环找到当前满足一项的数据
        //就退出循环得到的数据就是父数据(客户)
        if (isShop) {
          parent = this.customerList.find((item) => {
            return (item.shopList || []).some(
              (shop) => shop.shopCode === target.shopCode
            )
          })
          console.log('parent', parent)
        }
        //此时选中
        if (isAdd) {
          if (isShop) {
            //选中的是店铺,需要同时也选中父级的客户行
            toggleSelection(parent, true)
            this.pushToRight(target)
          } else {
            // 当前选中父亲,
            //1.存在有店铺的情况, (勾选客户会自动勾选店铺 触发下面点击店铺的操作)
            //2.存在没有店铺 只有客户的情况 (重新写一种情况就是没有店铺,即当前点击的target.shopList没有值,或者为空数组)
            toggleSelection(target, true)
            this.pushToRight(target)
          }
        }
        //取消选中
        else {
          if (isShop) {
            //如果点击的是店铺 则取消店铺操作勾选 从右边的数据移除
            this.removeRightShop(target)
          } else {
            //如果点击的是客户,还是两种情况
            //1.存在有店铺的情况, (勾选客户会自动勾选店铺 触发下面点击店铺的操作)
            //2.存在没有店铺 只有客户的情况 (重新写一种情况就是没有店铺,即当前点击的target.shopList没有值,或者为空数组)

            //2取消选中客户 没有店铺的情况
            this.removeRightShop(target)
            //1有店铺的情况,判断它此时shopList有数据,取消勾选 自动触发方法
            target.shopList &&
              target.shopList.length > 0 &&
              target.shopList.forEach((row) => toggleSelection(row, false))
          }
        }
      },

      //选中---把数据往右边List加
      pushToRight(row) {
        console.log('row', row)
        const leftParent = this.customerList.find((item) => {
          return (item.shopList || []).some(
            (shop) => shop.shopCode === row.shopCode
          )
        })
        //leftParent可能会存在undefined的情况
        //判断右边的父级(客户)数据是否已经存在右边,并找到此时右边的父级(客户)数据
        const rightParent =
          leftParent &&
          this.rightCustomerList.find(
            (item) => item.custCode === leftParent.custCode
          )
        if (rightParent) {
          // 如果右边已经存在该店铺的客户,
          // 但找不到该店铺的存在则直接push进来
          if (
            !(rightParent.shopList || []).some(
              (shop) => shop.shopCode === row.shopCode
            )
          ) {
            rightParent.shopList.push({ ...row })
          }
        } else {
          //如果右边不存在该店铺的客户
          if (leftParent) {
            const parent = { ...leftParent } //浅拷贝 方便进行数据处理和操作
            parent.shopList = [{ ...row }] //浅拷贝展开操作,生成一个新的对象,用新对象将parent.shopList数组对象替换

            this.rightCustomerList.push(parent) //通过以上的操作 这样就不会影响左边的数据
            // 刷新右边的数据
            this.tableData = this.rightCustomerList.slice(
              (this.pageTwo - 1) * this.pagesize,
              this.pageTwo * this.pagesize
            )
          } else {
            //客户没有店铺的情况,直接添加
            //一定要记得深拷贝一份,否则会出现影响左边数据的存在(如取消勾选掉子的会splice干掉)
            if (!row.shopList || row.shopList.length == 0) {
              let pushRow = JSON.parse(JSON.stringify(row))
              this.rightCustomerList.push(pushRow)
              // 刷新右侧
              this.tableData = this.rightCustomerList.slice(
                (this.pageTwo - 1) * this.pagesize,
                this.pageTwo * this.pagesize
              )
            }
          }
        }
      },
      //取消选中 --把数据从左边删除
      removeRightShop(row) {
        const leftParent = this.customerList.find((item) => {
          return (item.shopList || []).some(
            (shop) => shop.shopCode === row.shopCode
          )
        })

        const rightParent =
          leftParent &&
          this.rightCustomerList.find(
            (item) => item.custCode === leftParent.custCode
          )
        //此时知道右边的当前选中右边选中的数据,然后拿到当前选中的数据,
        //通过当前拿到rightParent数据中的shopList来判断
        //shopList长度大于0的是店铺--取消客户下的店铺
        //shopList长度为0的时候 说明所有店铺都取消,同时要取消该客户

        /*   1.此时找到相同的数据rightParent下的shopList的长度大于0,找到当前店铺的下标,然后取消勾选
        2.当rightParent的shopList的长度等于0时,说明此时的店铺数据全部取消勾选,此时要同时取消该客户的勾选 */
        if (rightParent) {
          //客户有店铺的情况
          console.log('执行了几次', rightParent)
          const shopIndex = rightParent.shopList.findIndex(
            (shop) => shop.shopCode === row.shopCode
          )
          //获取到当前删除店铺的下标 然后取消勾选
          if (shopIndex > -1) {
            rightParent.shopList.splice(shopIndex, 1)
          }
          if (rightParent.shopList.length === 0) {
            const custIndex = this.rightCustomerList.findIndex(
              (item) => item.custCode === rightParent.custCode
            )
            if (custIndex > -1) {
              this.rightCustomerList.splice(custIndex, 1)
              // 刷新右侧
              this.tableData = this.rightCustomerList.slice(
                (this.pageTwo - 1) * this.pagesize,
                this.pageTwo * this.pagesize
              )
              // 左侧取消选中父级
              this.$refs.filterCusTable.toggleRowSelection(leftParent, false)
            }
          }
        } else {
          //客户没有店铺的情况
          console.log('row', row)
          if (!row.shopList || row.shopList.length == 0) {
            const custIndex = this.rightCustomerList.findIndex(
              (item) => item.custCode === row.custCode
            )
            console.log('custIndex', custIndex)
            if (custIndex > -1) {
              this.rightCustomerList.splice(custIndex, 1)
              // 刷新右侧
              this.tableData = this.rightCustomerList.slice(
                (this.pageTwo - 1) * this.pagesize,
                this.pageTwo * this.pagesize
              )
            }
          }
        }
      },

Guess you like

Origin blog.csdn.net/weixin_42125732/article/details/132119196