【Vue.js实战案例】- Vue.js递归组件实现组织架构树和选人功能

栏目: 编程语言 · 发布时间: 5年前

内容简介:大家好!先上图看看本次案例的整体效果。1. api构建部门和员工信息接口,vuex全局存放部门list和员工list数据信息。

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

【Vue.js实战案例】- 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:;">
      <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
      }
    }

以上就是核心步骤的整体思路,欢迎讨论。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大数据之眼

大数据之眼

[德]尤夫娜·霍夫施泰特 / 陈巍 / 浙江文艺出版社 / 2018-5-7 / 68.00元

德国狂销10万册的大数据商业应用畅销书,经典之作《大数据时代》的姊妹篇。 该书在德语国家促发了一场关于大数据,人工智能与人的关系建构的大讨论。 德国大数据与人工智能领域权威,首度为中国读者亲笔作序。 在后大数据时代,如何维护自己的隐私,如何巧妙利用资源获得更多金钱? 一部对大数据发展所产生的问题进行思考和规避的先知式作品。 当智能机器欲“优化”我们,入侵我们的生活,统......一起来看看 《大数据之眼》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具