Vue3 + Ant Design Vue 可搜索 自定义字段 a-tree

记录一下,使用 Ant Design Vue a-tree 需要实现可搜索且后台返回数据不是标准数据的问题

可搜索 自定义字段

实现自定义字段需要使用 Tree props 的 replaceFields 属性
https://2x.antdv.com/components/tree-cn#API

<template>
  <div>
    <a-space>
      <a-input v-model:value="basicData.searchValue" placeholder="请输入物料类别名称" />
    </a-space>
    <a-tree :tree-data="basicData.treeData" :replaceFields="basicData.replaceFields" :expandedKeys="basicData.expandedKeys" :auto-expand-parent="basicData.autoExpandParent" @expand="onExpand" @select="onSelect">
    <!-- 查询到的字段样式变红 -->
      <template #title="{ code }">
        <span v-if="code.indexOf(basicData.searchValue) > -1">
          {{ code.substr(0, code.indexOf(basicData.searchValue)) }}
          <span style="color: #f50">{{ basicData.searchValue }}</span>
          {{ code.substr(code.indexOf(basicData.searchValue) + basicData.searchValue.length) }}
        </span>
        <span v-else>{{ code }}</span>
      </template>
    </a-tree>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { TreeDataItem } from 'ant-design-vue/es/tree/Tree'
import { GetTree } from '/@/api/wms/basicDataModule/inventoryCategoryArchives'

/* 页面基础数据 */
const basicData = reactive({
  searchValue: '',
  expandedKeys: [] as string[],
  backupsExpandedKeys: [] as string[],
  autoExpandParent: false,
  replaceFields: {
    title: 'name',
    key: 'code',
  },
  treeData: [] as TreeDataItem[],
})

/**
 * @description: 获取树形数据
 * @return {*}
 * @author: WANAN
 */
const getTreeData = () => {
  GetTree()
    .then((res) => {
      basicData.treeData = res
      console.log(res)
    })
    .catch((err) => {
      console.log(err)
    })
}
getTreeData()
/* --------------------------- 树形 a-tree --------------------------- */
/**
 * @description: 展开/收起节点时触发
 * @param {*} keys
 * @return {*}
 * @author: WANAN
 */
const onExpand = (keys: string[]) => {
  basicData.expandedKeys = keys
  basicData.autoExpandParent = false
}

/**
 * @description: 选中树形节点触发
 * @param {*} selectedKeys
 * @param {*} e
 * @return {*}
 * @author: WANAN
 */
const onSelect = (selectedKeys, _e) => {}

/**
 * @description: 获取节点中含有value的所有key集合
 * @param {*} value
 * @param {*} tree
 * @param {*} keyList
 * @return {*}
 * @author: WANAN
 */
const getkeyList = (value, tree, keyList) => {
  //遍历所有同一级的树
  for (let i = 0; i < tree.length; i++) {
    let node = tree[i]
    //如果该节点存在value值则push
    if (node.code.indexOf(value) > -1) {
      keyList.push(node.code)
    }
    //如果拥有孩子继续遍历
    if (node.children) {
      getkeyList(value, node.children, keyList)
    }
  }
  //因为是引用类型,所有每次递归操作的都是同一个数组
  return keyList
}

//该递归主要用于获取key的父亲节点的key值
const getParentKey = (key, tree) => {
  let parentKey, temp
  //遍历同级节点
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      //如果该节点的孩子中存在该key值,则该节点就是我们要找的父亲节点
      //如果不存在,继续遍历其子节点
      if (node.children.some((item) => item.code === key)) {
        parentKey = node.code
      } else if ((temp = getParentKey(key, node.children))) {
        //parentKey = this.getParentKey(key,node.children)
        //改进,避免二次遍历
        parentKey = temp
      }
    }
  }
  return parentKey
}

//获取该节点的所有祖先节点
const getAllParentKey = (key, tree) => {
  var parentKey
  if (key) {
    //获得父亲节点
    parentKey = getParentKey(key, tree)
    if (parentKey) {
      //如果父亲节点存在,判断是否已经存在于展开列表里,不存在就进行push
      if (!basicData.backupsExpandedKeys.some((item) => item === parentKey)) {
        basicData.backupsExpandedKeys.push(parentKey)
      }
      //继续向上查找祖先节点
      getAllParentKey(parentKey, tree)
    }
  }
}

watch(
  () => basicData.searchValue,
  (_newVal, _oldVal) => {
    debugger
    if (basicData.searchValue === '') {
      basicData.expandedKeys = []
    } else {
      //首先将展开项与展开项副本置为空
      basicData.expandedKeys = []
      basicData.backupsExpandedKeys = []
      //获取所有存在searchValue的节点
      let candidateKeysList = getkeyList(basicData.searchValue, basicData.treeData, [])
      //遍历满足条件的所有节点
      candidateKeysList.map((item) => {
        //获取每个节点的母亲节点
        var key = getParentKey(item, basicData.treeData)
        //当item是最高一级,父key为undefined,将不放入到数组中
        //如果母亲已存在于数组中,也不放入到数组中
        if (key && !basicData.backupsExpandedKeys.some((item) => item === key)) basicData.backupsExpandedKeys.push(key)
      })
      let length = basicData.backupsExpandedKeys.length
      for (let i = 0; i < length; i++) {
        getAllParentKey(basicData.backupsExpandedKeys[i], basicData.treeData)
      }
      basicData.expandedKeys = basicData.backupsExpandedKeys.slice()
      basicData.autoExpandParent = true
    }
  },
  {
    immediate: false,
  }
)
</script>

