【下拉选择树二】弹出框和树控件如何实现弹出框树选择器

195 阅读2分钟

起因

如何实现支持搜索、选择节点的弹出框树,选择器只能选择列表形式的数据,不能选择树形结构的数据

传统select选择器只能实现下拉框选择列表数据 image.png

无法实现选择树形结构的数据

image.png

思路:

  1. 自定义输入框+Popover弹出框,popover组件的内容为Tree树控件
  2. 使用v-popover将输入框关联到Popover弹出框,这样点击输入框就会弹出popover组件的内容
  3. 自定义输入框设置contenteditable属性和input事件,使其可编辑,用于搜索弹出框的树节点
  4. 输入框需要展示选中节点的值,这时就需要css样式设置选中值区域和编辑区区域

整体布局

<div v-clickoutside="clickAll">
    <el-popover ref="treePopover">
      <el-tree :filter-node-method="filterNodeMethod"></el-tree>
    </el-popover>
    <div
      ref="input"
      v-popover:treePopover
      tabindex="0"
      style="display: flex"
     >
       <!--选中值区-->
       <template></template>
       <!--编辑区-->
       <div
         style="flex: 1; min-width: 32px"
         contenteditable
         @input="changeContent"
       />
     </div>
 </div>

v-popover是Popover弹出框与其他组件建立联系的,这里treePopover指向Popover的索引ref,使其建立联系,所以在这个输入框点击就会弹出popover组件的内容。

注意设置自定义输入框样式,以及输入框编辑区和选中值区域样式,通过display布局将编辑区和选中值区域都放置于输入框内,编辑区宽度自适应并且设置最小宽度,保障在有选中值时也能输入内容。

编辑区支持可编辑需要用到contenteditable属性,并且调用input输入事件拿到输入的值,用于筛选树节点。

v-clickoutside,用于触发鼠标失焦后,关闭弹出框

关闭弹出框

clickAll() {
  if (this.$refs.treePopover.showPopper) {
     this.$refs.treePopover.doClose()
   }
}

搜索树节点

    // 方法
    filterNodeMethod(value, data) {
      if (!value) return true
      return data.label.indexOf(value) !== -1
    },
    changeContent(e) {
      this.query = e.target.innerText
    }
    
    // 监听
    watch: {
      query(v) {
        this.$refs.tree.filter(v)
      }
    }

选择树,支持单选或多选

<el-tree @check="nodeCheck" @Current-change="currentChange"></el-tree>

// 方法
nodeCheck(data) {
  this.checkedNodes = this.$refs.tree.getCheckedNodes()
},
currentChange(data, node) {
 this.checkedNodes = [this.$refs.tree.getCurrentNode()]
},

展示选中值

 <template v-if="checkedNodes.length">
   <span class="checked first">
       {{ checkedNodes[0].label }}
    </span>
    <span
      v-if="checkedNodes.length > 1"
      class="checked"
      style="margin-left: 8px"
      >
        +{{ checkedNodes.length - 1 }}
      </span>
  </template>

checkedNodes就是选中值,可以自定义展示形式到选中值区域

总结

通过Popover弹出框树和自定义输入框实现了输入内容进行筛选树节点、选中树节点,并将选中值展示到输入框里面。