搜尋
首頁web前端Vue.js聊聊Ant Design Vue中怎麼實現省市穿梭框

本篇文章带大家了解一下利用Ant Design Vue实现省市穿梭框的方法,希望对大家有所帮助!

聊聊Ant Design Vue中怎麼實現省市穿梭框

树形穿梭框

官方树穿梭框如下,左右是树结构,右边是列表。

本质上是有两套数据源,tree 使用的是树状数据源,transfer 使用的是列表数据源,将多维的树状数据源转为一维的,就是列表数据了。

具体使用可以查看官方文档之 带搜索框的穿梭框(https://antdv.com/components/transfer-cn/)

聊聊Ant Design Vue中怎麼實現省市穿梭框

城市穿梭框

改造穿梭框的原因:

  • targetKeys只需要城市数据,不需要省份数据

  • 源穿梭框中,子节点和父节点没有关联选中关系,需要处理,毕竟省市级是需要联动的

  • 目标穿梭框,也要支持树状结构

主要实现功能点:

  • 树形结构数据处理:关键词过滤;已选数据禁用状态;

  • 实现父节点和节点的关联选中

  • 穿梭框右侧仅展示城市数据,不显示省份数据

  • 选中城市数据:带省级信息返回,满足接口要求,即返回树状结构

聊聊Ant Design Vue中怎麼實現省市穿梭框

改造的本质:基于transfer的二次改造,主要是对数据的处理,组件基本没啥改变

组件参数和事件

自定义参数:考虑对外暴露的参数,参数的作用,属性等 自定义事件:考虑暴露出去的回调事件

// 自定义参数
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="[&#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>

数据源处理

  • 穿梭框数据处理(transferDataSource):多维数据转为一维数据

  • 树数据处理(treeData):数据源过滤处理,数据禁止操作处理

// 数据源示例
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 事件,回调数据(handleTransferChange)

  • search 搜索事件(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 事件,处理父节点和子节点的联动关系(handleTreeChecked)

  • expand 事件:树的展开和收缩(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;
},

清除事件

重新打开时,需要还原组件状态,例如滚动条位置,搜索框关键字等

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

【相关推荐:《vue.js教程》】

以上是聊聊Ant Design Vue中怎麼實現省市穿梭框的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:掘金社区。如有侵權,請聯絡admin@php.cn刪除
vue.js和前端堆棧:了解連接vue.js和前端堆棧:了解連接Apr 24, 2025 am 12:19 AM

Vue.js與前端技術棧緊密集成,提升開發效率和用戶體驗。 1)構建工具:與Webpack、Rollup集成,實現模塊化開發。 2)狀態管理:與Vuex集成,管理複雜應用狀態。 3)路由:與VueRouter集成,實現單頁面應用路由。 4)CSS預處理器:支持Sass、Less,提升樣式開發效率。

Netflix:探索React(或其他框架)的使用Netflix:探索React(或其他框架)的使用Apr 23, 2025 am 12:02 AM

Netflix選擇React來構建其用戶界面,因為React的組件化設計和虛擬DOM機制能夠高效處理複雜界面和頻繁更新。 1)組件化設計讓Netflix將界面分解成可管理的小組件,提高了開發效率和代碼可維護性。 2)虛擬DOM機制通過最小化DOM操作,確保了Netflix用戶界面的流暢性和高性能。

vue.js和前端:深入研究框架vue.js和前端:深入研究框架Apr 22, 2025 am 12:04 AM

Vue.js被開發者喜愛因為它易於上手且功能強大。 1)其響應式數據綁定係統自動更新視圖。 2)組件系統提高了代碼的可重用性和可維護性。 3)計算屬性和偵聽器增強了代碼的可讀性和性能。 4)使用VueDevtools和檢查控制台錯誤是常見的調試技巧。 5)性能優化包括使用key屬性、計算屬性和keep-alive組件。 6)最佳實踐包括清晰的組件命名、使用單文件組件和合理使用生命週期鉤子。

vue.js在前端的力量:關鍵特徵和好處vue.js在前端的力量:關鍵特徵和好處Apr 21, 2025 am 12:07 AM

Vue.js是一個漸進式的JavaScript框架,適用於構建高效、可維護的前端應用。其關鍵特性包括:1.響應式數據綁定,2.組件化開發,3.虛擬DOM。通過這些特性,Vue.js簡化了開發過程,提高了應用性能和可維護性,使其在現代Web開發中備受歡迎。

vue.js比反應好嗎?vue.js比反應好嗎?Apr 20, 2025 am 12:05 AM

Vue.js和React各有優劣,選擇取決於項目需求和團隊情況。 1)Vue.js適合小型項目和初學者,因其簡潔和易上手;2)React適用於大型項目和復雜UI,因其豐富的生態系統和組件化設計。

vue.js的功能:增強前端的用戶體驗vue.js的功能:增強前端的用戶體驗Apr 19, 2025 am 12:13 AM

Vue.js通過多種功能提升用戶體驗:1.響應式系統實現數據即時反饋;2.組件化開發提高代碼復用性;3.VueRouter提供平滑導航;4.動態數據綁定和過渡動畫增強交互效果;5.錯誤處理機制確保用戶反饋;6.性能優化和最佳實踐提升應用性能。

vue.js:定義其在網絡開發中的作用vue.js:定義其在網絡開發中的作用Apr 18, 2025 am 12:07 AM

Vue.js在Web開發中的角色是作為一個漸進式JavaScript框架,簡化開發過程並提高效率。 1)它通過響應式數據綁定和組件化開發,使開發者能專注於業務邏輯。 2)Vue.js的工作原理依賴於響應式系統和虛擬DOM,優化性能。 3)實際項目中,使用Vuex管理全局狀態和優化數據響應性是常見實踐。

了解vue.js:主要是前端框架了解vue.js:主要是前端框架Apr 17, 2025 am 12:20 AM

Vue.js是由尤雨溪在2014年發布的漸進式JavaScript框架,用於構建用戶界面。它的核心優勢包括:1.響應式數據綁定,數據變化自動更新視圖;2.組件化開發,UI可拆分為獨立、可複用的組件。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境