Home > Article > Web Front-end > Let's talk about how to implement province and city shuttle boxes in Ant Design Vue
This article will take you through how to use Ant Design Vue to implement provincial and city shuttle boxes. I hope it will be helpful to you!
The official tree shuttle box is as follows, with the tree structure on the left and the list on the right.
Essentially, there are two sets of data sources. tree
uses a tree data source, and transfer
uses a list data source to convert multi-dimensional tree data The source is converted to one-dimensional, which is list data.
For specific usage, you can view the official documentation of the shuttle box with search box (https://antdv.com/components/transfer-cn/)
Reasons for transforming the shuttle box:
targetKeys
Only city data is required, not province data
In the source shuttle box, the child node and the parent node have no associated selection relationship and need to be processed. After all, the provincial and municipal levels need to be linked.
The target shuttle box must also be supported. Tree structure
Main implementation function points:
Tree structure data processing: keyword filtering; selected data disabled state;
Realize the association between parent node and node selection
On the right side of the shuttle box, only city data is displayed, and province data is not displayed
Selected city data: returned with provincial information, meeting the interface requirements, that is, returning a tree structure
The essence of the transformation: based on The second transformation of transfer
is mainly about data processing. The components are basically unchanged.
Custom parameters: consider the parameters exposed to the outside world. The role of parameters, attributes, etc. Custom events: Consider exposed callback events
// 自定义参数 export default { props: { dataSource: { // 数据源 type: Array, default: () => [], }, targetKey: { // 右侧框数据的 key 集合 type: Array, default: () => [], }, }, }; // handleChange回调函数:treeData-左侧树结构数据,toArray-右侧树结构数据,targetKeys-选中城市key集合 this.$emit("handleChange", this.treeData, toArray, this.targetKeys);
<template> <!-- 穿梭框组件,数据源为列表形式 --> <a-transfer class="mcd-transfer" ref="singleTreeTransfer" show-search :locale="localeConfig" :titles="['所有城市', '已选城市']" :data-source="transferDataSource" :target-keys="targetKeys" :render="(item) => item.label" :show-select-all="true" @change="handleTransferChange" @search="handleTransferSearch" > <template slot="children" slot-scope="{ props: { direction, selectedKeys }, on: { itemSelect, itemSelectAll }, }" > <!-- 左边源数据框:树形控件 --> <a-tree v-if="direction === 'left'" class="mcd-tree" blockNode checkable :checked-keys="[...selectedKeys, ...targetKeys]" :expanded-keys="expandedKeys" :tree-data="treeData" @expand="handleTreeExpanded" @check=" (_, props) => { handleTreeChecked( _, props, [...selectedKeys, ...targetKeys], itemSelect, itemSelectAll ); } " @select=" (_, props) => { handleTreeChecked( _, props, [...selectedKeys, ...targetKeys], itemSelect, itemSelectAll ); } " /> </template> </a-transfer> </template>
Shuttle box Data processing (transferDataSource): Convert multi-dimensional data to one-dimensional data
Tree data processing (treeData): Data source filtering processing, data prohibition operation processing
// 数据源示例 const dataSource = [ { pid: "0", key: "1000", label: "黑龙江省", title: "黑龙江省", children: [ { pid: "1000", key: "1028", label: "大兴安岭地区", title: "大兴安岭地区", }, ], }, ]; // ant-transfer穿梭框数据源 transferDataSource() { // 穿梭框数据源 let transferDataSource = []; // 穿梭框数据转换,多维转为一维 function flatten(list = []) { list.forEach((item) => { transferDataSource.push(item); // 子数据处理 if (item.children && item.children.length) { flatten(item.children); } }); } if (this.dataSource && this.dataSource.length) { flatten(JSON.parse(JSON.stringify(this.dataSource))); } return transferDataSource; } // ant-tree树数据源 treeData() { // 树形控件数据源 const validate = (node, map) => { // 数据过滤处理 includes return node.title.includes(this.keyword); }; const result = filterTree( this.dataSource, this.targetKeys, validate, this.keyword ); return result; } // 树形结构数据过滤 const filterTree = (tree = [], targetKeys = [], validate = () => {}) => { if (!tree.length) { return []; } const result = []; for (let item of tree) { if (item.children && item.children.length) { let node = { ...item, children: [], disabled: targetKeys.includes(item.key), // 禁用属性 }; // 子级处理 for (let o of item.children) { if (!validate.apply(null, [o, targetKeys])) continue; node.children.push({ ...o, disabled: targetKeys.includes(o.key) }); } if (node.children.length) { result.push(node); } } } return result; };
change event, callback data (handleTransferChange)
search search event ( handleTransferSearch)
// 穿梭框:change事件 handleTransferChange(targetKeys, direction, moveKeys) { // 过滤:避免头部操作栏“全选”将省级key选中至右边 this.targetKeys = targetKeys.filter((o) => !this.pidKeys.includes(o)); // 选中城市数据:带省级信息返回,满足接口要求 const validate = (node, map) => { return map.includes(node.key) && node.title.includes(this.keyword); }; let toArray = filterTree(this.dataSource, this.targetKeys, validate); // handleChange回调函数:treeData-左侧树结构数据,toArray-右侧树结构数据,targetKeys-选中城市key集合 this.$emit("handleChange", this.treeData, toArray, this.targetKeys); }, // 穿梭框:搜索事件 handleTransferSearch(dir, value) { if (dir === "left") { this.keyword = value; } },
change event, handles the linkage relationship between parent node and child node (handleTreeChecked)
expand event: tree expansion and contraction (handleTreeExpanded)
// 树形控件:change事件 handleTreeChecked(keys, e, checkedKeys, itemSelect, itemSelectAll) { const { eventKey, checked, dataRef: { children }, } = e.node; if (this.pidKeys && this.pidKeys.includes(eventKey)) { // 父节点选中:将所有子节点也选中 let childKeys = children ? children.map((item) => item.key) : []; if (childKeys.length) itemSelectAll(childKeys, !checked); } itemSelect(eventKey, !isChecked(checkedKeys, eventKey)); // 子节点选中 }, // 树形控件:expand事件 handleTreeExpanded(expandedKeys) { this.expandedKeys = expandedKeys; },
Re When opening, you need to restore the component state, such as the scroll bar position, search box keywords, etc.
handleReset() { this.keyword = ""; this.$nextTick(() => { // 搜索框关键字清除 const ele = this.$refs.singleTreeTransfer.$el.getElementsByClassName( "anticon-close-circle" ); if (ele && ele.length) { ele[0] && ele[0].click(); ele[1] && ele[1].click(); } // 滚动条回到顶部 if (this.$el.querySelector(".mcd-tree")) { this.$el.querySelector(".mcd-tree").scrollTop = 0; } // 展开数据还原 this.expandedKeys = []; }); }
[Related recommendations: "vue.js Tutorial"]
The above is the detailed content of Let's talk about how to implement province and city shuttle boxes in Ant Design Vue. For more information, please follow other related articles on the PHP Chinese website!