Table of Contents
Tree shuttle box
City shuttle box
Component parameters and events
Shuttle box processing
Data source processing
Shuttle box event processing
Tree event
Clear event
Home Web Front-end Vue.js Let's talk about how to implement province and city shuttle boxes in Ant Design Vue

Let's talk about how to implement province and city shuttle boxes in Ant Design Vue

Dec 23, 2021 pm 07:15 PM
ant design vue 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!

Let's talk about how to implement province and city shuttle boxes in Ant Design Vue

Tree shuttle box

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/)

Lets talk about how to implement province and city shuttle boxes in Ant Design Vue

City shuttle box

Reasons for transforming the shuttle box:

  • targetKeysOnly 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

Lets talk about how to implement province and city shuttle boxes in Ant Design Vue

The essence of the transformation: based on The second transformation of transfer is mainly about data processing. The components are basically unchanged.

Component parameters and events

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);
Copy after login

Shuttle box processing

<template>
  <!-- 穿梭框组件,数据源为列表形式 -->
  <a-transfer
    class="mcd-transfer"
    ref="singleTreeTransfer"
    show-search
    :locale="localeConfig"
    :titles="[&#39;所有城市&#39;, &#39;已选城市&#39;]"
    :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 === &#39;left&#39;"
        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>
Copy after login

Data source processing

  • 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;
};
Copy after login

Shuttle box event processing

  • 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;
  }
},
Copy after login

Tree event

  • 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;
},
Copy after login

Clear event

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 = [];
  });
}
Copy after login

[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!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to use bootstrap in vue How to use bootstrap in vue Apr 07, 2025 pm 11:33 PM

Using Bootstrap in Vue.js is divided into five steps: Install Bootstrap. Import Bootstrap in main.js. Use the Bootstrap component directly in the template. Optional: Custom style. Optional: Use plug-ins.

How to add functions to buttons for vue How to add functions to buttons for vue Apr 08, 2025 am 08:51 AM

You can add a function to the Vue button by binding the button in the HTML template to a method. Define the method and write function logic in the Vue instance.

How to use watch in vue How to use watch in vue Apr 07, 2025 pm 11:36 PM

The watch option in Vue.js allows developers to listen for changes in specific data. When the data changes, watch triggers a callback function to perform update views or other tasks. Its configuration options include immediate, which specifies whether to execute a callback immediately, and deep, which specifies whether to recursively listen to changes to objects or arrays.

What does vue multi-page development mean? What does vue multi-page development mean? Apr 07, 2025 pm 11:57 PM

Vue multi-page development is a way to build applications using the Vue.js framework, where the application is divided into separate pages: Code Maintenance: Splitting the application into multiple pages can make the code easier to manage and maintain. Modularity: Each page can be used as a separate module for easy reuse and replacement. Simple routing: Navigation between pages can be managed through simple routing configuration. SEO Optimization: Each page has its own URL, which helps SEO.

How to reference js file with vue.js How to reference js file with vue.js Apr 07, 2025 pm 11:27 PM

There are three ways to refer to JS files in Vue.js: directly specify the path using the &lt;script&gt; tag;; dynamic import using the mounted() lifecycle hook; and importing through the Vuex state management library.

How to return to previous page by vue How to return to previous page by vue Apr 07, 2025 pm 11:30 PM

Vue.js has four methods to return to the previous page: $router.go(-1)$router.back() uses &lt;router-link to=&quot;/&quot; component window.history.back(), and the method selection depends on the scene.

How to use vue traversal How to use vue traversal Apr 07, 2025 pm 11:48 PM

There are three common methods for Vue.js to traverse arrays and objects: the v-for directive is used to traverse each element and render templates; the v-bind directive can be used with v-for to dynamically set attribute values ​​for each element; and the .map method can convert array elements into new arrays.

How to jump to the div of vue How to jump to the div of vue Apr 08, 2025 am 09:18 AM

There are two ways to jump div elements in Vue: use Vue Router and add router-link component. Add the @click event listener and call this.$router.push() method to jump.

See all articles