antd vue TreeSelect树选择的使用

官方文档:https://www.antdv.com/components/tree-select-cn/

基本使用

<template>
    <a-tree-select
            v-model="value"
            show-search
            style="width: 100%"
            :dropdown-style="{maxHeight:'400px', overflow:'auto'}"
            placeholder="Please select"
            allow-clear
            tree-default-expand-all
    >
        <a-tree-select-node key="0-1" value="parent 1" title="parent 1">
            <a-tree-select-node key="0-1-1" value="parent 1-0" title="parent 1-0">
                <a-tree-select-node key="random" :selectable="false" value="leaf1" title="my leaf" />
                <a-tree-select-node key="random1" value="leaf2" title="your leaf" />
            </a-tree-select-node>
            <a-tree-select-node key="random2" value="parent 1-1" title="parent 1-1">
                <a-tree-select-node key="random3" value="sss">
                    <b slot="title" style="color: #08c">sss</b>
                </a-tree-select-node>
            </a-tree-select-node>
        </a-tree-select-node>
    </a-tree-select>
</template>

<script>
export default {
data() {
return {
treeExpandedKeys: [],
value: undefined,
};
},
};
</script>

效果

image-20201208114619942

从已有的后端数据生成树选择框

参考:https://www.antdv.com/components/tree-select-cn/#components-tree-select-demo-generate-form-tree-data

假设后端数据已经有了但是不符合树选择框的要求,所以我们要进行一次转化

树选择组件

<a-tree-select
    v-model="form.pid"
    style="width: 100%"
    :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
    :treeData="treeData"
    placeholder="请选择父节点"
    allow-clear
    tree-default-expand-all
>

</a-tree-select>

data 属性

//tree select 树选择
treeData: [
    {
        title : '一级菜单',
        value : 0,
        key : 0
    }
],

method 方法

/**
 * 树选择框, 构造转换,转换后端数据为树形选择需要的数据
 * @param data  后端数据
 * @returns {[]}  返回结构
 */
convertToTreedata(data){
    //console.log(data, '数据构造........')
    var returnData = [];
    // 遍历数据
    for(var i = 0; i < data.length; i++){
        var tempObj = {
            title : data[i].title,
            value : data[i].id,
            key : data[i].id
        };
    <span class="hljs-comment">//判断是否存在子节点,如果存在则递归</span>
    <span class="hljs-keyword">if</span>(<span class="hljs-string">'child_node'</span> <span class="hljs-keyword">in</span> <span class="hljs-keyword">data</span>[i]){
        tempObj.children = <span class="hljs-keyword">this</span>.convertToTreedata(<span class="hljs-keyword">data</span>[i].child_node);
    }
    <span class="hljs-comment">//push到数据数组中</span>
    returnData.push(tempObj);
}
<span class="hljs-keyword">return</span> returnData;

},

// 在获取到后端数据之后调用
// 转换
var res = this.convertToTreedata(data.data.data);

// 脱掉一层再进行 push
this.treeData.push(...res);

效果

image-20201208143547178

单选输入搜索启用

参考:https://www.antdv.com/components/tree-select-cn/#API

image-20201208145250831

image-20201208145320636

组件设置

<!--
    v-model 双向绑定的值
    dropdown-style 下拉样式
    treeData   菜单数据
//重点属性
showSearch 是否开启搜索框(仅单选)
treeNodeFilterProp  输入搜索的属性

-->
<a-tree-select
v-model="form.pid"
style="width: 100%"
:dropdown-style="{maxHeight:'400px', overflow:'auto'}"
:treeData="treeData"
:showSearch="true"
treeNodeFilterProp='title'
placeholder="请选择父节点"
allow-clear
tree-default-expand-all
>

</a-tree-select>

可勾选 (使用勾选框实现多选功能)

参考:https://www.antdv.com/components/tree-select-cn/#components-tree-select-demo-checkable

实现代码

组件设置

<!-- 授权对话框 -->
<a-modal
        :visible="authorize_visible"
        title= "角色授权"
        :confirm-loading="authorize_confirmLoading"
        okText='确认'
        cancel-text="取消"
        @cancel="hideAuthorizeModel"
        @ok="submitAuthorize"
>
    <!-- 授权树选择 -->
    <a-tree-select
            v-model="authorize_value"
            style="width: 100%"
            :tree-data="treeData"
            tree-checkable
            :show-checked-strategy="SHOW_PARENT"
            search-placeholder="Please select"
    />
</a-modal>

script 导入

// 导入
import { TreeSelect } from 'ant-design-vue';
const SHOW_PARENT = TreeSelect.SHOW_PARENT;

data 导出

// 勾选框
SHOW_PARENT,
//tree select 树选择
treeData: [],
// 授权选择
authorize_value : [],

methods 主要方法

/**
 * 树选择框, 构造转换,转换后端数据为树形选择需要的数据
 * @param data  后端数据
 * @returns {[]}  返回结构
 */
