路由表
- 在当前项目中,我们要实现的最终效果是:不同用户登陆进来时,显示出来的菜单功能是不同的
静态路由表:不需要做权限控制的路由,每个用户都可以正常访问。
动态路由表:需要做权限控制的路由,用户如果权限不一致访问到的路由也不一样。
拆分静态和动态路由表
// 省略其他...
// 动态路由表,项目中不同的用户可以访问不同的功能
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选项置空,作为默认渲染路由。
动态设置标题
方法
- 在
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}`
}
- 等待路由页面跳转完成后, 设置最后一个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变量