element 树状下拉框

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了element 树状下拉框相关的知识,希望对你有一定的参考价值。

参考技术A <!--

    /**

    * 树形下拉选择组件,下拉框展示树形结构,提供选择某节点功能,方便其他模块调用

    * @author sxy https://bysjb.cn

    * @date 2020-12-02

    */

-->

<template>

  <div>

    <div v-show="isShowSelect" class="mask" @click="isShowSelect = !isShowSelect" />

    <el-popover

      v-model="isShowSelect"

      placement="bottom-start"

      :width="width"

      trigger="manual"

      style="padding: 12px 0;"

      @hide="popoverHide"

    >

      <el-tree

        ref="tree"

        class="common-tree"

        :style="style"

        :data="data"

        :props="defaultProps"

        :show-checkbox="multiple"

        :node-key="nodeKey"

        :check-strictly="checkStrictly"

        default-expand-all

        :expand-on-click-node="false"

        :check-on-click-node="multiple"

        :highlight-current="true"

        @node-click="handleNodeClick"

        @check-change="handleCheckChange"

      />

      <el-select

        slot="reference"

        ref="select"

        v-model="selectedData"

        :style="selectStyle"

        :size="size"

        :multiple="multiple"

        :clearable="clearable"

        :collapse-tags="collapseTags"

        class="tree-select"

        @click.native="isShowSelect = !isShowSelect"

        @remove-tag="removeSelectedNodes"

        @clear="removeSelectedNode"

        @change="changeSelectedNodes"

      >

        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />

      </el-select>

    </el-popover>

  </div>

</template>

<script>

