阅读 1034

vue 自定义系统流程【3】 路由及权限 -- 未完待续

路由及权限

一、初始化 及测试路由

  1. 安装 js-cookie

npm i js-cookie复制代码
  1. 工具类

  • ./utils/auth.js token 验证 【后面权限会用到,就一起增加了】

import Cookies from 'js-cookie'

const TokenKey = 'Admin-Token' //默认自定义 token

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}复制代码
  • ./utils/get-page-title.js 获取页头标题

import defaultSettings from '@/config/settings'
const title = defaultSettings.title || 'Vue Element Admin'
export default function getPageTitle(pageTitle) {
  if (pageTitle) {
    return `${pageTitle} - ${title}`
  }
  return `${title}`
}复制代码
  1. 在main.js 中引入 工具类

import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'复制代码
  1. 路由控制器 设置路由

  • ./src/router/index.js 继承【1】 的 index.js

  • 【增加】 登录页面路由、错误页面 404 401 路由

//staicRoutes 中增加
 {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },
  {
    path: '/404',
    component: () => import('@/views/error-page/404'),
    hidden: true
  },
  {
    path: '/401',
    component: () => import('@/views/error-page/401'),
    hidden: true
  },
  {
    path: '/',
    component: () => import('@/views/layout/index'),
    //hidden: true
  },复制代码
  1. 静态资源

  • 我把图片文件都拷贝到了

  • src\assets\images\errors/

  1. 模板

  • \src\views\error-page/401.vue

  • \src\views\error-page/404.vue

  • 修改401,404 图片文件路径 为上面的路径

@/assets/images/errors/xxx.xxx复制代码
  • 拷贝\src\views\login 文件夹

  • SocialSignin.vue 要在 wechatHandleClick(thirdpart) 和   tencentHandleClick(thirdpart) 下添加

console.log(thirdpart)
//否则可能 Esline 会提示 定义但是没有使用的错误复制代码
  1. 创建 ./premission.js 权限控制器

  • 这里面的设置标题,有一点问题,后面有机会再延伸开展,先挖坑

import router from './router'
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'

const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
	document.title = getPageTitle(to.meta.title)  //设置标题
	const hasToken = getToken() //获取token
	if (hasToken) {
		// console.log(hasToken)
		next()
	}else{
		if (whiteList.indexOf(to.path) !== -1) {
			// in the free login whitelist, go directly
			next()
		} else {
			// other pages that do not have permission to access are redirected to the login page.
			next()//暂时忽略
			// next(`/login?redirect=${to.path}`)
			// NProgress.done()
		}
	}
})复制代码
  1. 测试页面

  • 浏览器 测试 index.js 的各个页面

http://localhost:8080/login
http://localhost:8080/401 
。。。 
复制代码

二、控制权限 及 限定路由跳转

  1. 说明:

  • 这里面有2种思路。一种是传统类似 cms的,首页是可以访问的,但是 后台管理页面是另外的,那就涉及到多入口进入,也可以叫做不限制入口,这种适合综合网站,设置也比较复杂,暂时不展开。

  • 另外一种是 默认就限制入口的单入口进入,适合直接就是管理后台模板【当前使用这种】

  • 路由说明:所有的路由都由 getToken 获取 ,如果获取不到,则全部跳转到登录页面

  1. 跳转路由:router/index.js staticRoutes 下,最顶部增加

 {
    path: '/redirect',
    //component: Layout,
    hidden: true,
    children: [
      {
        path: '/redirect/:path(.*)',
        component: () => import('@/views/redirect/index')
      }
    ]
  },复制代码
  1. 拷贝跳转页面 模板: src/views/redirect

  2. 权限控制

  • permission.js 找到

