VueTreeselect el-tree-select 多选

1、VueTreeselect 是一个多选组件

npm install --save @riophae/vue-treeselect

 全部代码

<!-- Vue SFC -->
<template>
  <div id="app">
    <treeselect v-model="value" :multiple="true" :options="options" />
  </div>
</template>

<script>
  // import the component
  import Treeselect from '@riophae/vue-treeselect'
  // import the styles
  import '@riophae/vue-treeselect/dist/vue-treeselect.css'

  export default {
    // register the component
    components: { Treeselect },
    data() {
      return {
        // define the default value
        value: null,
        // define options
        options: [ {
          id: 'a',
          label: 'a',
          children: [ {
            id: 'aa',
            label: 'aa',
          }, {
            id: 'ab',
            label: 'ab',
          } ],
        }, {
          id: 'b',
          label: 'b',
        }, {
          id: 'c',
          label: 'c',
        } ],
      }

    },
  }
</script>

2、el-tree-select

npm install el-tree-select --save-dev
import ElTreeSelect from 'el-tree-select';
vue.use(ElTreeSelect);
内部直接使用 :  <el-tree-select v-model="id"/>
<template>
    <div id="app">
        <el-tree-select :styles="styles" v-model="values" :selectParams="selectParams" :treeParams="treeParams" :treeRenderFun="_renderFun" @searchFun="_searchFun" @node-click="_nodeClickFun" ref="treeSelect"/>
        <el-select multiple v-model="test" placeholder="请选择" @change="_selectChange">
            <el-option v-for="item in treeParams.data" :key="item.testId" :label="item.name" :value="item.testId"></el-option>
        </el-select>
    </div>
</template>
<style>
#app {
    display: flex;
    justify-content: space-between;
    width: 600px;
}
</style>
<script>
export default {
    name: 'App',
    data() {
        return {
            styles: {
                width: '300px'
            },
            test: '',
            values: ['11111'],
            selectParams: {
                multiple: true,
                clearable: true,
                placeholder: '请输入内容'
            },
            treeParams: {
                clickParent: false,
                filterable: true,
                'check-strictly': true,
                'default-expand-all': true,
                'expand-on-click-node': false,
                data: [],
                props: {
                    children: 'child',
                    label: 'name',
                    disabled: 'disabled',
                    value: 'testId'
                }
            }
        };
    },
    mounted() {
        let data = [
            {
                testId: '1',
                name: '节点1',
                disabled: true,
                child: [
                    {
                        testId: '11111',
                        name: '子节点'
                    }
                ]
            },
            {
                testId: '2',
                name: '节点2',
                child: [
                    {
                        testId: '222222',
                        disabled: true,
                        name: '子节点'
                    }
                ]
            },
            {
                testId: '3',
                name: '节点3'
            },
            {
                testId: '4',
                name: '节点4'
            },
            {
                testId: '5',
                name: '节点5'
            },
            {
                testId: '6',
                name: '节点6'
            }
        ];
        this.treeParams.data = data;
        this.$refs.treeSelect.treeDataUpdateFun(data);
    },
    methods: {
        // 下拉框修改
        _selectChange(val) {
            console.log(val, '<-select change');
        },
        // 树点击
        _nodeClickFun(data, node, vm) {
            console.log('this _nodeClickFun', this.values, data, node);
        },
        // 树过滤
        _searchFun(value) {
            console.log(value, '<--_searchFun');
            // 自行判断 是走后台查询,还是前端过滤
            // this.$refs.treeSelect.$refs.tree.filter(value);
            this.$refs.treeSelect.filterFun(value);
            // 后台查询
            // this.$refs.treeSelect.treeDataUpdateFun(treeData);
        },
        // 自定义render
        _renderFun(h, { node, data, store }) {
            return (
                <span class='custom-tree-node'>
                    <span>{node.label}</span>
                </span>
            );
        }
    },
    components: { }
};
</script>

 

 

Vue 2 中直接使用 Element Plus 的 `el-tree-select` 组件是不可能的,因为 Element Plus 是专门为 Vue 3 设计的组件库。然而,可以通过自定义的方式,在 Vue 2 和 Element UI 的基础上模拟实现类似的树形下拉择器功能。 以下是基于 Vue 2 和 Element UI 实现的一个简单版本的 `treeSelect` 组件: ### 自定义 Tree Select 组件 #### HTML 结构 通过组合 `el-select` 和 `el-tree` 来构建一个可交互的树形择器。 ```html <template> <div class="tree-select"> <el-popover placement="bottom" width="auto" trigger="click" v-model="visible" > <el-tree ref="tree" :data="options" :props="defaultProps" node-key="id" highlight-current :show-checkbox="multiple" :default-checked-keys="checkedKeys" @check-change="handleCheckChange" @node-click="handleNodeClick" ></el-tree> <el-input slot="reference" v-model="selectedLabel" readonly placeholder="请..." suffix-icon="el-icon-arrow-down" /> </el-popover> </div> </template> ``` #### JavaScript 部分 逻辑部分主要处理节点的择状态以及回显到输入框的功能。 ```javascript <script> export default { name: "TreeSelect", props: { value: Array, // 双向绑定值 options: { type: Array, required: true }, // 树结构数据源 multiple: Boolean, // 是否支持 }, data() { return { visible: false, selectedLabel: "", // 当前展示的文字 checkedKeys: [], // 已勾的 key 列表 defaultProps: { children: "children", // 子节点属性名 label: "label", // 节点标签属性名 }, }; }, watch: { value(newVal) { this.checkedKeys = newVal; this.updateSelectedLabel(); }, }, methods: { handleCheckChange(node, isChecked) { const keys = this.$refs.tree.getCheckedKeys(); this.$emit("input", keys); // 更新父级组件的数据 this.updateSelectedLabel(); // 同步更新显示文字 }, handleNodeClick(data) { if (!this.multiple) { this.selectedLabel = data.label; // 单模式下直接设置当前项 this.$emit("input", [data.id]); // 发送单个 id this.visible = false; // 关闭弹窗 } }, updateSelectedLabel() { let labels = []; if (this.options && this.value.length > 0) { function findLabels(tree, ids) { tree.forEach((item) => { if (ids.includes(item.id)) { labels.push(item.label); } item.children && findLabels(item.children, ids); }); } findLabels(this.options, this.value); } this.selectedLabel = labels.join(", "); }, }, }; </script> ``` #### CSS 样式 简单的样式调整可以让组件看起来更美观。 ```css <style scoped> .tree-select .el-input { cursor: pointer; } </style> ``` --- ### 使用方法 将该组件注册并引入项目后,可以像下面这样调用它: ```html <template> <div> <tree-select v-model="selectedValues" :options="treeData" multiple ></tree-select> </div> </template> <script> import TreeSelect from "./components/TreeSelect.vue"; export default { components: { TreeSelect }, data() { return { selectedValues: [], treeData: [ { id: 1, label: "一级菜单 1", children: [ { id: 4, label: "二级菜单 1-1" }, { id: 5, label: "二级菜单 1-2" }, ], }, { id: 2, label: "一级菜单 2", children: [{ id: 6, label: "二级菜单 2-1" }], }, ], }; }, }; </script> ``` --- ### 注意事项 1. 如果需要修改默认字段名称(如 `id`, `label`, `children`),可以在 `defaultProps` 属性中重新指定[^1]。 2. 模式下的行为由 `el-tree` 的 `@check-change` 方法控制;而单则依赖于 `@node-click`[^2]。 3. 对于复杂场景(如异步加载子节点),需额外扩展 `lazy` 加载机制[^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小并不小

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值