人力资源管理系统随记(二)

120 阅读2分钟

路由表

  • 在当前项目中,我们要实现的最终效果是:不同用户登陆进来时,显示出来的菜单功能是不同的

静态路由表:不需要做权限控制的路由,每个用户都可以正常访问。
动态路由表:需要做权限控制的路由,用户如果权限不一致访问到的路由也不一样。

拆分静态和动态路由表

// 省略其他...
// 动态路由表,项目中不同的用户可以访问不同的功能
export const asyncRoutes = [
  // 先空着这里,后面来补充功能
]

// 静态路由表,项目中每个用户都可以访问的功能
export const constantRoutes = [
  // 省略....
]

const createRouter = () => new Router({
  // 控制路由滚动行为  滚动到顶部
  scrollBehavior: () => ({ y: 0 }),
  // 组合到一起组成路由表
  routes: [...constantRoutes, ...asyncRoutes]
})

快速创建文件夹命令

# 快速创建文件夹
# 使用 Git bash here 这个工具进行文件夹创建
mkdir departments employees setting salarys social attendances approvals permission

注意: 需要在需要创建文件的文件夹下打开终端执行

嵌套路由

分析 要想显示员工管理页面的内容的同时 还能看到layout组件,则可以将它设置为layout的二级路由。

{
    path: '/approvals', // 审批
    component: Layout,
    children: [
      {
        path: '',
        name: 'Approvals',
        component: () => import('@/views/approvals'),
        meta: { title: '审批' }
      }
    ]
  }

总结 模仿原来首页的写法,实现了Layout架子的渲染,并且我们把二级路由的path选项置空,作为默认渲染路由。

动态设置标题

image.png 方法

  1. permission.js引入工具方法getPageTitle
    getPageTitle
import defaultSettings from '@/settings'

const title = defaultSettings.title || 'Vue Admin Template'

export default function getPageTitle(pageTitle) {
  if (pageTitle) {
    // return `${pageTitle} - ${title}`
    return `${title} - ${pageTitle}`
  }
  return `${title}`
}
  1. 等待路由页面跳转完成后, 设置最后一个to的元信息meta里的title标题
// 后置路由守卫
router.afterEach((to, from) => {
  document.title = getPageTitle(to.meta.title)
  // 隐藏进度条效果
  NProgress.done()
})

默认插槽

 <!-- 默认插槽  并且使用内部的数据进行自定义模板的渲染, 
 scope.data 所以直接key解构赋值变量也是data(对应数据对象)-->
          <el-tree class="departments-tree" :data="treeData" :props="defaultProps">
              <template #default="{ data }">
                <el-row
                  type="flex"
                  justify="space-between"
                  align="middle"
                  style="height: 40px; width: 100%;"
                >
                  <!-- 部门名字 -->
                  <el-col :span="20">
                    <span>{{ data.name }}</span>
                  </el-col>
                  <!-- 负责人、操作 -->
                  <el-col :span="4">
                    <el-row type="flex" justify="end">
                      <el-col>{{ data.manager }}</el-col>
                      <el-col>
  • 使用插槽技术的时候,想要在插槽具体标签位置,如何拿到组件内给插槽绑定属性和值?

v-slot="变量名" (变量名的值:会收集slot身上属性和值形成对象)
例如:v-slot="scope" scope的值 组件内源码在slot身上的属性名和值{data:行数据对象}
#default="{ data }" 写全了是 v-slot:deflut="{ data }"

数据结构转化

/**
 * 把扁平结构的数据, 转成树形控件
 * @param {*} list 遍历结构数组
 * @param {*} rootValue 返回数组,第一层对象的pid值
 * @returns
 */
export function transTree(list, rootValue) {
  const treeData = [] // 装下属对象的
  list.forEach(item => {
    if (item.pid === rootValue) { // 当前对象pid符合, 继续递归调用查找它的下属
      const children = transTree(list, item.id) // 返回item对象下属数组
      if (children.length) {
        item.children = children // 为item添加children属性保存下属数组
      }
      treeData.push(item) // 把当前对象保存到数组里, 继续遍历
    }
  })
  // 遍历结束, rootValue的id对应下属们收集成功, 返回给上一次递归调用children, 加到父级对象的children属性下
  return treeData
}

.sync

<!-- 新增-子部门-弹窗 -->
<!-- .sync作用: 快速实现双向数据绑定
	以前: 子改父变量值
	需求: 组件内想要影响父组件的showDepartDialog变量值, 可以这样写
	父组件: 绑定自定义事件, 把值赋予给父页面里变量
    @updateDialog="val => showDepartDialog = val"
    子组件: 触发自定义事件, 传值给val
    this.$emit('updateDialog', false)

    现在: 我不想自己起自定义事件名, 也不想写赋值的函数, 让.sync帮我吧
	:dialog-visible.sync="showDepartDialog"
    这句话干了2件事 
		(1): 把showDepartDialog变量值传入给组件内props叫dialogVisible变量 (父->子)
		(2): 转换为自定义事件绑定@update:dialogVisible="val => showDepartDialog = val"
    哎哎哎. 巧了, 这.sync干的第二件事和我们父绑定事件一样啊, 而且少写这么多代码, 真香

    总结: .sync可以给当前绑定绑定固定格式update:变量名的事件, 把值赋予给右侧的变量
-->
<depart-dialog :dialog-visible.sync="showDepartDialog" />

.sync实际上干了什么?

给所在标签绑定了@update:属性名="val => Vue变量名 = val"
其实就是个语法糖, 绑定个自定义事件, 把收到的值给右侧的Vue变量