vue使用ant design tree树形控件搜索功能及配合表格动态隐藏列数据

效果展示

项目中有时会用到表格动态列的功能,在使用ant design时发现并没有这个功能,而列显隐的功能用到的及较多,所以就只能自己封装下。

子页面:

<template>
  <a-drawer :visible="visible" width="30%" @close="close" :drawerStyle="{background:'#06347f'}" :closable="false">
    <div class="person">
      <div style="width: 100%; padding: 10px margin-top:20px;">
        <a-input-search v-model="searchStr" placeholder="输⼊搜选项" style="width: 100%" @search="onSearch"></a-input-search>
      </div>
      <!-- selectedKeys是选中项key的集合,expandedKeys是展开项key的集合-->
      <a-tree v-if="treeData.length" :checkedKeys="checkedKeys" :treeData="treeData" checkable :selectable="false"
        :selectedKeys="selectedKeys" :expandedKeys="expandedKeys" @expand="onExpand" :autoExpandParent="autoExpandParent" 
        @select="onSelect" @check="onCheck" class="person-tree" show-line>
        <template slot="name" slot-scope="{ name }">
          <span v-html="name.replace(new RegExp(searchValue,'g'),'<span style=color:#f50>'+searchValue+'</span>')"></span>
        </template>
      </a-tree>
    </div>
  </a-drawer> 
</template>

<script>
export default {
  props:{
    visible:{
      type:Boolean,
      default:false
    },
    columns:{
      type:Array,
      default:Array
    },
  },
  data(){
    return{
      expandedKeys: [],
      backupsExpandedKeys: [],
      autoExpandParent: false,
      checkedKeys: [],
      selectedKeys: [],
      searchValue: '',
      treeData: [],
      searchStr: '',
      column:[]
    }
  },
  created(){
    this.getTreeData()
  },
  methods:{
    getTreeData(){
      this.column=this.columns
      let data=[{
        name: '数据列显隐',
        key: '0-0',
        scopedSlots: { title: 'name' },
        children: []
      }]
      this.columns.forEach(item=>{
        if(item.title && item.key){
          data[0].children.push({name:item.title,key:item.key,scopedSlots:{title:'name'}})
          this.checkedKeys.push(item.key)
          this.selectedKeys.push(item.key)
        }
      })
      this.treeData=data
    },
    onSearch () {
      this.searchValue = this.searchStr
      if (this.searchValue === '') {
        this.expandedKeys = []
      } else {
        this.expandedKeys = []
        this.backupsExpandedKeys = []
        const candidateKeysList = this.getkeyList(this.searchValue,this.treeData,[])
        candidateKeysList.forEach((item) => {
          const key = this.getParentKey(item, this.treeData)
          // eslint-disable-next-line no-shadow
          if (key && !this.backupsExpandedKeys.some((item) => item === key)) this.backupsExpandedKeys.push(key)
        })
        const { length } = this.backupsExpandedKeys
        // eslint-disable-next-line no-plusplus
        for (let i = 0; i < length; i++) {
          this.getAllParentKey(this.backupsExpandedKeys[i],this.treeData)
        }
        this.expandedKeys = this.backupsExpandedKeys.slice()
      }
    },
    getkeyList (value, tree, keyList) {
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        if (node.name.indexOf(value) > -1) {
          keyList.push(node.key)
        }
        if (node.children) {
          this.getkeyList(value, node.children, keyList)
        }
      }
      return keyList
    },
    getParentKey (key, tree) {
      let parentKey
      let temp
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i]
        if (node.children) {
          if (node.children.some((item) => item.key === key)) {
            parentKey = node.key
            // eslint-disable-next-line no-cond-assign
          } else if((temp = this.getParentKey(key, node.children))){
            parentKey = temp
          }
        }
      }
      return parentKey
    },
    getAllParentKey (key, tree) {
      let parentKey
      if (key) {
        parentKey = this.getParentKey(key, tree)
        if (parentKey) {
          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,e) {
      let nodes=e.checkedNodes
      let names=[]
      this.column.forEach(item=>{
        for (var i in nodes) {
          let info=nodes[i].data.props.dataRef
          if(item.key==info.key){
            names.push(item)
          }
        }
      })
      this.checkedKeys = checkedKeys
      this.tableProps(names)
    },
    onSelect (selectedKeys, e) {
      let nodes=e.checkedNodes
      let names=[]
      this.column.forEach(item=>{
        for (var i in nodes) {
          let info=nodes[i].data.props.dataRef
          if(item.key==info.key){
            names.push(item)
          }
        }
      })
      this.selectedKeys = selectedKeys
      this.tableProps(names)
    },
    tableProps(names){
      let column=names
      column.unshift({title:'序号',width:80,align:'center',scopedSlots:{customRender:'index'}})
      column.push({title:'操作',width:300,align:'center',scopedSlots:{customRender:'action'}})
      this.$emit('close',column)
    },
    close(){
      this.$emit('close')
    }
  }
}
</script>

