<template> 
 | 
  <div> 
 | 
    <el-input v-model="text" @click.native="open()" suffix-icon="el-icon-arrow-down" slot="reference" :placeholder="placeholder"/> 
 | 
    <zt-dialog ref="dialog" :append-to-body="true" :title="title" :hasConfirm="true" @confirm="confirm"> 
 | 
      <el-row> 
 | 
        <el-col class="tree" :span="14"> 
 | 
          <el-container> 
 | 
            <el-main> 
 | 
              <el-input class="input-filter" v-model="filterText" size="small" clearableplaceholder="输入名称进行过滤"></el-input> 
 | 
              <zt-tree-selector ref="tree" v-model="treeValue" :idField="idField" :textField="textField" :parentIdField="parentIdField" 
 | 
                :datas="datas" :simple="simple" :multiple="multiple" :leaf-only="leafOnly" :lazy="lazy" :check-strictly="checkStrictly" :expandLevel="expandLevel" 
 | 
                :disabled-filter="disabledFilter" @selected="onSelected"/> 
 | 
            </el-main> 
 | 
          </el-container> 
 | 
        </el-col> 
 | 
        <el-col :span="10"> 
 | 
          <el-container> 
 | 
            <el-main> 
 | 
              <el-input class="input-selected" v-model="selectedText" size="small" readonly/> 
 | 
              <div v-for="item in selectedData" :key="item[idField]" style="margin-top: 10px"> 
 | 
                <div> 
 | 
                  <label style="width: 80%; display: inline-block"> {{item[textField]}}</label> 
 | 
                  <el-link v-if="multiple" @click="cancelSelected(item)" type="danger"> 
 | 
                    <i class="el-icon-close" title="删除"></i> 
 | 
                  </el-link> 
 | 
                </div> 
 | 
              </div> 
 | 
            </el-main> 
 | 
          </el-container> 
 | 
        </el-col> 
 | 
      </el-row> 
 | 
    </zt-dialog> 
 | 
  </div> 
 | 
  
 | 
</template> 
 | 
