自定义穿梭框实现详解 table 穿梭框

业精于勤 荒于嬉

需求描述

element 的 穿梭框el-transfer 使用起来样式很受限制,一般我们需要根据自己的需求实现数据的灵活选择,左右穿梭,就需要用到自定义的穿梭框了

思路分析

封装自定义的穿梭框,要考虑的是自己的需求样式,以及数据展示格式

A:什么样式?

Q:穿梭框样式,一般分为左右两侧,此处不多说,根据自己的 UI 画页面就可以了

A:展示的数据格式?

Q : 主要是根据自己的页面展示,分析自己需要的是什么样的数据,

A : 其他逻辑功能分析?

Q: 你需求的穿梭框需要什么样的功能,是否有搜索,是单选还是双选等?一步一步,实现功能,细化逻辑。

A:穿梭框的主要功能是数据可以左右穿梭怎么实现?

B:数据展示分为左右两侧,与此同时有一个包含左右两侧的总数据,左侧数据=总数据.filter(右侧数据)

table 穿梭框实现案例

实现后的效果(忽略粗糙的样式)

自定义穿梭框实现详解 table 穿梭框_第1张图片

 

基本功能

搜索功能自动过滤

其实上面效果的实现还是依赖了element ui ,因为项目中本来用了element-ui 并设定了统一的格式,所以就是用了element 

搜索功能好实现,就是根据搜索内容过滤数据 改变 table 的 data 就可以了,在element 的 el-transfer 中,过滤值的基础是label ,而我们自己写可以根据自己的条件进行过滤搜索

思路是:1、总的data 过滤到右侧数据  2、搜索内容+自己需要的过滤逻辑实现搜索过滤

  const filterData = []
  const leftData = this.tableData.filter(item => !this.currentSelection.some(citem => citem.no == item.no))
  leftData.map(item => {
        if (item.no == this.inputContent || item.name.includes(this.inputContent)) {
          // 根据自己的搜索条件来判断
          filterData.push(item)
        }
      })

 

table多选,并控制最多选择数量

table 使用的是elemtn ui ,所以同样有很多现成的东西可以用

1、设置可以多选 并可以通过点击行进行选中

      el-table 满足上述功能,只需要添加对应的属性和事件就可以 row-click 操作行点击选中的操作

           
               
               
            

2、根据选择数量控制checkbox 状态

      checkbox 的可选状态需要用 :selectable=‘setSelectable’ 设置 两个table设置代码如下。

    
 setSelectable(row, index) {
      if (this.leftSelected.length + this.currentSelection.length >= this.maxSelect) {
        return this.leftSelected.findIndex(item => item.no == row.no) != -1
      }
      return true
    },


handleRowClick(row) {
      const allSelectLength = this.leftSelected.length + this.currentSelection.length
      if (allSelectLength == this.maxSelect && this.leftSelected.findIndex(item => item.no === row.no) == -1) {
        return false
      }
      this.$refs.tableRef.toggleRowSelection(row)
    },

 

中间选择按钮动态切换可选择状态

思路:中间按钮是否可点击的状态左侧是否选中数据来决定 ,在触发table选中触发selection 时 进行实时判断

 handleSelectionChange(selection) {

      this.leftSelected = selection
      
      this.disabled = !(this.leftSelected.length > 0)
    },

 

在table 重新渲染时,已经选择的数据状态保持

在table 的数据更新时,table控件会重新渲染,重新渲染后会导致 selection 清空

什么时候数据会变化呢?1、搜索内容发生变化  2、右侧的数据删除左侧会增加

主要修改 handleSelectionChange 方法中 this.leftSelected = selection 需要根据条件设置,比如如果是重新渲染触发的事件,不能直接赋值使用,要恢复选中的状态

选中状态切换关键:this.$refs.tableRef.toggleRowSelection(item, true)

    handleSelectionChange(selection) {
      if (this.needSaveCheck) {
        this.saveSelect()
      } else {
        this.leftSelected = selection
      }
      this.disabled = !(this.leftSelected.length > 0)
    },

    saveSelect() {
      this.$nextTick(() => {
        this.currentTableData.map(item => {
          if (this.leftSelected.findIndex(lef => item.no == lef.no) !== -1) {
            this.$refs.tableRef.toggleRowSelection(item, true)
          }
        })
        this.needSaveCheck = false // 写在nextTick 方法里面很重要
      })
    }

问题总结

在保存选中状态时候,一定要在$nextTick 方法中,且this.needSaveCheck = false 一定在nextTick 中 ,不然会被handleSelectionChange 触发的selection 覆盖 ,另外在$nextTick之前设置选中的属性,页面渲染完成以后,会没有蓝色状态,只是没有selectable 不一样 。

整体代码




积跬步 至千里

自定义穿梭框实现详解 table 穿梭框_第2张图片

 

你可能感兴趣的:(问题收集,web,前端,vue,vue.js)