export default

  props:

    // 树结构数据

    data:

      type: Array,

      default()

        return []

     

    ,

    defaultProps:

      type: Object,

      default()

        return

          children: 'children',

          label: 'name'

       

     

    ,

    // 配置是否可多选

    multiple:

      type: Boolean,

      default()

        return false

     

    ,

    // 配置是否可清空选择

    clearable:

      type: Boolean,

      default()

        return false

     

    ,

    // 配置多选时是否将选中值按文字的形式展示

    collapseTags:

      type: Boolean,

      default()

        return false

     

    ,

    nodeKey:

      type: String,

      default()

        return 'id'

     

    ,

    // 显示复选框情况下,是否严格遵循父子不互相关联

    checkStrictly:

      type: Boolean,

      default()

        return false

     

    ,

    // 默认选中的节点key数组

    checkedKeys:

      type: Array,

      default()

        return []

     

    ,

    size:

      type: String,

      default()

        return 'medium'

     

    ,

    width:

      type: Number,

      default()

        return 250

     

    ,

    height:

      type: Number,

      default()

        return 300

     

   

  ,

  data()

    return

      isShowSelect: false, // 是否显示树状选择器

      options: [],

      selectedData: [], // 选中的节点

      style: 'width:' + (this.width - 24) + 'px;' + 'height:' + this.height + 'px;',

      selectStyle: 'width:' + (this.width + 24) + 'px;',

      checkedIds: [],

      checkedData: []

   

  ,

  watch:

    isShowSelect(val)

      // 隐藏select自带的下拉框

      this.$refs.select.blur()

    ,

    checkedKeys(val)

      console.log('checkedKeys', val)

      if (!val) return

      this.checkedKeys = val

      this.initCheckedData()

   

  ,

  mounted()

    this.initCheckedData()

  ,

  methods:

    // 单选时点击tree节点,设置select选项

    setSelectOption(node)

      const tmpMap =

      tmpMap.value = node.key

      tmpMap.label = node.label

      this.options = []

      this.options.push(tmpMap)

      this.selectedData = node.key

    ,

    // 单选,选中传进来的节点

    checkSelectedNode(checkedKeys)

      var item = checkedKeys[0]

      this.$refs.tree.setCurrentKey(item)

      var node = this.$refs.tree.getNode(item)

      this.setSelectOption(node)

    ,

    // 多选,勾选上传进来的节点

    checkSelectedNodes(checkedKeys)

      // this.$refs.tree.setCheckedKeys(checkedKeys)

      // 优化select回显显示 有个延迟的效果

      const that = this

      setTimeout(function()

        that.$refs.tree.setCheckedKeys(checkedKeys)

      , 10)

      // console.log('checkSelectedNodes', checkedKeys, this.selectedData)

    ,

    // 单选,清空选中

    clearSelectedNode()

      this.selectedData = []

      this.$refs.tree.setCurrentKey(null)

    ,

    // 多选,清空所有勾选

    clearSelectedNodes()

      var checkedKeys = this.$refs.tree.getCheckedKeys() // 所有被选中的节点的 key 所组成的数组数据

      for (let i = 0; i < checkedKeys.length; i++)

        this.$refs.tree.setChecked(checkedKeys[i], false)

     

    ,

    initCheckedData()

      if (this.multiple)

        // 多选

        // console.log(this.checkedKeys.length)

        if (this.checkedKeys.length > 0)

          this.checkSelectedNodes(this.checkedKeys)

        else

          this.clearSelectedNodes()

       

      else

        // 单选

        if (this.checkedKeys.length > 0)

          this.checkSelectedNode(this.checkedKeys)

        else

          this.clearSelectedNode()

       

     

    ,

    popoverHide()

      if (this.multiple)

        this.checkedIds = this.$refs.tree.getCheckedKeys() // 所有被选中的节点的 key 所组成的数组数据

        this.checkedData = this.$refs.tree.getCheckedNodes() // 所有被选中的节点所组成的数组数据

      else

        this.checkedIds = this.$refs.tree.getCurrentKey()

        this.checkedData = this.$refs.tree.getCurrentNode()

     

      this.$emit('popoverHide', this.checkedIds, this.checkedData)

    ,

    // 单选,节点被点击时的回调,返回被点击的节点数据

    handleNodeClick(data, node)

      if (!this.multiple)

        this.setSelectOption(node)

        this.isShowSelect = !this.isShowSelect

        this.$emit('change', this.selectedData)

     

    ,

    // 多选,节点勾选状态发生变化时的回调

    handleCheckChange()

      var checkedKeys = this.$refs.tree.getCheckedKeys() // 所有被选中的节点的 key 所组成的数组数据

      // console.log('handleCheckChange', checkedKeys)

      this.options = checkedKeys.map((item) =>

        var node = this.$refs.tree.getNode(item) // 所有被选中的节点对应的node

        const tmpMap =

        tmpMap.value = node.key

        tmpMap.label = node.label

        return tmpMap

      )

      this.selectedData = this.options.map((item) =>

        return item.value

      )

      this.$emit('change', this.selectedData)

    ,

    // 多选,删除任一select选项的回调

    removeSelectedNodes(val)

      this.$refs.tree.setChecked(val, false)

      var node = this.$refs.tree.getNode(val)

      if (!this.checkStrictly && node.childNodes.length > 0)

        this.treeToList(node).map(item =>

          if (item.childNodes.length <= 0)

            this.$refs.tree.setChecked(item, false)

         

        )

        this.handleCheckChange()

     

      this.$emit('change', this.selectedData)

    ,

    treeToList(tree)

      var queen = []

      var out = []

      queen = queen.concat(tree)

      while (queen.length)

        var first = queen.shift()

        if (first.childNodes)

          queen = queen.concat(first.childNodes)

       

        out.push(first)

     

      return out

    ,

    // 单选,清空select输入框的回调

    removeSelectedNode()

      this.clearSelectedNode()

      this.$emit('change', this.selectedData)

    ,

    // 选中的select选项改变的回调

    changeSelectedNodes(selectedData)

      // 多选,清空select输入框时,清除树勾选

      if (this.multiple && selectedData.length <= 0)

        this.clearSelectedNodes()

     

      this.$emit('change', this.selectedData)

   

 



</script>

<style scoped>

  .mask

    width: 100%;

    height: 100%;

    position: fixed;

    top: 0;

    left: 0;

    opacity: 0;

    z-index: 11;

 

  .common-tree

    overflow: auto;

 

  .tree-select

    z-index: 111;

 

</style>

以上是关于element 树状下拉框的主要内容,如果未能解决你的问题,请参考以下文章

在element-ui的select下拉框加上滚动加载

Vue:解决 element-ui 下拉框过多导致卡顿问题

element-ui select下拉框滚动加载更多

实现多列下拉框组件的另一种思路(element-ui 多列下拉框)

element 下拉框支持搜索并输入

element中el-select下拉框整体样式修改 ,下拉菜单样式修改