完整全部代码

<template>
  <div>
    <a-space>
      <a-input v-model:value="basicData.searchValue" placeholder="请输入物料类别名称" />
    </a-space>
    <a-tree :tree-data="basicData.treeData" :replaceFields="basicData.replaceFields" :expandedKeys="basicData.expandedKeys" :auto-expand-parent="basicData.autoExpandParent" @expand="onExpand" @select="onSelect">
    <!-- 查询到的字段样式变红 -->
      <template #title="{ code }">
        <span v-if="code.indexOf(basicData.searchValue) > -1">
          {{ code.substr(0, code.indexOf(basicData.searchValue)) }}
          <span style="color: #f50">{{ basicData.searchValue }}</span>
          {{ code.substr(code.indexOf(basicData.searchValue) + basicData.searchValue.length) }}
        </span>
        <span v-else>{{ code }}</span>
      </template>
    </a-tree>
  </div>
</template>
<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { TreeDataItem } from 'ant-design-vue/es/tree/Tree'
import { GetTree } from '/@/api/wms/basicDataModule/inventoryCategoryArchives'

/* 页面基础数据 */
const basicData = reactive({
  searchValue: '',
  expandedKeys: [] as string[],
  backupsExpandedKeys: [] as string[],
  autoExpandParent: false,
  replaceFields: {
    title: 'name',
    key: 'code',
  },
  treeData: [] as TreeDataItem[],
})

/**
 * @description: 获取树形数据
 * @return {*}
 * @author: WANAN
 */
const getTreeData = () => {
  GetTree()
    .then((res) => {
      basicData.treeData = res
      console.log(res)
    })
    .catch((err) => {
      console.log(err)
    })
}
getTreeData()
/* --------------------------- 树形 a-tree --------------------------- */
/**
 * @description: 展开/收起节点时触发
 * @param {*} keys
 * @return {*}
 * @author: WANAN
 */
const onExpand = (keys: string[]) => {
  basicData.expandedKeys = keys
  basicData.autoExpandParent = false
}

/**
 * @description: 选中树形节点触发
 * @param {*} selectedKeys
 * @param {*} e
 * @return {*}
 * @author: WANAN
 */
const onSelect = (selectedKeys, _e) => {}

/**
 * @description: 获取节点中含有value的所有key集合
 * @param {*} value
 * @param {*} tree
 * @param {*} keyList
 * @return {*}
 * @author: WANAN
 */
const getkeyList = (value, tree, keyList) => {
  //遍历所有同一级的树
  for (let i = 0; i < tree.length; i++) {
    let node = tree[i]
    //如果该节点存在value值则push
    if (node.code.indexOf(value) > -1) {
      keyList.push(node.code)
    }
    //如果拥有孩子继续遍历
    if (node.children) {
      getkeyList(value, node.children, keyList)
    }
  }
  //因为是引用类型,所有每次递归操作的都是同一个数组
  return keyList
}

//该递归主要用于获取key的父亲节点的key值
const getParentKey = (key, tree) => {
  let parentKey, temp
  //遍历同级节点
  for (let i = 0; i < tree.length; i++) {
    const node = tree[i]
    if (node.children) {
      //如果该节点的孩子中存在该key值,则该节点就是我们要找的父亲节点
      //如果不存在,继续遍历其子节点
      if (node.children.some((item) => item.code === key)) {
        parentKey = node.code
      } else if ((temp = getParentKey(key, node.children))) {
        //parentKey = this.getParentKey(key,node.children)
        //改进,避免二次遍历
        parentKey = temp
      }
    }
  }
  return parentKey
}

//获取该节点的所有祖先节点
const getAllParentKey = (key, tree) => {
  var parentKey
  if (key) {
    //获得父亲节点
    parentKey = getParentKey(key, tree)
    if (parentKey) {
      //如果父亲节点存在,判断是否已经存在于展开列表里,不存在就进行push
      if (!basicData.backupsExpandedKeys.some((item) => item === parentKey)) {
        basicData.backupsExpandedKeys.push(parentKey)
      }
      //继续向上查找祖先节点
      getAllParentKey(parentKey, tree)
    }
  }
}

watch(
  () => basicData.searchValue,
  (_newVal, _oldVal) => {
    debugger
    if (basicData.searchValue === '') {
      basicData.expandedKeys = []
    } else {
      //首先将展开项与展开项副本置为空
      basicData.expandedKeys = []
      basicData.backupsExpandedKeys = []
      //获取所有存在searchValue的节点
      let candidateKeysList = getkeyList(basicData.searchValue, basicData.treeData, [])
      //遍历满足条件的所有节点
      candidateKeysList.map((item) => {
        //获取每个节点的母亲节点
        var key = getParentKey(item, basicData.treeData)
        //当item是最高一级,父key为undefined,将不放入到数组中
        //如果母亲已存在于数组中,也不放入到数组中
        if (key && !basicData.backupsExpandedKeys.some((item) => item === key)) basicData.backupsExpandedKeys.push(key)
      })
      let length = basicData.backupsExpandedKeys.length
      for (let i = 0; i < length; i++) {
        getAllParentKey(basicData.backupsExpandedKeys[i], basicData.treeData)
      }
      basicData.expandedKeys = basicData.backupsExpandedKeys.slice()
      basicData.autoExpandParent = true
    }
  },
  {
    immediate: false,
  }
)
</script>
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值