Vue.js递归组件实现组织架构树和选人功能


Posted in Javascript onJuly 04, 2019

大家好!先上图看看本次案例的整体效果。

Vue.js递归组件实现组织架构树和选人功能

浪奔,浪流,万里涛涛江水永不休。如果在jq时代来实这个功能简直有些噩梦了,但是自从前端思想发展到现在的以MVVM为主流的大背景下,来实现一个这样繁杂的功能简直不能容易太多。下面就手把手带您一步步拨开这个案例的层层迷雾。

实现步骤如下:

1. api构建部门和员工信息接口,vuex全局存放部门list和员工list数据信息。

api:

export default {
 getEmployeeList () {
  return {
   returncode: 0,
   message: '',
   result: [
    {
     id: 1,
     employeeName: '吴亦凡',
     departmentId: 44
    },
    {
     id: 2,
     employeeName: '鹿晗',
     departmentId: 45
    },
    {
     id: 3,
     employeeName: '孙红雷',
     departmentId: 44
    },
    {
     id: 4,
     employeeName: '周杰伦',
     departmentId: 45
    },
    {
     id: 5,
     employeeName: '张国荣',
     departmentId: 45
    },
    {
     id: 6,
     employeeName: '陈百强',
     departmentId: 45
    },
    {
     id: 7,
     employeeName: '谭咏麟',
     departmentId: 41
    },
    {
     id: 8,
     employeeName: '谷村新司',
     departmentId: 45
    },
    {
     id: 9,
     employeeName: '中岛美雪',
     departmentId: 46
    },
    {
     id: 10,
     employeeName: '周润发',
     departmentId: 47
    },
    {
     id: 14,
     employeeName: '周慧敏',
     departmentId: 58
    },
    {
     id: 13,
     employeeName: '张学友',
     departmentId: 58
    }
   ]
  }
 },
 getDepartmentList () {
  return {
   returncode: 0,
   message: '',
   result: [
    {
     id: 40,
     name: '研发一部',
     parentId: 37,
     sequence: 2
    },
    {
     id: 41,
     name: '研发二部',
     parentId: 37,
     sequence: 4
    },
    {
     id: 43,
     name: '市场',
     parentId: 0,
     sequence: 6
    },
    {
     id: 44,
     name: '销售',
     parentId: 0,
     sequence: 4
    },
    {
     id: 45,
     name: '财务',
     parentId: 0,
     sequence: 5
    },
    {
     id: 46,
     name: '研发三部',
     parentId: 37,
     sequence: 1
    },
    {
     id: 47,
     name: '研发四部',
     parentId: 37,
     sequence: 3
    },
    {
     id: 37,
     name: '研发',
     parentId: 0,
     sequence: 5
    },
    {
     id: 58,
     name: '研发一部',
     parentId: 57,
     sequence: 1
    },
    {
     id: 59,
     name: '测试',
     parentId: 0,
     sequence: 5
    },
    {
     id: 60,
     name: '测试一部',
     parentId: 59,
     sequence: 1
    },
    {
     id: 61,
     name: '测试二部',
     parentId: 59,
     sequence: 2
    },
    {
     id: 62,
     name: '研发二部',
     parentId: 57,
     sequence: 2
    }
   ]
  }
 }
}

store:

import dataApi from '@/api/data.api.js'
const state = {
 employeeList: [],
 departmentList: []
}

const getters = {
 employeeList: state => state.employeeList,
 departmentList: state => state.departmentList
}

const mutations = {
 SetEmployeeList (state, { employeeList }) {
  state.employeeList = employeeList
 },
 SetDepartmentList (state, { departmentList }) {
  state.departmentList = departmentList
 }
}

const actions = {
 getEmployeeList ({ commit }) {
  let employeeResult = dataApi.getEmployeeList()
  if (employeeResult.returncode === 0) {
   commit('SetEmployeeList', { employeeList: employeeResult.result })
  }
 },
 getDepartmentList ({ commit }) {
  let departmentResult = dataApi.getDepartmentList()
  if (departmentResult.returncode === 0) {
   commit('SetDepartmentList', { departmentList: departmentResult.result })
  }
 }
}

export default {
 state,
 getters,
 mutations,
 actions,
 namespaced: true
}

2. vue.$set为员工对象增加响应式属性checked控制是否选中,methods中创建选中方法如下:

selectEmployee () {
   var self = this
   if (self.employee.checked === undefined) {
    this.$set(self.employee, 'checked', true)
   } else {
    self.employee.checked = !self.employee.checked
   }
  }

3. computed计算属性监控文本框输入字段searchKey的变化实现左侧员工列表实时检索功能。

searchEmployeeList () {
   var self = this
   if (self.searchKey.trim() === '') {
    console.log(self.employeeList)
    return self.employeeList.filter(item => item.checked === undefined || !item.checked)
   } else {
    return self.employeeList.filter(item => (item.employeeName.indexOf(self.searchKey.trim()) !== -1) && (item.checked === undefined || !item.checked))
   }
  }

4. 构建组织结构树的部门组件,部门下可能存在子部门和员工,所以组件内部再调用部门组件和员工组件,以达到循环递归的效果。

