Element-UI封装El-Select-Tree组件(树形下拉选择器)

Element-UI

1、封装Select-Tree组件

在这里插入图片描述在这里插入图片描述

1.1、代码实现

el-select-tree/index.js

import SelectTree from "./select-tree.vue";

/* istanbul ignore next */
SelectTree.install = function (Vue) {
  Vue.component(SelectTree.name, SelectTree);
};

export { SelectTree };

el-select-tree/select-tree.vue

<template>
  <el-select
    :disabled="disabled"
    :size="size"
    :clearable="clearable"
    :placeholder="placeholder"
    :no-data-text="noDataText"
    :popper-class="popperClass"
    :popper-append-to-body="popperAppendToBody"
    :multiple="multiple"
    :value="value"
    @visible-change="handleVisibleChange"
    @remove-tag="handleRemoveTag"
    @clear="handleClear"
    ref="selectRef"
  >
    <el-option
      v-if="data.length !== 0"
      value=""
      style="display: none"
    ></el-option>

    <template v-if="value">
      <el-option
        :value="item[nodeKey]"
        :label="item[props?.label ?? 'label']"
        style="display: none"
        :key="item[nodeKey]"
        v-for="item in optionData"
      ></el-option>
    </template>

    <el-tree
      :node-key="nodeKey"
      :props="props"
      :data="data"
      :highlight-current="highlightCurrent"
      :default-expand-all="defaultExpandAll"
      :expand-on-click-node="expandOnClickNode"
      :check-on-click-node="checkOnClickNode"
      :auto-expand-parent="autoExpandParent"
      :show-checkbox="showCheckbox"
      :check-strictly="checkStrictly"
      @check="handleCkeck"
      @current-change="handleCurrentChange"
      ref="treeRef"
    ></el-tree>
  </el-select>
</template>

