tree-transfer穿梭树的组件封装

1.需求界面

tree-transfer穿梭树的组件封装_第1张图片

2.使用

1).安装

npm install el-tree-transfer --save

2).组件封装

新建公共组件:addressTreeTransfer.vue

/*
 * @Author: duyan
 * @Date: 2020-07-31 14:37:51
 * @Last Modified by: duyan
 * @Last Modified time: 2020-08-04 11:17:16
 */
<template>
  <div class="addressTreeTransfer">
    <h4>
      <!-- <label>请打开f12查看移动数据</label> -->
      <!-- <el-button size="medium" type="info" @click="changeMode">当前模式:{{ mode }}</el-button> -->
      <el-button size="medium" @click="clearChecked()">清除选中</el-button>
    </h4>
    <div class="box">
      <!-- lazy -->
      <!-- :lazyFn="lazyFn" -->
      <tree-transfer
        ref="wl-tree-transfer"
        :mode="mode"
        :title="title"
        :to_data="treeToData"
        :from_data="treeFromData"
        :filter-node="filterNode"
        :default-props="treeDefaultProps"
        :button_text="['添加', '移除']"
        :default-checked-keys="defaultCheckedKeys"
        :default-expanded-keys="[]"
        :pid="pid"
        filter
        high-light
        default-transfer
        height="300px"
        node_key="id"
        open-all
        @right-check-change="rightCheckChange"
        @left-check-change="leftCheckChange"
        @removeBtn="remove"
        @addBtn="add"
      >
        <span slot="title-right" class="my-title-right" @click="handleTitleRight"/>
      </tree-transfer>
    </div>
  </div>
</template>

<script>
import treeTransfer from 'el-tree-transfer'

export default {
  // 名字
  name: 'AddressTreeTransfer',
  // 部件
  components: {
    treeTransfer
  },
  // 静态
  props: {
    treeToData: {// 穿梭框 - 目标数据 - 树形
      type: Array,
      default: () => []
    },
    treeFromData: {// 穿梭框 - 源数据 - 树形
      type: Array,
      default: () => []
    },
    treeDefaultProps: {
      type: Object,
      default: () => {}
    },
    pid: {
      type: String,
      default: ''
    }
  },
  // 数据
  data() {
    return {
      mode: 'transfer', // transfer addressList
      fromArray: [],
      toArray: [],
      defaultCheckedKeys: [] // 左侧默认选中数据,
    }
  },
  // 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;
  computed: {
    title() {
      if (this.mode === 'transfer') {
        return ['未选地点', '已有地点']
      } else {
        return ['通讯录', '收件人', '抄送人', '密送人']
      }
    }
  },
  // 对象内部的属性监听,也叫深度监听
  watch: {
  },
  // 请求数据
  created() {
    // this.defaultCheckedKeys = [1];
    this.$nextTick(() => {
      // this.defaultCheckedKeys = [1];
    })
  },
  mounted() {
    setTimeout(() => {
      this.defaultCheckedKeys = [1]
    }, 1000)
  },
  // 方法表示一个具体的操作,主要书写业务逻辑;
  methods: {
    // 清除选中
    clearChecked() {
      this.$refs['wl-tree-transfer'].clearChecked()
    },
    // 自定义筛选函数
    filterNode(value, data, where) {
      if (!value) return true
      return data[this.treeDefaultProps.label].indexOf(value) !== -1
    },
    // 懒加载回调
    lazyFn(node, resolve) {
      setTimeout(() => {
        resolve([])
      }, 500)
    },
    // 切换模式 现有树形穿梭框模式transfer 和通讯录模式addressList
    changeMode() {
      if (this.mode === 'transfer') {
        this.mode = 'addressList'
      } else {
        this.mode = 'transfer'
      }
    },
    // 添加按钮
    add(fromData, toData, obj) {
      // 树形穿梭框模式transfer时,返回参数为左侧树移动后数据、右侧树移动后数据、移动的{keys,nodes,halfKeys,halfNodes}对象
      // 通讯录模式addressList时,返回参数为右侧收件人列表、右侧抄送人列表、右侧密送人列表
      console.log('fromData:', fromData)
      console.log('toData:', toData)
      console.log('obj:', obj)
      this.$emit('selectedToData', toData)
    },
    // 移除按钮
    remove(fromData, toData, obj) {
      // 树形穿梭框模式transfer时,返回参数为左侧树移动后数据、右侧树移动后数据、移动的{keys,nodes,halfKeys,halfNodes}对象
      // 通讯录模式addressList时,返回参数为右侧收件人列表、右侧抄送人列表、右侧密送人列表
      console.log('fromData:', fromData)
      console.log('toData:', toData)
      console.log('obj:', obj)
      this.$emit('selectedToData', toData)
    },
    // 左侧源数据选中事件
    leftCheckChange(nodeObj, treeObj, checkAll) {
      console.log(nodeObj)
      console.log(treeObj)
      console.log(checkAll)
    },
    // 右侧目标数据选中事件
    rightCheckChange(nodeObj, treeObj, checkAll) {
      console.log(nodeObj)
      console.log(treeObj)
      console.log(checkAll)
    },
    // 自定义节点 仅树形结构支持
    renderContent(h, { node, data, store }) {
      return (
        <span class='custom-tree-node'>
          <span>{node.label}</span>
          <span>
            <el-button
              size='mini'
              type='text'
              on-click={() => this.append(data)}
            >
              Append
            </el-button>
            <el-button
              size='mini'
              type='text'
              on-click={() => this.remove(node, data)}
            >
              Delete
            </el-button>
          </span>
        </span>
      )
    },
    // 标题自定义区点击事件
    handleTitleRight() {
      alert('标题自定义区点击事件')
    }
  }
}
</script>

 <style scoped>
  .box {
    width: 80%;
    margin: 0 auto;
    text-align: left;
  }
  .btn {
    border: 1px solid #ebeef5;
    padding: 5px 10px;
    background-color: #f5f7fa;
    outline: none;
  }
  .my-title-right {
    float: right;
    font-size: 12px;
    cursor: pointer;
  }
  </style>

3).组件使用

import addressTreeTranfer from '@/views/oms/propertyOrder/workAddress/addressTreeTransfer'

// 部件
  components: {
    addressTreeTranfer
  },
 <addressTreeTranfer  :pid="'parkId'" :tree-default-props="treeDefaultProps" :tree-to-data="treeToData" :tree-from-data="treeFromData" @selectedToData="selectedToData" />

data:(请求数据根据自己的需求进行组合,样式如下,注意父子之间的关系)

treeToData: [
	{
		children:[
				{
				disabled: false,
				gateName: "视频",
				id: "1-1-2",
				parkId:"1-2",
				}
			]
		disabled: false,
		gateName: "芳华社区",
		id: "1-2",
		parkId: 0,
	}
],
treeFromData: [
	{
		children:[
			{
			disabled: false
			gateName: "杜艳1通道"
			id: "1-1-1"
			parkId: "1-1"
			}
		]
		disabled: false
		gateName: "杜艳的停车场"
		id: "1-1"
		parkId: 0
	}
],
treeDefaultProps: { label: 'gateName', children: 'children' }

methods:

// 选择穿梭框
    selectedToData(data) {
     console.log(data)
    }

注意: 本组件使用的主要难点就是要根据自己的需求来重新赋值父子组件(treeDefaultProps),还有就是数据的组合,我拿到的数据都是散的,需要一个个组合起来,这个比较麻烦

参考链接:源码及文档说明

你可能感兴趣的:(vue,js)