<script> 
 | 
  import {debounce} from 'lodash' 
 | 
  export default { 
 | 
    name: 'ZtTreeDialogSelector', 
 | 
    components: {}, 
 | 
    props: { 
 | 
      value: [String, Array], 
 | 
      title: String, 
 | 
      idField: { 
 | 
        type: String, 
 | 
        default: 'id' 
 | 
      }, 
 | 
      textField: { 
 | 
        type: String, 
 | 
        default: 'name' 
 | 
      }, 
 | 
      parentIdField: { 
 | 
        type: String, 
 | 
        default: 'pid' 
 | 
      }, 
 | 
      url: String, 
 | 
      // datas: [String, Array], 
 | 
      simple: { // 简单模式 
 | 
        type: Boolean, 
 | 
        default: false 
 | 
      }, 
 | 
      multiple: { 
 | 
        type: Boolean, 
 | 
        default: false 
 | 
      }, 
 | 
      leafOnly: { // 是否只能选择叶子节点 
 | 
        type: Boolean, 
 | 
        default: false 
 | 
      }, 
 | 
      checkStrictly: { 
 | 
        type: Boolean, 
 | 
        default: false 
 | 
      }, 
 | 
      lazy: { // 懒加载子节点 
 | 
        type: Boolean, 
 | 
        default: false 
 | 
      }, 
 | 
      expandLevel: { // 懒加载展开层级 
 | 
        type: Number, 
 | 
        default: 0 
 | 
      }, 
 | 
      disabledFilter: Function, // 可选的节点 
 | 
      disabled: { 
 | 
        type: Boolean, 
 | 
        default: false 
 | 
      }, 
 | 
      placeholder: String 
 | 
    }, 
 | 
    inject: { 
 | 
      elForm: { 
 | 
        default: '' 
 | 
      } 
 | 
    }, 
 | 
    data() { 
 | 
      return { 
 | 
        datas: [], 
 | 
        treeValue: this.value, 
 | 
        filterText: '', 
 | 
        text: null, 
 | 
        selectedData: [] 
 | 
      } 
 | 
    }, 
 | 
    computed: { 
 | 
      selectedText() { 
 | 
        return `已选择(${this.selectedData.length})` 
 | 
      } 
 | 
    }, 
 | 
    watch: { 
 | 
      value(val, oldval) { // 传递给tree-selector 
 | 
        this.treeValue = val 
 | 
        this.setTextOnetime() 
 | 
      }, 
 | 
      filterText: debounce(function (val) { 
 | 
        this.$refs.tree.filter(val) 
 | 
      }, 1000) 
 | 
    }, 
 | 
    async mounted() { 
 | 
      let res = await this.$http.get(this.url, null) 
 | 
      this.datas = res.data 
 | 
      this.setTextOnetime() 
 | 
    }, 
 | 
    methods: { 
 | 
      open() { 
 | 
        if (this.disabled || (this.elForm || {}).disabled) { 
 | 
          // 只读 
 | 
        } else { 
 | 
          this.$refs.dialog.open() 
 | 
        } 
 | 
      }, 
 | 
      onInputChange(val) { 
 | 
        this.$refs.tree.filter(val) 
 | 
      }, 
 | 
      setTextOnetime() { // 组件没有初始化时设置text 
 | 
        if (!this.treeValue) { 
 | 
          this.text = '' 
 | 
        } 
 | 
        if (!this.$refs.tree) { 
 | 
          if (this.datas) { 
 | 
            if (this.treeValue) { 
 | 
              let values = Array.isArray(this.treeValue) ? this.treeValue : this.treeValue.split(',') 
 | 
              let dataList = this.flattenTrees(this.datas) 
 | 
              let texts = [] 
 | 
              dataList.forEach(d => { 
 | 
                if (values.indexOf(d[this.idField]) >= 0) { 
 | 
                  texts.push(d[this.textField]) 
 | 
                } 
 | 
              }) 
 | 
              this.text = texts.join(',') 
 | 
            } else { 
 | 
              this.text = '' 
 | 
            } 
 | 
          } 
 | 
        } 
 | 
      }, 
 | 
      onSelected(data) { 
 | 
        if (!this.multiple) { // 单选 
 | 
          if (!data) { 
 | 
            this.text = ('') 
 | 
          } else { 
 | 
            this.selectedData = [data] 
 | 
            this.text = data[this.textField] // combox设置显示值 
 | 
          } 
 | 
        } else { // 多选 
 | 
          let texts = [] 
 | 
          let values = [] 
 | 
          data.forEach(node => { 
 | 
            texts.push(node[this.textField]) 
 | 
            values.push(node[this.idField]) 
 | 
          }) 
 | 
          this.selectedData = data 
 | 
          this.text = texts.join(',') 
 | 
        } 
 | 
      }, 
 | 
      cancelSelected(node) { 
 | 
        this.$refs.tree.cancelSelected(node, false) 
 | 
      }, 
 | 
      confirm() { 
 | 
        this.$emit('input', this.treeValue) 
 | 
        this.$emit('confirm', this.treeValue, this.selectedData) 
 | 
        this.$refs.dialog.close() 
 | 
      }, 
 | 
      flattenTrees(trees) { // tree转array 
 | 
        let result = [] 
 | 
        trees.forEach(item => { 
 | 
          result.push(item) 
 | 
          item.children && result.push(...this.flattenTrees(item.children)) 
 | 
        }) 
 | 
        return result 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
</script> 
 | 
<style lang="scss"> 
 | 
  
 | 
  .tree { 
 | 
    border-right: 1px solid #DCDFE6; 
 | 
  } 
 | 
  
 | 
  .input-filter, .input-selected { 
 | 
    margin-bottom: 15px; 
 | 
  } 
 | 
  
 | 
  .input-selected input { 
 | 
    border-top: none; 
 | 
    border-left: none; 
 | 
    border-right: none; 
 | 
    border-radius: 0px; 
 | 
  } 
 | 
  
 | 
</style> 
 |