<template>
 <li @click.stop="expandTree()">
  <a :class="lvl|level">
   <span class="expand-tree-icon">
    <i class="fa fa-caret-right" :class="{'active':department.expand}"></i>
   </span>
   <span>
    <i class="lcfont lc-department-o"></i>
   </span>
   <span class="title">
    <span>{{department.name}}</span>
    <span class="title-desc">({{allChildEmployeeList.length}}人 )</span>
    <i class="lcfont lc-add" @click.stop="selectDepartmentEmployees()" title="添加整个部门成员"></i>
   </span>
  </a>
  <ul v-show="department.expand">
   <child-employee
    v-for="(employee,index) in childEmployeeList"
    :employee="employee"
    :lvl="lvl+1"
    :key="index"
   ></child-employee>
   <child-department
    v-for="(department,index) in childDepartmentList"
    :department="department"
    :employeeList="employeeList"
    :departmentList="departmentList"
    :lvl="lvl+1"
    :key="index"
   ></child-department>
  </ul>
 </li>
</template>

5. 结构树之员工组件

<template>
 <li v-on:click.stop="selectEmployee()">
  <a class="member-item" v-bind:class="lvl|level" href="javascript:;" rel="external nofollow" >
   <div class="lc-avatar flex-se1" name="true" size="30">
    <div class="lc-avatar-30" :title="employee.employeeName">
     <span class="lc-avatar-def" style="background-color: rgb(112, 118, 142);">
      <div>{{employee.employeeName}}</div>
     </span>
     <div class="lc-avatar-name">{{employee.employeeName}}</div>
    </div>
   </div>
   <i class="lcfont" v-bind:class="{'lc-check':employee.checked}"></i>
  </a>
 </li>
</template>

6. 和上面员工的选中原理类似,控制部门节点的展开和合并也通过$set方法扩展一个响应式的expand属性。

expandTree () {
   var self = this
   if (self.department.expand === undefined) {
    self.$set(self.department, 'expand', true)
   } else {
    self.department.expand = !self.department.expand
   }
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
纯文字版返回顶端的js代码
Aug 01 Javascript
js简单实现删除记录时的提示效果
Dec 05 Javascript
jquery事件重复绑定的快速解决方法
Jan 03 Javascript
JavaScript中的条件判断语句使用详解
Jun 03 Javascript
jquery实现不包含当前项的选择器实例
Jun 25 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
Dec 10 Javascript
基于jquery实现图片上传本地预览功能
Jan 08 Javascript
Node.js制作简单聊天室
Jan 12 Javascript
AngularJS中的路由使用及实现代码
Oct 09 Javascript
vue实现验证码输入框组件
Dec 14 Javascript
vue单页缓存存在的问题及解决方案(小结)
Sep 25 Javascript
关于AngularJS中几种Providers的区别总结
May 17 Javascript
vue-cli配置flexible过程详解
Jul 04 #Javascript
vue动态配置模板 'component is'代码
Jul 04 #Javascript
react 移动端实现列表左滑删除的示例代码
Jul 04 #Javascript
jQuery删除/清空指定元素的所有子节点实例代码
Jul 04 #jQuery
小程序中canvas的drawImage方法参数使用详解
Jul 04 #Javascript
vue如何限制只能输入正负数及小数
Jul 04 #Javascript
Vue项目中ESlint规范示例代码
Jul 04 #Javascript
You might like
一个程序下载的管理程序(一)
2006/10/09 PHP
php 采集书并合成txt格式的实现代码
2009/03/01 PHP
php 随机生成10位字符代码
2009/03/26 PHP
PHP数据库调用类调用实例(详细注释)
2012/07/12 PHP
destoon安装出现Internal Server Error的解决方法
2014/06/21 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
如何判断图片地址是否失效
2007/02/02 Javascript
关于jquery性能最佳实践的讨论,与求教
2012/03/30 Javascript
jQuery中[attribute!=value]选择器用法实例
2014/12/31 Javascript
浅谈javascript事件取消和阻止冒泡
2015/05/26 Javascript
jQuery切换所有复选框选中状态的方法
2015/07/02 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
jQuery Ajax 实例代码 ($.ajax、$.post、$.get)
2016/04/29 Javascript
vue.js中指令Directives详解
2017/03/20 Javascript
vue在使用ECharts时的异步更新和数据加载详解
2017/11/22 Javascript
解决循环中setTimeout执行顺序的问题
2018/06/20 Javascript
详解使用jest对vue项目进行单元测试
2018/09/07 Javascript
详解vue中使用微信jssdk
2019/04/19 Javascript
Vue 实现从文件中获取文本信息的方法详解
2019/10/16 Javascript
ElementUI之Message功能拓展详解
2019/10/18 Javascript
JS判断数组四种实现方法详解
2020/06/29 Javascript
[01:44]Ti10举办地公布
2019/08/25 DOTA
Python 实现数据结构-堆栈和队列的操作方法
2019/07/17 Python
python实现人脸签到系统
2020/04/13 Python
基于python实现ROC曲线绘制广场解析
2020/06/28 Python
HTML5的革新 结构之美
2011/06/20 HTML / CSS
什么是Rollback Segment
2013/04/22 面试题
物业公司采购员岗位职责
2013/12/31 职场文书
运动会广播稿60字
2014/01/15 职场文书
教师年度考核自我鉴定
2014/01/19 职场文书
有多年工作经验的自我评价
2014/03/02 职场文书
三严三实心得体会范文
2014/10/13 职场文书
乐山大佛导游词
2015/02/02 职场文书
物业接待员岗位职责
2015/04/15 职场文书
小学六年级班主任工作经验交流材料
2015/11/02 职场文书
阿里云ECS云服务器快照的概念以及如何使用
2022/04/21 Servers