if (whiteList.indexOf(to.path) !== -1) {
			// in the free login whitelist, go directly
			next()
} else {
。。。 
 
复制代码
  • else 部分改为

next(`/login?redirect=${to.path}`)复制代码
  1. 测试一下

  • 浏览器进入网址,最终都会跳转到 http://localhost:8080/login?redirect=/xxx

http://localhost:8080复制代码
  1. NProgress 进度条

三、axios

  1. 安装

  • axios 网络请求 ajax

npm i axios复制代码

四、Vuex 状态管理模式 v4.x 【权限配置相关】

  • 整体控制都在 permission.js 里面 router.beforeEach(async(to, from, next) => { 中进行

  • 提示:浏览器 的 websocket 栏,可以查看错误信息

  1. 安装

  • 文档 vuex.vuejs.org/zh/

npm i vuex@next复制代码
  1. 新建 状态文件夹  src/store

  • 复制 store/getter.js

  • store/index.js 引入 vuex

  • 新写法如下

import { createStore } from 'vuex'
import getters from './getters'

//模块文件夹
const modulesFiles = require.context('./modules', true, /\.js$/)
//解析模块
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

export default createStore({
	modules,
	getters
})复制代码
  1. /src/main.js 中全局引入

  • 官网示例:github.com/vuejs/vuex/…

import store from './store'
。。。
const app = createApp(App)
app.component('svg-icon', SvgIcon).use(ElementPlus).use(router).use(store).mount('#app')复制代码

4 ./src/permission.js 中引入

  • 新写法

import { useStore } from 'vuex'
import getters from './getters'

//模块文件夹
const modulesFiles = require.context('./modules', true, /\.js$/)
//解析模块
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

export default {
	setup () {
		const store = useStore({
			modules,
			getters
		})
		return store
	}
}复制代码
  1. /src/router/index.js

  • 找到 export default router

//在 上面添加 :重置路由函数
const router = createRouter({
  history: createWebHistory(),
  // scrollBehavior: () => ({ y: 0 }),
  routes: staicRoutes
})复制代码
  1. \src\store\modules/user.js 用户状态管理

  • 拷贝

  1. ENV 环境变量文件

  • 全局根目录下,新建 /.env.development

  • 主要定义了当前 ENV 的类型以及 VUE_APP_BASE_API 【ajax路径】

  • 后面还有其他的env ,先挖坑

  1. /utils/request.js 请求工具

  • axios 请求 都在这里发出

  1. 创建 src/api 文件夹 所有接口文件夹

  • 在这里引入了request.js

  • api/user 暂时直接考过去

  1. 这时候 打开控制台,测试一下登录,然后发现后台console 请求失败,说明前面步骤已经测通,准备开始下一步

errError: Request failed with status code 404复制代码
  1. 剩余的几个文件暂时不考过去【继续挖坑】

流程说明

  1. 实现流程

- src/views/login/index.vue 中
- 通过 handleLogin() {	
- 访问状态 this.$store.dispatch('user/login', this.loginForm)
- 在 store/modules/user.js 中调用 api/user.js 的 login方法
- 进行提交 login复制代码
  1. 流程解析

  • 这时候重新看刚才的第9步的问题:

- 浏览器 刚才那个登录页面,console 打开,查看 network 部分,login是红色,点击后查看 右侧 header
- Request Url:http://localhost:8080/dev-api/vue-element-admin/user/login 这个就是请求的地址
- 其实是由 env 和 api 拼接的。复制代码
  1. 延伸阅读

  • 如果在路由 router/index.js 中把刚才那个 链接 加进去设置的话

/dev-api/vue-element-admin/user/login复制代码
  • 是可以访问的,但还是不能进行post,还是会 一样出现404

  • 原因是什么?

  • 因为 进行POST 请求的是外站【也就是后端】,而路由配置的都是本站,也就是前端请求。

  • 具体的解释是什么?继续挖坑。。。以后补上

五、搭建 本地虚拟测试服务器 mockjs

  • 为了模拟后台数据及接口

1. 安装

npm i -D mockjs复制代码

2. 引入 mockjs 的使用

  • 进入 vue.config.js devServer 属性

  • 增加如下

before: require('./mock/mock-server.js')复制代码

3.自建 mockjs server

  1. 根目录 创建  mock 文件夹

  • 以下创建的.js 文件 或 文件夹 全部都在 mock 文件夹内

  1. 创建 工具类 utils.js

复制代码
  1. 创建 mock-server.js【服务器】 文件

  2. 创建 index.js【入口】文件

  • 拷贝过去就好了

  • 先注销跟 article、search 相关的语句

复制代码
  1. 创建 user.js 用户文件【拷贝】

  • 模拟请求访问后得到的用户数据

  1. 这时候 重启启动服务器

  • 点击登录后 发现会跳转了

  • 如果 url 只是指向 login 的话,就完成登录,会跳到  路由设置的 ‘/’ 首页中

  • 如果还有别的指向,则跳转到之前设置的 页面中

4. 完成路由及权限控制

  • 接下来完成 之前的权限路由 src/permission.js

- 之前的路由已经实现没有权限,除登录外,全部跳转到登录页面
- 现在还要实现,有权限的情况下,登录页面 直接跳到首页
- 有权限,但是没有路由的话,跳到404复制代码
  • 提示:如果想要明显的看出效果,可以在 if (hasToken) { 里面 加上,你就知道权限在哪里了

alert('23')复制代码
  1. /src/router/index.js 增加 特殊权限路由

  • 原本的 constantRoutes、asyncRoutes 我改为 staicRoutes、rolesRoutes 我觉得更直观点。一个是静态路由,不需要权限的,一个是权限路由

  • 如果改这两个名字的,permission.js 的第一行导入 要记得换成一样的

export const rolesRoutes = [
  {
	path: '/permission',
    component: Layout,
    redirect: '/permission/page',
    alwaysShow: true, // will always show the root menu
    name: 'Permission',
    meta: {
      title: 'Permission',
      icon: 'lock',
      roles: ['admin', 'editor'] // you can set roles in root nav
    },
    children: [
      {
        path: 'page',
        component: () => import('@/views/permission/page'),
        name: 'PagePermission',
        meta: {
          title: 'Page Permission',
          roles: ['admin'] // or you can only set roles in sub nav
        }
      },
      {
        path: 'directive',
        component: () => import('@/views/permission/directive'),
        name: 'DirectivePermission',
        meta: {
          title: 'Directive Permission'
          // if do not set roles, means: this page does not require permission
        }
      },
      {
        path: 'role',
        component: () => import('@/views/permission/role'),
        name: 'RolePermission',
        meta: {
          title: 'Role Permission',
          roles: ['admin']
        }
      }
    ]
  },
// 404 page must be placed at the end !!!
  { path: '*', redirect: '/404', hidden: true }
]复制代码
  1. 权限控制 src/permission.js

复制代码
  1. 创建 role 文件夹 【权限访问模拟】

  • role/index.js 用户文件【拷贝】

  • 模拟请求访问后得到的用户数据

  1. /store/modules/permission.js

  • 1步设置的 accessRoutes,最终获取到这里,用于判断是否在 【有权限的状态】

  1. redirect 的跳转的路由

  • 增加 @/directive/permission/index.js' // 权限判断指令

  • @/utils/permission' // 权限判断函数

  • 'views/permission/components/SwitchRoles'

  1. 接口

  • src/api/role.js

  • src/api/user.js

  1. 工具

  • /utils/index.js

  1. src\views\permission

  • role.vue

- role.vue 中部分修改
slot-scope  全部改为 v-slot复制代码
  • 示例

//原
<template slot-scope="scope">
  {{ scope.row.key }}
</template>

//改为
 <template v-slot="{scope}">
  {{ scope.row.name }}
</template>复制代码

    • role.vue

29 行 :visible.sync= 改为
v-model=复制代码
  • 到了这一步,总觉得路由和权限这块还是没说清楚,而且总觉得有点太繁琐了。

  • 虽然这个是最重要的地方,但是觉得还是有点绕圈圈。有空再重新做一下

六. 框架填充及路由的深度优化

1. 框架填充

  1. 增加 前台模板框架

  • 原本的layout文件夹 vue-element-admin\src\layout\components

  • 拷贝到 views\layout\components

  1. 拷贝控制台模板 src\views\dashboard

  2. /router/index.js 修改

  • asyncRoutes 增加路由

复制代码

2. 拷贝 \src\layout\mixin

  • 主要用于防抖

  • 参考 blog.csdn.net/zcc900726/a…

3. 拷贝组件 [\src\components]

  • Breadcrumb 面包屑导航

  • ErrorLog 错误日志

  • HeaderSearch 页头搜索

  • RightPanel 右侧栏

  • ScreenFull 全屏

  • SizeSelect 尺寸选择?

  • ThemePicker 模板选择

  • Hamburger ?

4. 安装 依赖

  • vue-count-to 计时器?

  • echarts 表格样式?

  • screenfull 全屏

  • fuse.js

npm i vue-count-to
npm i echarts
npm i screenfull
npm i fuse.js复制代码

5. 模板填充 及 修改vue

  1. 复制vue

  • src\views\dashboard\admin\components/BarChart.Vue

  • beforeDestroy.vue 改 beforeUnmount【问题10】

  • boxCard.vue slot 改 :v-slot 【问题5】

  • LineChart.vue、PieChart.vue beforeDestroy 改 beforeUnmount

  • views\dashboard\admin\components\TodoList\index.vue 这个改动的比较多 主要是filter 废除 还未解决

  • views\dashboard\admin\components\TransactionTable.vue 这个改动的比较多 主要是filter 废除 还未解决

  • src\api/remote-search.js

  • \src\components\GithubCorner

  • \src\components\PanThumb

  • \src\components\TextHoverEffect

  1. 修改 新版本echart 引入【问题11】

  • PieChart.vue

  • LineChart.vue

  • RaddarChart.vue

  • BarChart.vue

- import echarts from 'echarts'
- 改为
import * as echarts from 'echarts'复制代码
  1. index.vue

  • 之前测试的那个可以去掉了,改成现在的了

  • 拷贝 layout/index.vue 过去

line 61 @import "~@/styles/mixin.scss"; => @import "~@/res/styles/mixin.scss";
line 62 @import "~@/styles/variables.scss"; => @import "~@/res/styles/variables.scss";复制代码
  1. \src\views\layout\mixin\ResizeHandler.js

line 8 暂时增加  console.log(route)复制代码

6. 修改组件模板 vue 【\src\views\layout\components\】

  1. Sidebar\index.vue

line25 import variables from '@/styles/variables.scss' => import variables from '@/res/styles/variables.scss'复制代码
  1. Navbar.vue

1. slot => :v-slot
2. @click.native => v-on:click复制代码
  1. Sidebar\SidebarItem.vue

slot => :v-slot复制代码
  1. TagsView\ScrollPane.vue

line2: @wheel.native.prevent => v-on:prevent
line25:  beforeDestroy => beforeUnmount复制代码
  1. TagsView\Index.vue

line12:@click.middle.native => v-on:click
line13:@contextmenu.prevent.native => v-on:prevent复制代码
  1. ThemePicker\Index.vue

11 const version = require('element-ui/package.json').version // element-ui version from node_modules
- 改为
const version = require('element-plus/package.json').version // element-ui version from node_modules复制代码
  1. ErrorLog\index.vue

line 3 @click.native => v-on@click
line 9 :visible.sync => :v-bind:visible
line 10. slot => :v-slot
line 16. slot-scope => v-slot复制代码
  1. \RightPanel\index.vue,Screenfull\index.vue

beforeDestroy => beforeUnmount复制代码
  1. SizeSelect\index.vue

line 6 slot => :v-slot复制代码
  1. ThemePicker\index.vue

line 28 handler: function(val, oldVal) {
- 暂时修改 :增加 console.log(oldVal)复制代码

七、状态管理

  • 之前挖的 那个 store 文件夹的文件坑,现在来补上

  1. 拷贝

  • 把app.js/errorLog.js/setting.js/tagView.js 考过去

  1. 修改

  • setting.js

line1 import variables from '@/styles/element-variables.scss' => import variables from '@/res/styles/element-variables.scss' 
line2 import defaultSettings from '@/settings' => import defaultSettings from '@/config/settings'复制代码
  • /src/res/styles/element-variables.scss

line 23 : $--font-path: "~element-ui/lib/theme-chalk/fonts"; => $--font-path: "~element-plus/lib/theme-chalk/fonts";
line 25 : @import "~element-ui/packages/theme-chalk/src/index"; => @import "~element-plus/packages/theme-chalk/src/index";复制代码
  • 【暂时】把assets\custom-theme/fonts 文件夹 考入 src\res\styles 下面

七点五、半途小记

  • 做到这里,发现页面不显示了,应该是其他的component 没有拷贝进来,发现的问题也越来越多了。文档有时候都来不及写了,因为边写边码实在是太慢了。有时候解决完几个问题了,又忘记写记录了。。。

  • 只好放在最后复盘的时候再来吧

  • 之前的路由 router.js 中 那个 静态权限和必要权限 的 变量名,我还是改回去了,constantRoutes 和 asyncRoutes,因为后面有部分地方需要用到。暂时还是先完成升级,再来处理这个问题吧。

  • 【3】不知不觉写的有点多了,估计很多都可以放到【4】去写。。。但是感觉还差一些,而且也得放到【3】中。那就继续吧。

八、component 的文件补充

  1. 问题分析

  • 登录后 console 出现 vue 的警告问题【问题12】、【问题13】,并且页面显示空白

  • 初步分析是因为路由有写,但是 component 没有拷贝过来。

  • 这样就不是 error 型的错误,不需要检查前面的框架进入流程错误。而是属于 warm 警告类的错误,检查页面模板就可以

  • 看错误主要是出在子菜单上面

  1. 【问题13的解决】结果:

  • 找了半天,始终无法解决。后来发现自己的思路错了,去翻了一下 element-plus 的文档。问题也很简单。。。element-plus 和 element-ui 的部分代码不一样。。。

  • el-submenu 【2.x】 =》 el-sub-menu

  1. 【卡在 问题14 Unhandled error during execution of render function】 上面了,好像很多人都是卡在这里。。

  • 我也无奈了,只能等更新完了再继续了。。

九、后记

  • 写到这里我决定暂停一下了。实在看不出问题在哪里。。。我决定去啃文档了。

  • 之前写的几篇,都没有做整理。以后完成了再来整理吧。当前还是得先去啃文档。

  • 暂停。。这算是大坑了吧~~~


问题

  1. 登录界面 index.vue

  • Missing required prop: "modelValue"

  • xtraneous non-props attributes (visible) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.

  • 问题原因:

  • blog.csdn.net/Zoroastrian…

  • 解决:

  • vue.config.js

configureWebpack 底下的
 module: {
			// rules: [ 
    全部注释掉就可以了
    - 似乎已经由vue 进行控制了,就不要在这里配置了复制代码
  1. vuex.esm-browser.js?5502:1012 [vuex] unknown action type: user/login

  • 一般是 store/index.js 的配置出错

  • 例如:检查这里

export default createStore({
	modules: {
		modules,
		getters
	},
})复制代码
  • 应该改为

export default createStore({
	modules,
	getters
})复制代码
  1. errError: Request failed with status code 404

  • mock.js 没有起作用,或者 request.js 的最终路由写错

  1. Cannot read property 'concat' of undefined

  • 部分 vue 没有加载

  1. slot-scope are deprecated

  • 插槽:v3 中的 slotslot-scope 改为 v-slot

  • 文档 v3.cn.vuejs.org/guide/compo…

  • 解决

//原写法
<div class="content">
    <slot name="contrite"></slot>
  </div>
//js
  <h1 slot="contrite" class="title">内容</h1>

//渲染结果
<div class="content">
    <h1 class="title">内容</h1>
</div>

//2.新写法
  <div class="content">
    <slot name="contrite"></slot>
  </div>
   <template v-slot:contrite>
        内容
   </template>
//可以简写
   <template #contrite>
        内容
   </template>
//渲染结果一致复制代码
  1. ::v-deep usage as a combinator has been deprecated. Use :deep() instead.

  2. [Vue Router warn]: Component "default" in record with path "undefined" is not a valid component. Received "undefined".

  3. [Vue Router warn]: uncaught error during route navigation:

  4. vue-router.esm-bundler.js?6c02:72 [Vue Router warn]: Unexpected error when starting the router: Error: Invalid route component

  • 94 行 directory v-deep 改为

  • 示例

//原
.parent ::v-deep .child {
   ...
}

//改为
.parent ::v-deep(.child) {
    ...
}复制代码
  • 到登录成功后的 无路由404

  1. The beforeDestroy lifecycle hook is deprecated. Use beforeUnmount instead

  • 照着改


  1. 引入echars5.0报错“export ‘default‘ (imported as ‘echarts‘) was not found in ‘echarts‘

  • 【解决】引入方式改为

import * as echarts from 'echarts';
// 或
const echarts = require('echarts');复制代码
  1. Cannot read property 'icon' of undefined

  • 估计问题在 router ,部分 component 没有引入

  • console 定位到错误 Proxy.render (Item.vue?b2c3:16)

  • 位于:\src\views\layout\components\Sidebar\item.vue

  1. Failed to resolve component: el-submenu

If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

  • 无法解析组件【el子菜单】

  1. Unhandled error during execution of render function 。。。

  • Unhandled error during execution of scheduler flush. This is likely a Vue internals bug.


作者:刺猬老爷
链接:https://juejin.cn/post/7022167007910952997


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