<style lang="scss" scope>
.person {
  width: 100%;
  background: #06347f;
  overflow: hidden;
  .ant-input {
    background: #06347f;
    border: 1px solid #08a7fd;
    color: #fff;
  }
  .ant-input-search {
    .ant-input-search-icon {
      color: #fff;
    }
  }
  .person-tree {
    color: #00adff;
    .ant-tree-title {
      color: #00adff;
    }
    .ant-tree-checkbox-inner {
      background-color: transparent;
      border-color: #00adff;
    }
  }
  li.ant-tree-treenode-disabled > .ant-tree-node-content-wrapper span {
    color: #00adff;
  }
  .ant-tree li .ant-tree-node-content-wrapper {
    width: calc(100%-24px);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: #00adff;
  }
  .ant-tree.ant-tree-show-line li span.ant-tree-switcher {
    color: #00adff;
    background: rgba(0, 60, 117, 1);
  }
  .ant-tree.ant-tree-show-line li:not(:last-child)::before {
    border-left: 1px dashed #00adff;
    top: 6px;
    height: calc(90%);
  }
}
</style>

默认拿到table表格columns配置的数据,其中序号列和操作列不进行动态显隐,如果需要请自行配置

父页面:

剩下的就是在需要的页面引入该功能就可以了

<template>
  <div>
    <div class="btn-top">
      <div class="btn-top-left"><a-button type="primary" icon="plus">新增</a-button></div>
      <div class="btn-top-right"><a-button shape="circle" icon="unordered-list" @click="visible=!visible"></a-button></div>
    </div>
    <a-table :columns="columns" :data-source="dataList">
      <template slot="index" slot-scope="text,record,index">{{index+1}}</template>
      <template slot="action">
        <a-button type="link" icon="eye">详情</a-button>
        <a-button type="link" icon="edit">编辑</a-button>
        <a-button type="link" icon="delete" style="color:red;">删除</a-button>
      </template>
    </a-table>

    <dynamic-column :visible="visible" :columns="columns" @close="close"></dynamic-column>
  </div>
</template>

<script>
import dynamicColumn from "@/components/dynamicColumn.vue"
export default {
  components:{dynamicColumn},
  data(){
    return{
      columns:[
        {title:'序号',width:80,align:'center',scopedSlots:{customRender:'index'}},
        {title:'姓名',align:'center',dataIndex:'name',key:'name'},
        {title:'性别',align:'center',dataIndex:'sex',key:'sex'},
        {title:'年龄',align:'center',dataIndex:'age',key:'age'},
        {title:'籍贯',align:'center',dataIndex:'place',key:'place'},
        {title:'部门',align:'center',dataIndex:'depart',key:'depart'},
        {title:'岗位',align:'center',dataIndex:'post',key:'post'},
        {title:'职长',align:'center',dataIndex:'postTime',key:'postTime'},
        {title:'能力',align:'center',dataIndex:'abillty',key:'abillty'},
        {title:'操作',width:300,align:'center',scopedSlots:{customRender:'action'}},
      ],
      dataList:[
        {name:'妲己',sex:'女',age:'17',place:'山东',depart:'财务',post:'部长',postTime:'2年',abillty:'优'},
        {name:'墨子',sex:'男',age:'19',place:'广州',depart:'人资',post:'部长',postTime:'3年',abillty:'良'},
        {name:'鲁班',sex:'男',age:'18',place:'上海',depart:'技术',post:'部长',postTime:'2年',abillty:'优'},
        {name:'庄周',sex:'女',age:'21',place:'河北',depart:'后勤',post:'部长',postTime:'4年',abillty:'良'},
      ],
      visible:false
    }
  },
  methods:{
    close(list){
      if(list){
        this.columns=list
      }else{
        this.visible=false
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.btn-top{
  padding: 10px;
  display: flex;
  justify-content: space-between;
}
</style>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值