<script>
export default {
  name: "ElSelectTree",
  componentName: "ElSelectTree",
  model: {
    prop: "value",
    event: "update:value",
  },
  emits: ["update:value", "visible-change", "change"],

  props: {
    value: {
      type: String | Number | Array,
    },
    data: {
      type: Array,
      required: true,
      default: () => [],
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    size: {
      type: "medium" | "small" | "mini",
    },
    clearable: {
      type: Boolean,
      default: false,
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    noDataText: {
      type: String,
      default: "无数据",
    },
    popperClass: {
      type: String,
    },
    popperAppendToBody: {
      type: Boolean,
      default: true,
    },
    // tree
    nodeKey: {
      type: String,
      required: true,
    },
    props: {
      type: Object,
      default: () => {},
    },
    highlightCurrent: {
      type: Boolean,
      default: false,
    },
    defaultExpandAll: {
      type: Boolean,
      default: false,
    },
    expandOnClickNode: {
      type: Boolean,
      default: false,
    },
    checkOnClickNode: {
      type: Boolean,
      default: false,
    },
    autoExpandParent: {
      type: Boolean,
      default: false,
    },
    checkStrictly: {
      type: Boolean,
      default: false,
    },
  },

  computed: {
    showCheckbox() {
      return this.multiple;
    },
  },

  watch: {
    value(val) {
      if (!this.multiple) {
        this.setCurrentNode(val);
      } else {
        this.setMultipleCurrentNode(val);
      }

      if (!val) {
        return;
      }

      this.optionData = this.flatteningTreeData.filter((item) => {
        return val.includes(item[this.nodeKey]);
      });
    },

    data(val) {
      this.flatteningTree(val);
    },
  },

  data() {
    return {
      flatteningTreeData: [],
      optionData: [],
    };
  },

  methods: {
    /**
     * 扁平化树形结构
     * @param {Array} data
     */
    flatteningTree(data) {
      data.forEach((item) => {
        const children = this.props?.children ?? "children";

        if (item[children] && item[children].length) {
          this.flatteningTree(item[children]);
        } else {
          delete item[children];
        }
        this.flatteningTreeData.push(item);
      });
    },

    handleCkeck(data, { checkedKeys, halfCheckedKeys }) {
      if (this.multiple) {
        const val = [...checkedKeys, ...halfCheckedKeys];
        this.$emit("update:value", val);
        this.$emit("change", val);
      }
    },
    handleCurrentChange(data) {
      if (!this.multiple) {
        this.$emit("update:value", data[this.nodeKey]);
        this.$emit("change", data[this.nodeKey]);
        this.$refs.selectRef.blur();
      }
    },

    /**
     * 单选节点选中
     * @param {String} val key
     */
    setCurrentNode(val) {
      this.$nextTick(() => {
        this.$refs.treeRef.setChecked(val);
      });
    },

    /**
     * 多选节点选中
     * @param {Array} data
     */
    setMultipleCurrentNode(data) {
      this.$nextTick(() => {
        this.$refs.treeRef.setCheckedKeys(data, this.checkStrictly);
      });
    },

    handleVisibleChange(visible) {
      if (visible) {
        this.multiple
          ? this.setMultipleCurrentNode(this.value)
          : this.setCurrentNode(this.value);
      }
      this.$emit("visible-change", visible);
    },

    handleRemoveTag(val) {
      val = this.value.filter((item) => item !== val);
      this.$emit("update:value", val);
    },

    handleClear() {
      this.$emit("update:value", undefined);
    },
  },
};
</script>

1.2、食用文档

  • 在 main.js 引入 el-select-tree/index.js
  • 使用 Vue.use(SelectTree) 挂载组件
import { SelectTree } from '@/components/el-select-tree'
Vue.use(SelectTree)
  • 28
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单的封装示例: 1. 在 `components` 目录下新建一个 `select` 目录,然后在 `select` 目录下新建两个文件 `select.wxml` 和 `select.js`。 2. 在 `select.wxml` 文件中编写下拉选择器的模板代码,示例如下: ``` <view class="el-select" bindtap="onSelectTap"> <view class="el-select__input"> <input type="text" class="el-select__inner" placeholder="{{placeholder}}" disabled="{{disabled}}" value="{{selectedText}}"> <i class="el-select__caret el-icon-arrow-down"></i> </view> <view class="el-select-dropdown" hidden="{{!showDropdown}}" catchtouchmove="catchTouchMove"> <scroll-view scroll-y="{{true}}" class="el-select-dropdown__list"> <view class="el-select-dropdown__item" wx:for="{{options}}" wx:key="{{item.value}}" bindtap="onOptionTap" data-value="{{item.value}}"> {{item.label}} </view> </scroll-view> </view> </view> ``` 其中,`placeholder` 表示选择器的占位符,`disabled` 表示选择器是否禁用,`selectedText` 表示当前选中的文本,`showDropdown` 表示下拉框是否显示,`options` 表示下拉框的选项列表。 3. 在 `select.js` 文件中编写组件的逻辑代码,示例如下: ``` Component({ properties: { options: { type: Array, value: [] }, placeholder: { type: String, value: '' }, disabled: { type: Boolean, value: false }, value: { type: [String, Number], value: '', observer: 'onValueChange' } }, data: { selectedValue: '', selectedText: '', showDropdown: false }, methods: { onValueChange: function(newVal) { var options = this.data.options; var selectedItem = options.find(function(item) { return item.value == newVal; }); if (selectedItem) { this.setData({ selectedValue: selectedItem.value, selectedText: selectedItem.label }); } }, onSelectTap: function() { if (this.data.disabled) { return; } this.setData({ showDropdown: !this.data.showDropdown }); }, onOptionTap: function(event) { var value = event.currentTarget.dataset.value; this.setData({ selectedValue: value, selectedText: this.data.options.find(function(item) { return item.value == value; }).label, showDropdown: false }); this.triggerEvent('change', { value: value }); }, catchTouchMove: function() { // 阻止滚动穿透 } } }); ``` 其中,`options` 表示下拉框的选项列表,`placeholder` 表示选择器的占位符,`disabled` 表示选择器是否禁用,`value` 表示当前选中的值,`selectedValue` 表示当前选中的值,`selectedText` 表示当前选中的文本,`showDropdown` 表示下拉框是否显示。 4. 在需要使用下拉选择器的页面中,引入 `select` 组件并传入相关参数,示例如下: ``` <import src="../../components/select/select.wxml" /> <template is="select" data="{{ options: options, placeholder: '请选择', value: value }}" /> ``` 其中,`options` 表示下拉框的选项列表,`placeholder` 表示选择器的占位符,`value` 表示当前选中的值。 5. 在需要监听选择器值改变的页面中,使用 `bind:change` 绑定事件即可,示例如下: ``` <import src="../../components/select/select.wxml" /> <view class="page"> <template is="select" data="{{ options: options, placeholder: '请选择', value: value }}" bind:change="onSelectChange" /> </view> ``` 其中,`onSelectChange` 表示选择器值改变时触发的事件处理函数。 这只是一个简单的示例,如果需要更多功能可以根据实际需求进行扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值