欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Element--简单的二次封装tree组件

程序员文章站 2022-06-08 09:31:24
...
<template>
  <div class="about">
    <myTree :data.sync="data" :fileDrop="fileDrop" :diectoryDrop="diectoryDrop" :del="del"></myTree>
  </div>
</template>
<script>
import myTree from '../components/myTree.vue'
export default {
  components: {
    myTree
  },
  data () {
    return {
      data: [],
      fileDrop: [{ text: 'rm', value: '删除文件' }],
      diectoryDrop: [
        { text: 'rn', value: '修改名字' },
        { text: 'rm', value: '删除文件夹' }
      ]
    }
  },
  mounted () {
    this.ff()
  },
  methods: {
    del (id) {
      // 此方法必须返回一个Promise
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve()
        }, 3000)
      })
    },
    ff () {
      const data = {
        code: 0,
        parent: [
          { name: '文件夹1', pid: 0, id: 1 },
          { name: '文件夹2', pid: 0, id: 2 },
          { name: '文件夹3', pid: 0, id: 3 },
          { name: '文件夹1-1', pid: 1, id: 4 },
          { name: '文件夹2-', pid: 2, id: 5 }
        ],
        child: [
          { name: '文件1', pid: 1, id: 10001 },
          { name: '文件2', pid: 1, id: 10002 },
          { name: '文件2-1', pid: 2, id: 10003 },
          { name: '文件2-2', pid: 2, id: 10004 },
          { name: '文件1-1-1', pid: 4, id: 10005 },
          { name: '文件2-1-1', pid: 5, id: 10006 }
        ]
      }
      data.parent.forEach((item) => (item.type = 'parent'))
      // 格式化数据 扁平的数据如何变多层数据 递归数据
      const allData = [...data.parent, ...data.child]

      this.data = allData
    }
  }
}
</script>

<template>
  <el-tree :data="list" default-expand-all :expand-on-click-node="false" :render-content="render"></el-tree>

</template>
<script>
import _ from 'lodash'
export default {
  name: 'tree',
  props: {
    data: {
      type: Array,
      default: () => []
    },
    fileDrop: {
      type: Array,
      default: () => []
    },
    diectoryDrop: {
      type: Array,
      default: () => []
    },
    del: Function
  },
  data () {
    return {
      list: [],
      currentId: '', // 点击编辑的时候的id
      currentContent: '' // 当前编辑的内容
    }
  },
  beforeCreate () {
    console.log('子初始化')
  },
  watch: {
    data () {
      this.transfromData()
    }
  },
  methods: {
    transfromData () {
      // 对数据进行克隆
      const allData = _.cloneDeep(this.data)

      // 格式化数据 扁平的数据如何变多层数据 递归数据

      // 映射数据 例如:{1:{name:'xxx',id:1}}  id为当前id pid为父亲id
      // memo:计算后的返回值 初始值为reduce函数的参数二
      // current:当前函数
      const treeMap = allData.reduce((memo, current) => {
        current.label = current.name
        memo[current.id] = current
        return memo
      }, {})

      console.log(treeMap)

      const res = allData.reduce((arr, current) => {
        // 拿到当前项的父id去映射变表treeMap中找 没有找到自己就是父亲
        const pid = current.pid
        const parent = treeMap[pid]
        if (parent) {
          parent.children
            ? parent.children.push(current)
            : (parent.children = [current])
        } else if (pid === 0) {
          arr.push(current)
        }

        return arr
      }, [])

      this.list = res
    },
    isParent (data) {
      return data.type === 'parent'
    },
    handleRename (data) {
      // 重命名
      this.currentId = data.id
      this.currentContent = data.name
    },
    remove (id) {
      const list = _.cloneDeep(this.data)
      console.log(id)
      const arr = list.filter((item) => {
        return item.id !== id
      })

      // .sync 用法
      this.$emit('update:data', arr)

      this.$message({
        type: 'success',
        message: '删除成功!'
      })
    },
    handleRemove (data) {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 判断
          // 用户传递了删除方法就调用没有就直接删除

          this.del
            ? this.del(data.id).then(() => {
              this.remove(data.id)
            })
            : this.remove(data.id)
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    handleCommand (data, value) {
      console.log(data, value)
      if (value === 'rn') {
        this.handleRename(data)
      } else if (value === 'rm') {
        this.handleRemove(data)
      }
    },
    handinput (v) {
      this.currentContent = v
    },
    render (h, { node, data, store }) {
      // data:当前节点数据

      const list = this.isParent(data) ? this.diectoryDrop : this.fileDrop

      return (
        <div>
          {this.isParent(data) ? (
            node.expanded ? (
              <i class="el-icon-folder-opened"></i>
            ) : (
              <i class="el-icon-folder"></i>
            )
          ) : (
            <i class="el-icon-document"></i>
          )}

          {data.id === this.currentId ? (
            <el-input
              value={this.currentContent}
              on-input={this.handinput}
            ></el-input>
          ) : (
            data.name
          )}

          {data.id !== this.currentId ? (
            <el-dropdown
              placement="bottom-start"
              trigger="click"
              on-command={this.handleCommand.bind(this, data)}
            >
              <span class="el-dropdown-link">
                <i class="el-icon-arrow-down el-icon--right"></i>
              </span>
              <el-dropdown-menu slot="dropdown">
                {list.map((item) => (
                  <el-dropdown-item command={item.text}>
                    {item.value}
                  </el-dropdown-item>
                ))}
              </el-dropdown-menu>
            </el-dropdown>
          ) : (
            <span>
              <button type="text" on-click={this.ok.bind(this, data)}>
                确认
              </button>
              <button type="text" on-click={this.cannel}>
                取消
              </button>
            </span>
          )}
        </div>
      )
    },
    ok (data) {
      console.log(data)

      const list = _.cloneDeep(this.data)
      const item = list.find((l) => {
        return l.id === data.id
      })

      console.log(item)

      item.name = this.currentContent

      // .sync 用法
      this.$emit('update:data', list)

      this.currentId = ''

      this.$message({
        type: 'success',
        message: '修改成功!'
      })
    },
    cannel () {
      this.currentId = ''
    }
  }
}
</script>
<style lang="less" scoped>
</style>

相关标签: UI组件库