antd的穿梭框的数据貌似只接收key和title,而且必须是字符串(我测试不是字符串的不行),
所以要把后端返回的数据再处理一下得到我们想要的数据
除了实现简单的穿梭框功能,还想要重写搜索事件,想达到的效果是搜索到的结果的节点能自动展开且高亮显示
给穿梭框添加show-search
完整代码:
<template><!-- 选择图层穿梭框 --><a-modal title="选择数据图层" width="900px" :visible="true" :maskClosable="false" wrapClassName="transferModal"centered @ok="getSelectedNodes" destroyOnClose><a-transferclass="tree-transfer":titles="['所有数据图层', '已选数据图层']":operations="['添加', '移除']":data-source="dataSource":target-keys="targetKeys":render="item => item.title":show-select-all="false"@change="onChange"show-search@search="handleSearch"><templateslot="children"slot-scope="{ props: { direction, selectedKeys }, on: { itemSelect } }"><a-treev-if="direction === 'left'"blockNodecheckablecheckStrictlydefaultExpandAll:checkedKeys="[...selectedKeys, ...targetKeys]":treeData="newTreeData":expandedKeys="expandedKeys" :auto-expand-parent="autoExpandParent"@expand="onExpand"@check="(_, props) => {onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect);}"@select="(_, props) => {onChecked(_, props, [...selectedKeys, ...targetKeys], itemSelect);}"><template slot="title" slot-scope="{ name }"><span v-if="name.indexOf(searchValue) > -1">{{ name.substr(0, name.indexOf(searchValue)) }}<span style="color: #f50">{{ searchValue }}</span>{{ name.substr(name.indexOf(searchValue) + searchValue.length) }}</span><span v-else>{{ name }}</span></template></a-tree></template></a-transfer></a-modal>
</template><script>
import { auth_service_tree_zyfx } from "@/API/api/g_api"function isChecked(selectedKeys, eventKey) {return selectedKeys.indexOf(eventKey) !== -1;
}function handleTreeData(data, targetKeys = []) {//数据选中移到右侧就设置为禁选data.forEach(item => {item['disabled'] = targetKeys.includes(item.key);if (item.children) {handleTreeData(item.children, targetKeys);}});return data;
}
const getParentKey = (key, tree) => {let parentKey;for (let i = 0; i < tree.length; i++) {const node = tree[i];if (node.children) {if (node.children.some((item) => item.id === key)) {parentKey = String(node.id);} else if (getParentKey(key, node.children)) {parentKey = getParentKey(key, node.children);}}}return parentKey;
};
const dataList = [];
const generateList = (data) => {for (let i = 0; i < data.length; i++) {const node = data[i];const key = node.id;const name = node.name;dataList.push({ key, title: name });if (node.children) {generateList(node.children);}}
};
export default {data() {return {treeData: [],targetKeys: [],dataSource: [],checkedNodes: [],dataList: [],expandedKeys: [],searchValue: "",autoExpandParent: true,}},computed: {newTreeData() {return handleTreeData(this.treeData, this.targetKeys);},},mounted(){this.init();},methods:{async init(){let data = await auth_service_tree_zyfx()this.treeData = data.code==1?data.data:[];this.renderTreeNodes(this.treeData)//console.log(this.treeData);//generateList(this.treeData);this.flatten(JSON.parse(JSON.stringify(this.treeData)));},renderTreeNodes(list) {list.forEach(item => {item.key = String(item.id);item.title = item.name;this.dataList.push({ key: item.id, title: item.name });if(item.children){this.renderTreeNodes(item.children);}});},flatten(list = []) {list.forEach(item => {this.dataSource.push(item);this.flatten(item.children);});},onChange(targetKeys) { //两栏之间转移时的回调函数// console.log('Target Keys:', targetKeys);this.targetKeys = targetKeys;},onChecked(_, e, checkedKeys, itemSelect) {//选中项发生改变时的回调函数// console.log(_, e.checkedNodes, checkedKeys, itemSelect);this.checkedNodes = e.checkedNodes;const { eventKey } = e.node;itemSelect(eventKey, !isChecked(checkedKeys, eventKey));},onExpand(expandedKeys) {this.expandedKeys = expandedKeys;this.autoExpandParent = false;},handleSearch(dir, value) {// console.log('search:', dir, value);if(dir=="left"){const expandedKeys = this.dataList.map((item) => {if (item.title.toString().indexOf(value) > -1) {return getParentKey(item.key, this.treeData);}return null;}).filter((item, i, self) => item && self.indexOf(item) === i);// console.log(expandedKeys);Object.assign(this, {expandedKeys,searchValue: value,autoExpandParent: true,});}},getSelectedNodes(){let nodes = [];this.checkedNodes.map(r=>{if(this.targetKeys.includes(r.key)){nodes.push(r.data.props.dataRef)}});console.log(nodes);}}
};
</script><style lang="scss" scoped>
::v-deep .transferModal{.ant-modal-body{max-height: 70vh;// overflow-y: auto;.tree-transfer{height: 100%;}.ant-transfer-list-body{max-height: 300px;overflow: auto;}}
}
</style>
实现效果如下: