antd-vue 树形搜索框自动展开并变色

1 篇文章 0 订阅
1 篇文章 0 订阅

<template>

  <page-header-wrapper>

    <a-row type="flex" justify="space-around">

      <a-col :xl="7" :lg="24" style="border: 1px solid rgba(0, 0, 0, 0.5); box-shadow: 0px 0.5px 10px #888888">

        <a-input-search

          v-model="searchStr"

          placeholder="请搜索公司名称"

          style="width: 100%"

          @search="onSearch"

        ></a-input-search>

        <!-- selectedKeys是选中项key的集合,expandedKeys是展开项key的集合 -->

        <a-tree

          v-model="checkedKeys"

          :treeData="treeData"

          :selectedKeys="selectedKeys"

          :expandedKeys="expandedKeys"

          @expand="onExpand"

          :autoExpandParent="autoExpandParent"

          :replaceFields="replaceFields"

          @select="onSelect"

          style="height: 70vh; overflow-y: auto"

        >

          <template slot="title1" slot-scope="{ name }" style="display: flex; justify-content: space-between">

            <span

              v-html="name.replace(new RegExp(searchValue, 'g'), '<span style=color:#f50>' + searchValue + '</span>')"

            ></span>

            <a-button type="link" style="float: right" size="small" @click="showModal()">公司详情</a-button>

          </template>



          <template

            slot="title"

            slot-scope="{ name }"

            style="display: flex; justify-content: space-between; width: 100%"

          >

            <span

              v-html="name.replace(new RegExp(searchValue, 'g'), '<span style=color:#f50>' + searchValue + '</span>')"

            ></span>

          </template>

        </a-tree>

        <!-- 公司详情模态框 -->

        <a-modal v-model="visible" :title="computedname">

          <!-- 自定义页脚按钮 -->

          <template slot="footer">

            <a-button key="submit" type="primary" @click="handleOk">返回</a-button>

          </template>

          <p>姓名: {{ fname == null ? '纯爱战神爱看动漫' : fname }}</p>

          <p>手机号: {{ fphone == null ? '155xxxxxxxx' : fphone }}</p>

          <p>社会统一代码: {{ code == null ? '12345656632412342345' : code }}</p>

          <p>企业公章号码: {{ seal == null ? '1234234134134134' : seal }}</p>

          <p>账号:{{ lvdao_name == null ? '123456' : lvdao_name }}</p>

          <p>密码:{{ lvdao_pwd == null ? '123456' : lvdao_pwd }}</p>

          <div style="text-align: center">

            <p>执照副本</p>

            <div><img style="width: 240px" :src="business" alt="" /></div>

            <!-- <div><img style="width: 240px" :src="business==''?'@/assets/logo.png':business" alt="" /></div> -->

          </div>

          <div style="text-align: center">

            <p>许可证</p>

            <div><img style="width: 240px" :src="certificates" alt="" /></div>

          </div>

        </a-modal>

      </a-col>

    </a-row>

  </page-header-wrapper>

</template>



<script>

let treeData = [

  {

    name: '五等份的花架',

    key: '五等份的花架',

    scopedSlots: { title: 'title1' }, //有此属性的都会被装上插槽名为title的插槽

    children: [

      {

        name: '只能选一个',

        key: '0-0-0',

        scopedSlots: { title: 'title' },

        children: [

          { name: '一花 13388888888', key: '一花 13388888888', scopedSlots: { title: 'title' } },

          { name: '二乃 13388888888', key: '二乃 13388888888', scopedSlots: { title: 'title' } },

          { name: '三玖 13388888888', key: '三玖 13388888888', scopedSlots: { title: 'title' } },

          { name: '四叶 13388888888', key: '四叶 13388888888', scopedSlots: { title: 'title' } },

          { name: '五月 13388888888', key: '五月 13388888888', scopedSlots: { title: 'title' } }

        ]

      }

    ]

  },

  {

    name: '我的青春物语果然有问题',

    key: '我的青春物语果然有问题',

    scopedSlots: { title: 'title1' },

    children: [

      {

        name: '大老师自爆',

        key: '1-0-0',

        scopedSlots: { title: 'title' },

        children: [

          { name: '雪乃 13388888888', key: '雪乃 13388888888', scopedSlots: { title: 'title' } },

          { name: '团子 13388888888', key: '团子 13388888888', scopedSlots: { title: 'title' } },

          { name: '一色 13388888888', key: '一色 13388888888', scopedSlots: { title: 'title' } },

          { name: '平冢静 13388888888', key: '平冢静 13388888888', scopedSlots: { title: 'title' } }

        ]

      }

    ]

  },

  {

    name: '青春猪头少年不可能梦见兔女郎学姐',

    key: '青春猪头少年不可能梦见兔女郎学姐',

    scopedSlots: { title: 'title1' },

    children: [

      {

        name: '麻衣姐姐天下第一',

        key: '2-0-0',

        scopedSlots: { title: 'title' },

        children: [

          { name: '李白 13388888888', key: '李白 13388888888', scopedSlots: { title: 'title' } },

          { name: '杜甫 13388888888', key: '杜甫 13388888888', scopedSlots: { title: 'title' } },

          { name: '王维 13388888888', key: '王维 13388888888', scopedSlots: { title: 'title' } },

          { name: '白居易 13388888888', key: '白居易 13388888888', scopedSlots: { title: 'title' } }

        ]

      }

    ]

  },

  {

    name: '路人女主养成计划',

    key: '路人女主养成计划',

    scopedSlots: { title: 'title1' },

    children: [

      {

        name: '授权子公司',

        key: '3-0-0',

        scopedSlots: { title: 'title' },

        children: [

          { name: '学姐 13444433888', key: '165156165', scopedSlots: { title: 'title' } },

          { name: '双马尾 13354648588', key: '89456541564', scopedSlots: { title: 'title' } },

          { name: '加藤惠 13123132288', key: '65465', scopedSlots: { title: 'title' } }

        ]

      }

    ]

  }

];

export default {

    data() {

      return {

        replaceFields:{title:'name'},

        expandedKeys: [],

        backupsExpandedKeys: [],

        autoExpandParent: false,

        checkedKeys: [],

        selectedKeys: [],

        searchValue: '',

        treeData,

        searchStr: ''

      };

    },

    methods: {

      onSearch(){

        var vm=this;

        //添加这行代码是为了只点击搜索才触发

        vm.searchValue = vm.searchStr;

        //如果搜索值为空,则不展开任何项,expandedKeys置为空

        //如果搜索值不位空,则expandedKeys的值要为搜索值的父亲及其所有祖先

        if(vm.searchValue === ''){

          vm.expandedKeys = [];

        }else{

          //首先将展开项与展开项副本置为空

          vm.expandedKeys = [];

          vm.backupsExpandedKeys = [];

          //获取所有存在searchValue的节点

          let candidateKeysList = vm.getkeyList(vm.searchValue,vm.treeData,[]);

          //遍历满足条件的所有节点

          candidateKeysList.map(

            item=>{

              //获取每个节点的母亲节点

              var key=vm.getParentKey(item,vm.treeData);

              //当item是最高一级,父key为undefined,将不放入到数组中

              //如果母亲已存在于数组中,也不放入到数组中

              if(key && !vm.backupsExpandedKeys.some(item=>item===key))

                vm.backupsExpandedKeys.push(key);

            }

          )

          let length=this.backupsExpandedKeys.length;

          for(let i=0;i<length;i++){

            vm.getAllParentKey(vm.backupsExpandedKeys[i],vm.treeData)

          }

          vm.expandedKeys = vm.backupsExpandedKeys.slice();

        }

      },

      //获取节点中含有value的所有key集合

      getkeyList(value,tree,keyList){

        //遍历所有同一级的树

        for(let i=0;i<tree.length;i++){

          let node = tree[i];

          //如果该节点存在value值则push

          if(node.name.indexOf(value)>-1){

            keyList.push(node.key);

          }

          //如果拥有孩子继续遍历

          if(node.children){

              this.getkeyList(value,node.children,keyList);

          }

        }

        //因为是引用类型,所有每次递归操作的都是同一个数组

        return keyList;

      },

      //该递归主要用于获取key的父亲节点的key值

      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.key===key)){

              parentKey = node.key;

            }else if(temp=this.getParentKey(key,node.children)){

              //parentKey = this.getParentKey(key,node.children)

              //改进,避免二次遍历

              parentKey = temp;

            }

          }

        }

        return parentKey;

      },

      //获取该节点的所有祖先节点

      getAllParentKey(key,tree){

        var parentKey;

        if(key){

          //获得父亲节点

          parentKey = this.getParentKey(key,tree);

          if(parentKey){

            //如果父亲节点存在,判断是否已经存在于展开列表里,不存在就进行push

            if(!this.backupsExpandedKeys.some(item=>item===parentKey)){

              this.backupsExpandedKeys.push(parentKey);

            }

            //继续向上查找祖先节点

            this.getAllParentKey(parentKey,tree);

          }

        }

      },

      onExpand(expandedKeys) {

        //用户点击展开时,取消自动展开效果

        this.expandedKeys = expandedKeys;

        this.autoExpandParent = false;

      },

      onCheck(checkedKeys) {

        console.log('onCheck', checkedKeys);

        this.checkedKeys = checkedKeys;

      },

      onSelect(selectedKeys, info) {

        console.log('onSelect', info);

        this.selectedKeys = selectedKeys;

      },

    },

  };

</script>



<style lang="less" scoped>

::v-deep .ant-tree-node-content-wrapper {

  display: contents !important;

}

</style>

此demo复制过去就能使用,但是发起网络请求并处理数据后有时候会出现搜索无法展开的情况。此时需要在处理数据时处理异步操作,下面是我当时的解决办法

其中使用 async 与 await 解决异步

?为判断内部是否有后面的参数

??为如果值为 空 或者 null 就执行后续代码

async getComputeData() {
      //获取公司列表
     const res = await  this.$mApi.getNodeAction('/company/list', { pageSize: 100000, pageNo: 1 });
        this.companyList = res.result.data;
        // console.log('接口获取的公司列表', res.result.data);
        //将数组进行修改并push到 treeData 里面
        this.treeData = [];
        for (const element of res.result.data) {
          const { result = {} } = await this.$mApi.getNodeAction('/team/company', { id: element.id });
          if (!result.authCompanyList.length) {
              this.treeData.push({
                // name: element.name,
                name: element?.name ?? '暂时公司没名字' ,
                key: element.id,
                scopedSlots: { title: 'title1' }
              });
              // this.generateList(res.result.data); // 必须初始化树结构时执行,否则搜索结果不展开
            } else {
              //遍历子公司
              let childrenList = [];
              for (const item of result.authCompanyList) {
                childrenList.push({
                  name: item.realname || 'haha',
                  key: item.company_id,
                  scopedSlots: { title: 'title' }
                });
              }
              this.treeData.push({
                // name:element.name,
                name: element?.name ?? '暂时公司没名字' ,
                key: element.id,
                scopedSlots: { title: 'title1' },
                children: [
                  {
                    name: '授权子公司',
                    key: element.name + element.id,
                    scopedSlots: { title: 'title' },
                    children: childrenList
                  }
                ]
              });
        }
      }
    },

效果展示

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: antd-mobile-vue是一个基于Vue.js框架的移动端组件库,它提供了一系列UI组件,用于开发高质量的移动端应用。 与其它UI组件库相比,antd-mobile-vue具有以下优势和特点: 1. 高质量的组件:antd-mobile-vue提供了丰富的移动端UI组件,如按钮、表单、弹窗、导航等,这些组件都经过了精心设计和开发,具有统一的风格和良好的用户体验。 2. 灵活的布局:antd-mobile-vue提供了灵活的布局组件,如栅格布局、Flex布局,可帮助开发者快速搭建页面结构,并自适应不同的屏幕尺寸。 3. 易于使用和扩展:antd-mobile-vue的组件使用简单,开发者可以通过简单的配置和参数就可以实现复杂的交互效果。而且,antd-mobile-vue的组件提供了丰富的扩展能力,可以根据项目需求进行个性化的定制。 4. 生态丰富:antd-mobile-vue拥有庞大的开发者社区和活跃的维护团队,开发者可以通过官方文档和社区资源获取帮助和支持。此外,antd-mobile-vue还与其它Vue.js生态工具和库良好地兼容,如Vue Router、Vue CLI等。 5. 支持国际化:antd-mobile-vue提供了多语言支持,开发者可以根据项目需求灵活地切换多种语言环境。 总之,antd-mobile-vue是一个功能强大、易于使用和扩展的移动端组件库,它可以帮助开发者快速构建高质量的移动端应用,提高开发效率和用户体验。 ### 回答2: antd-mobile-vue是一种基于Vue.js框架的移动端UI库。它是对Ant Design Mobile的Vue组件实现的封装和扩展,旨在为开发者提供高质量、易用性的移动端组件库,帮助快速开发移动应用程序。 antd-mobile-vue提供了丰富的移动端UI组件,如按钮、导航栏、标签栏、列表、表单等,可以满足日常开发中绝大部分的界面需求。这些组件都经过精心设计和优化,在视觉和交互上都符合当前移动端的设计原则和用户体验。而且,它还提供了灵活的定制和扩展能力,允许开发者根据具体需求进行个性化定制,提高开发效率和用户体验。 除了UI组件外,antd-mobile-vue还提供了一些实用的工具和功能,如样式工具库、语言国际化、路由管理等。这些工具和功能都是为了让开发者更方便地进行移动应用开发,减少重复性的工作,提高开发效率。 antd-mobile-vue拥有广泛的社区支持和文档资料,开发者可以从社区中获取帮助和解决问题,学习和掌握使用该库的技巧和最佳实践。同时,antd-mobile-vue还提供了详细的官方文档和示例代码,方便开发者快速入手和上手该库。 总之,antd-mobile-vue是一款功能强大、易用性强的移动端UI库,适用于各种移动应用的开发。无论是个人开发者还是团队开发,都可以通过使用antd-mobile-vue来快速构建高质量的移动应用程序。 ### 回答3: antd-mobile-vue 是一个基于 Vue.js 的移动端 UI 组件库,它提供了丰富的移动端组件和样式风格,可以帮助开发者快速构建优雅的移动端应用。 antd-mobile-vue 的特点有以下几个方面: 1. 高度可定制:antd-mobile-vue 提供了大量的组件,涵盖了移动端常见的UI元素,如按钮、导航栏、表单等,这些组件的样式和交互行为都可以通过配置进行定制,满足不同项目的需求。 2. 兼容性强:antd-mobile-vue 提供了对不同移动端浏览器和操作系统的支持,保证组件在不同环境下的正常运行和展示,同时也保证了用户的使用体验。 3. 特色设计:antd-mobile-vue 的设计风格简洁、现代,符合移动端用户的审美要求,同时也遵循了 Material Design 和 iOS Human Interface Guidelines 等设计准则,保证了用户的熟悉感和易用性。 4. 文档丰富:antd-mobile-vue 提供了详细的文档和示例代码,开发者可以根据文档了解组件的使用方法和配置参数,快速上手使用。 5. 生态丰富:antd-mobile-vue 是基于 Ant Design Mobile(antd-mobile)的 Vue 实现,可以与其它 Vue 生态工具和插件无缝集成,如 Vue Router、Vuex 等,方便开发者构建复杂的移动应用。 总之,antd-mobile-vue 是一个强大而灵活的移动端 UI 组件库,它可以帮助开发者节省时间和精力,快速开发出高质量的移动应用。无论是个人项目还是企业应用,都可以考虑使用这个库来提升开发效率和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值