convertToTreedata(data){
    //console.log(data, '数据构造........')
    var returnData = [];
    // 遍历数据
    for(var i = 0; i < data.length; i++){
        var tempObj = {
            title : data[i].title,
            value : data[i].id,
            key : data[i].id
        };
    <span class="hljs-comment">//判断是否存在子节点,如果存在则递归</span>
    <span class="hljs-keyword">if</span>(<span class="hljs-string">'child_node'</span> <span class="hljs-keyword">in</span> <span class="hljs-keyword">data</span>[i]){
        tempObj.children = <span class="hljs-keyword">this</span>.convertToTreedata(<span class="hljs-keyword">data</span>[i].child_node);
    }
    <span class="hljs-comment">//push到数据数组中</span>
    returnData.push(tempObj);
}
<span class="hljs-keyword">return</span> returnData;

},
// 获取授权菜单
getAuthorizeMenu(){
this.loading = true;
this.axios.get(process.env.VUE_APP_API_URL + this.urls.getMenus).then((data) => {
// 修改 loading 状态
this.loading = false;

    <span class="hljs-comment">//数据</span>
    <span class="hljs-keyword">this</span>.<span class="hljs-keyword">data</span> = <span class="hljs-keyword">data</span>.<span class="hljs-keyword">data</span>.<span class="hljs-keyword">data</span>;

    <span class="hljs-comment">//树选择,下拉框重新构造</span>
    <span class="hljs-comment">//转换树菜单选择</span>
    <span class="hljs-keyword">var</span> res = <span class="hljs-keyword">this</span>.convertToTreedata(<span class="hljs-keyword">data</span>.<span class="hljs-keyword">data</span>.<span class="hljs-keyword">data</span>);
    <span class="hljs-comment">//脱掉一层再进行push</span>
    <span class="hljs-keyword">this</span>.treeData.push(...res);
    <span class="hljs-comment">// console.log(this.treeData)</span>
});

},

mounted 中调用

// 获取授权菜单
this.getAuthorizeMenu();

效果

image-20201222151423299

多选输入搜索启用

参考:

https://www.antdv.com/components/tree-select-cn/#API

image-20201222151739788

组件设置

<!-- 授权树选择 -->
<a-tree-select
        v-model="authorize_value"
        style="width: 100%"
        :tree-data="treeData"
        tree-checkable
        // 设置搜索事件
        :filterTreeNode="searchFilterTreeNode"
        :show-checked-strategy="SHOW_PARENT"
        search-placeholder="Please select"
/>

method 实现

// 多选搜索过滤
searchFilterTreeNode(inputValue, treeNode){
    /*console.log(inputValue);
    console.log(treeNode);
    // 组件数据
    console.log(treeNode.componentOptions.propsData.title);
    // 原数据
    console.log(treeNode.data.props.title);*/
    return (
        treeNode.componentOptions.propsData.title.toLowerCase().indexOf(inputValue.toLowerCase()) >= 0
    );
},

效果

image-20201222153711163

关于勾选获取值的问题

使用树选择之后,选中父节点子节点会一起选中,但是双向绑定的值只有你选中的父节点值,

image-20201224101312962

那下面两种情况的勾选值怎么获取呢?

  • 获取勾选父节点和下面勾选的子节点的值
  • 获取已勾选子节点以及半勾选状态的父节点的值

先看 api

https://www.antdv.com/components/tree-select-cn/#API

image-20201224101436376

看这几个事件应该是 change 事件了,打印一下

选中父节点 (相当于全选)

image-20201224102543699

半勾选

image-20201224102740484

看到这里,估计就知道怎么获取了

change 事件的第三个参数是组件属性,属性里面有个allCheckedNodes属性,这个是个数组,每个数组项都有nodechildren(如果有子项才有),通过这两个属性就可以获取我们想要的值。

但是这只能获取

  • 获取勾选父节点和下面勾选的子节点的值

这种情况的那第二种情况怎么获取呢?第二种情况需要使用 select 事件,同样是第三个属性有个halfCheckedKeys的数组,这里就保存半勾选的父节点

image-20201224140648616

但是这样又出现一个问题 select 事件只会在选中时触发,那如果选中了再取消,这时候父节点数据就会有问题,那如何更新父节点数据呢?

表示没找到方法

我真是黑人问号了......

要不就只能用下面的 show_ALL,要不就换 Tree 树形控件

https://antdv.com/components/tree-cn/

showCheckedStrategy 属性解决勾选的问题

先看下官方解释

定义选中项回填的方式。TreeSelect.SHOW_ALL: 显示所有选中节点 (包括父节点). TreeSelect.SHOW_PARENT: 只显示父节点 (当父节点下所有子节点都选中时). 默认只显示子节点.

image-20201224110941870

啥意思,给你看下效果就知道了

设置为 SHOW_ALL

showCheckedStrategy="SHOW_ALL"

效果

image-20201224111221165

设置为 SHOW_PARENT

showCheckedStrategy="SHOW_PARENT"

image-20201224111719192

设置为 SHOW_CHILD

image-20201224111841828

这三种只有 SHOW_ALL 是将所有的值获取到,效果没那么好看