<template>
  <div>
    <el-tree
        :check-strictly="checkStrictly"
        :show-checkbox="showCheckbox"
        empty-text="暂无数据"
        :highlight-current = "highlightCurrent"
        :default-expand-all = "defaultExpandAll"
        :expand-on-click-node="expandOnClickNode"
        :data="treeList"
        :node-key="nodeKey"
        :filter-node-method="filterNode"
        @node-click="handleNodeClick"
        @check="handleCheck"
        :props="defaultProps"
        :current-node-key="currentNodeKey"
        :render-content="renderContent"
        ref="tree">
      <slot name="slotTree">
      </slot>
    </el-tree>
  </div>
</template>

<script>
export default {
  name: "index.vue",
  props: {
    //tree数据
    treeList: {
      type: Array
    },
    //自定义节点内容相关配置
    defaultProps: {
      type: Object,
      default() {
        return {
          children: "children",
          label: "label"
        };
      }
    },
    //唯一标识的属性
    nodeKey: {
      type: String,
      default() {
        return "id";
      }
    },
    //选中节点
    currentNodeKey:{
      type:String
    },
    //是否默认展开所有节点
    defaultExpandAll:{
      type: Boolean,
      default() {
        return false
      }
    },
    //树节点的内容区的渲染
    renderContent :{
      type:Object,
    },
    //节点是否高亮
    highlightCurrent:{
      type: Boolean,
      default() {
        return true
      }
    },
    //是否显示复选框
    showCheckbox:{
      type: Boolean,
      default() {
        return false
      }
    },
    //是否在点击节点的时候展开或者收缩节点(设置为false后，点击箭头才能展开收缩)
    expandOnClickNode:{
      type: Boolean,
      default() {
        return true
      }
    },
    //在显示复选框的情况下，是否严格的遵循父子不互相关联的做法
    checkStrictly: {
      type: Boolean,
      default() {
        return false
      }
    },
  },
  data() {
    return {
      filterText:""
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    }
  },
  methods:{
    //监听筛选
    filterTree(data) {
      this.filterText = data
    },
    //点击树节点
    handleNodeClick(data,node) {
      this.$emit("handleNodeClick", data,node);
    },
    //通过 node 获取节点
    getCheckedNodes() {
      this.$emit("getCheckedNodes", this.$refs.tree.getCheckedNodes())
    },
    //通过 key 获取节点
    getCheckedKeys() {
      this.$emit("getCheckedKeys", this.$refs.tree.getCheckedKeys())
    },
    //通过 node 设置节点 入参类型array
    setCheckedNodes(arr) {
      this.$refs.tree.setCheckedNodes(arr);
    },
    //通过 key 设置节点 入参类型array
    setCheckedKeys(arr) {
      this.$refs.tree.setCheckedKeys(arr);
    },
    //清空
    resetChecked() {
      this.$refs.tree.setCheckedKeys([]);
    },
    //点击复选框
    handleCheck(checkedKeys,checkedNodes,halfCheckedKeys,halfCheckedNodes){
      let params= {
        checkedKeys,
        checkedNodes,
        halfCheckedKeys,
        halfCheckedNodes
      }
      this.$emit("handleCheck", params);
    },
    // 触发页面显示配置的筛选
    filterNode(value, data, node) {
      // 如果什么都没填就直接返回
      if (!value) return true;
      // 如果传入的value和data中的label相同说明是匹配到了
      if (data[this.defaultProps.label].indexOf(value) !== -1) {
        return true;
      }
      // 否则要去判断它是不是选中节点的子节点
      return this.checkBelongToChooseNode(value, data, node);
    },
    // 判断传入的节点是不是选中节点的子节点
    checkBelongToChooseNode(value, data, node) {
      const level = node.level;
      // 如果传入的节点本身就是一级节点就不用校验了
      if (level === 1) {
        return false;
      }
      // 先取当前节点的父节点
      let parentData = node.parent;
      // 遍历当前节点的父节点
      let index = 0;
      while (index < level - 1) {
        // 如果匹配到直接返回
        if (parentData.data[this.defaultProps.label].indexOf(value) !== -1) {
          return true;
        }
        // 否则的话再往上一层做匹配
        parentData = parentData.parent;
        index ++;
      }
      // 没匹配到返回false
      return false;
    },
  }
}
</script>

<style scoped>

</style>
