项目作者: sijinglei

项目描述 :
基于vuejs的树表格
高级语言: Vue
项目地址: git://github.com/sijinglei/vue-tree-table.git
创建时间: 2018-07-23T09:03:19Z
项目社区:https://github.com/sijinglei/vue-tree-table

开源协议:

下载


基于vue.js实现树形表格的封装(vue-tree-table)

前言

由于公司产品(基于vue.js)需要,要实现一个树形表格的功能,百度、google找了一通,并没有发现很靠谱的,也不是很灵活。所以就用vue自己撸了一个,还望大家多多指教。

主要技术点:vue子组件的递归实现及相关样式的实现

树形表格实现

  • 效果图(Demo)
  • 主要代码

    index.vue页面实现业务逻辑代码,比如树表格上面的一些操作按钮的实现及数据获取。

    1. <template>
    2. <div class="contains">
    3. <h1>树表格实现</h1>
    4. <tree-table ref="recTree"
    5. :list.sync="treeDataSource"
    6. @actionFunc="actionFunc"
    7. @deleteFunc="deleteFunc"
    8. @orderByFunc="orderByFunc"></tree-table>
    9. </div>
    10. </template>
    11. <script>
    12. import treeTable from '@/components/tree-table.vue'
    13. export default {
    14. data() {
    15. return {
    16. list: [], // 请求原始数据
    17. treeDataSource: [] // 组合成树表格接收的数据
    18. }
    19. },
    20. components: {
    21. treeTable
    22. },
    23. methods: {
    24. orderByFunc(val) {
    25. alert('排序')
    26. alert(val)
    27. },
    28. actionFunc(m) {
    29. alert('编辑')
    30. },
    31. deleteFunc(m) {
    32. alert('删除')
    33. }
    34. }
    35. }
    36. </script>
    1. 原始数据`list`:是不包含子数据的数据结构,即没有层级结构,例如:
    2. [{id:111,parentId:0,name:'父及'},{id:111,parentId:111,name:'子级'}...],通过parentId来获取对应父子层级结构
    3. `treeDataSource`:是树表格需要的数据结构,例如:
    4. [{id:0,name:'父及',children:[{id:10,name:'子级',children:[]}]},...]

    如果后台返回给你的是原始数据格式,就可以用下面方法封装成树表格可以使用的数据结构:

    1. getTreeData() {
    2. // 取父节点
    3. let parentArr = this.list.filter(l => l.parentId === 0)
    4. this.treeDataSource = this.getTreeData(this.list, parentArr)
    5. },
    6. // 这里处理没有children结构的数据
    7. getTreeData(list, dataArr) {
    8. dataArr.map((pNode, i) => {
    9. let childObj = []
    10. list.map((cNode, j) => {
    11. if (pNode.Id === cNode.parentId) {
    12. childObj.push(cNode)
    13. }
    14. })
    15. pNode.children = childObj
    16. if (childObj.length > 0) {
    17. this.getTreeData(list, childObj)
    18. }
    19. })
    20. return dataArr
    21. }

    tree-table.vue页面。此页面是实现树表格的关健页面。主要代码如下:

    1. <template>
    2. <div class="tree-table">
    3. <div class="tree-head">
    4. <table>
    5. <tr>
    6. <td class="td1">职位名称</td>
    7. <td class="td2">负责人</td>
    8. <td class="td3" @click="isDesc=!isDesc">
    9. 创建时间
    10. <div class="arrow">
    11. <span class="up-arrow" :class="{'sort':isDesc}"></span>
    12. <span class="down-arrow" :class="{'sort':!isDesc}"></span>
    13. </div>
    14. </td>
    15. <td class="td4">工作经验</td>
    16. <td class="td5">发布时间</td>
    17. <td class="td6">操作</td>
    18. </tr>
    19. </table>
    20. </div>
    21. <div id="scrollWrap" class="tree-wrap">
    22. <div class="tree-body">
    23. <table v-if='treeDataSource.length>0'>
    24. <tbody>
    25. <tr>
    26. <td>
    27. <tree-item
    28. v-for="(model,i) in treeDataSource"
    29. :key="'root_node_'+i"
    30. :root="0"
    31. :num="i"
    32. @actionFunc="actionFunc"
    33. @deleteFunc="deleteFunc"
    34. :nodes="treeDataSource.length"
    35. :trees.sync="treeDataSource"
    36. :model.sync="model">
    37. </tree-item>
    38. </td>
    39. </tr>
    40. </tbody>
    41. </table>
    42. </div>
    43. </div>
    44. </div>
    45. </template>

    首先这里的子组件tree-item没有在页面上有引入,但是也可以正常使用。这里就是关健点,因为这个子组件是需要递归实现,所以,需要动态注册到当前组件中。代码如下(由于代码太多,先贴图说明吧,点击这里可以看源码):

这里子组件看起来是不是挺奇怪的,但是为了递归他本身,暂时也只想到这种办法。如果有更好的办法,欢迎留言指正。

那么,树表格的结构实现在哪里呢??对,就是在子组件的模版(template)里面,这里就不贴代码了,可以移步到源码查看。

  • 感谢

    收到favourli的指正,现已将原有写法更新,采用递归组件来实现,这样页面看起来就更清晰。

    1. components: {
    2. treeItem: () => import('./tree-item.vue')
    3. }

补充一点:不要只看js部分,css部分才是这个树表格的关健所在。当然里面我采用了大量的计算属性去判断各种样式的展示,还有一种方法,就是在initTreeData方法里面去实现,这个方法就是处理或添加一些我们树表格所使用的信息。比如我现在在里面实现的层级线的偏移量m.bLeft = level === 1 ? 34 : (level - 2) * 16 + 34 这个计算如果没有看明白,可以留言。

最后,此篇乃我的开篇之作,如有问题,还请多多包含,多多指教!!!顺便给我好久没有更新的博客打个广告,
欢迎点击(一座城池

Build Setup

  1. # install dependencies
  2. npm install
  3. # serve with hot reload at localhost:8080
  4. npm run dev
  5. # build for production with minification
  6. npm run build
  7. # build for production and view the bundle analyzer report
  8. npm run build --report

For a detailed explanation on how things work, check out the guide and docs for vue-loader.