硅谷甄选

288 阅读4分钟

路由鉴权

  • 进度条(nprogress)
  • 如果用户已登录,访问登录页面(/login),则会自动跳转到首页(/)
  • 如果用户已登录且有用户名信息,放行除登录页面以外的其他路由。
  • 如果用户已登录但没有用户名信息,会等待用户信息获取成功后再放行路由。
  • 如果用户未登录,只能访问登录页面

二次封装axios

  • 跨域: vite中配置proxy changeOrigin:true

  • 自动加载变量 通过写多个配置文件

  • 请求拦截器 如果已登录,则在请求头中添加用户的 Token,以便服务器进行身份验证。

  • 响应拦截器中,处理服务器返回的响应。如果请求成功,返回响应数据;如果请求失败,根据 HTTP 状态码处理不同的网络错误(并且返回一个失败的promise对象)。

自定义插件注册全局组件

  • app.component是全局注册组件的方法
  • 二次封装icon组件 三级分类组件 Object.keys().forEach遍历
  • 对外暴露一个插件对象,通过install方法注册全局组件

添加属性值时编辑和查看模式的切换(nexttick) 难点

  • 准备一个数组,将来存储对应的组件实例el-input

  • 编辑模式是input,查看模式是div 通过v-if切换

  • input绑定blur事件,当失去焦点时,切换到查看模式 div绑定click事件,当点击时,切换到编辑模式

  • 问题:只解决了一个属性值模式的切换,而我们需要对每个属性值都设置这种功能,我们在attrValue中增加flag属性,每一个row都有一个flag属性,用于判断当前是编辑模式还是查看模式

  • 点击添加属性值时,push一个valueName为空的对象,flag值为true 利用nextTick聚焦在最后一个input上

  • 细节:切换为查看模式时 为空时删除 重复时删除(使用find)

问题:修改属性后点取消 但是属性还是显示在页面上 因为操作的是同一个对象也 就是当我们修改属性值后,并没有保存(发请求),但是界面还是改了。这是因为我们的赋值语句:Object.assign(attrParams, row)是浅拷贝。相当于我们在修改服务器发回来的数据并展示在页面上。服务器内部并没有修改。

登录业务相关

  • token持久化:我们把它在localStorage中存储起来,这样即使刷新页面,也能从localStorage中获取到token,从而实现自动登录,pinia中的token我们从localStorage中获取
  • 点击登录按钮后,通知仓库进行登录操作,登录成功后,跳转到首页
  • 体验优化:点击按钮的加载效果 ElNotification通知提示

刷新操作 (watch nexttick )

  • settings组件和main组件属于兄弟组件,不好传值,我们可以通过在仓库中定义refresh属性,然后在settings组件中修改refresh属性的值,从而触发main组件中的watch监听函数,从而实现刷新操作。v-if = “flag”

递归组件生成动态菜单 难点

  • 在路由元信息中添加(icon title hidden)属性,用于生成菜单
  • 遍历路由数组,放在用户小仓库中,分为三种情况,前两种分别判断子路由情况和hidden,其中有不止一个子路由的路由,我们需要递归调用菜单组件,传入item.children作为参数,这样就可以生成多级菜单了。

菜单权限的实现 路由拆分 难点

  • 操作在获取用户信息成功后进行
  • 后台传过来的信息有Routes参数,表示该用户可以访问的所有菜单权限,我们根据已经定义好的异步路由把它筛选出来,如果有子路由,我们需要递归调用,把item.children的值赋为filterAsyncRoute(item.children, routes) 这需要我们对asyncRoutes进行深拷贝,否则会修改原数组
  • 设置菜单需要的路由 顺序依次为 常量路由 筛选后的异步路由 404页面
  • 遍历后两个部分添加到路由中 router.addRoute(route)
  • 在路由前置守卫中next({..to}) 如果参数to不能找到对应的路由的话,就再执行一次beforeEach((to, from, next)直到其中的next({ ...to})能找到对应的路由为止。确保添加的异步路由已经生效

按钮权限实现

  • 通过自定义指令实现按钮权限的控制
  • 后端返回一个buttons 获取用户应有的按钮 存在用户仓库中
  • app.derective实现全局自定义指令 mounted表示挂载时自动执行一次 el是dom对象 options是指令的参数 自定义指令右侧的值 不包含的话移除dom el.parentNode.removeChild(el)

细节

  • onBeforeUnmount 组件销毁前 把仓库中三级分类的数据清空 $reset