开发条件:需要会vuex+vue-router
页面开发
.vue文件
<template>
// 页面dom渲染
</template>
<script lang="ts">
// 页面逻辑处理
</script>
<style>
// 页面样式
</style>
由登录页面起手
考虑因素
- 输入网址进入项目首页
- 在进入项目首页时候进行路由判断,看是否携带签名(即:检验是否可以免密登录)
- 有则直接展示
- 没有则跳转到登录页面
- 进行登录页面的编写(表单验证+防抖/限制提交)
- 用户信息托管给vuex去进行管理 (收录用户信息)
编写开始
1.创页面并在路由中注册
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import Index from '../views/index/index.vue'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Index',
component: Index,
redirect: '/dashboard',
children: [{
path: '/dashboard',
component: () => import('@/views/dashboard/index.vue'),
name: 'Dashboard',
meta: {
title:'XX后台管理系统'
}
}]
},
{
path:'/login',
name:'Login',
component: () => import('../views/login/index.vue'),
meta: {
title:'登录'
}
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
2.进行导航守卫的编写permission.ts
自行学习vue-router
// permission.ts
import router from '@/router/index';
// 导航守卫对路由跳转前进行处理
let whiteList = ['/login']
router.beforeResolve((to:any, from:any, next:any) => {
let token = ""; // 预留字段
document.title = to.meta.title; // 网页标题
if(token){
if(to.path === '/login'){
next('/')
}else{
// ...这里需要进行路由的重写权限配置
}
}else{
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
}
}
})
3.cookie的方法封装,也可以使用插件
// cookie.ts
/**
* 功能:全局存cookie
*/
export function setForeverCookie(name:string,value:string) {
var date =new Date()
if(value != null&&name !== null){
date.setTime(date.getTime()+12*30*24*60*60*1000)
document.cookie = name +"="+value+";path=/;expires="+date.toUTCString()
}
}
/**
* 说明:增加/修改会话cookie
*/
export function setCookie(name:string,value:string,time:number) {
var date =new Date()
if(time != undefined){
date.setTime(date.getTime()+time*1000)
document.cookie = name +"="+value+";expires="+date.toUTCString()
}else{
document.cookie = name+"="+value
}
}
/**
* 说明:删除cookie
*/
export function delCookie(name:string) {
var date =new Date()
if(name != null){
date.setTime(date.getTime()-1000)
document.cookie = name +"=null;expires="+date.toUTCString()
}
}
/**
*说明:获得cookie
*/
export function getCookie(name:string):string {
var arr = document.cookie.split(';')
var cookieValue = ''
if(name === "all"){
cookieValue = document.cookie
}else{
for(const i in arr){
if(document.cookie.split(';').join(',').split('=')[0] === name){
cookieValue = document.cookie.split(';').join(',').split('=')[1]
}
}
}
return cookieValue
}
4.axios进行一波封装
// request.ts
import axios from 'axios'
import { ElMessage } from 'element-plus'
import store from '@/store'
import { getCookie } from './cookie'
/**
* 说明:基于axios的请求封装
*/
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 60 * 2 * 1000
});
/**
* 说明:请求前拦截
* 功能:携带token
*/
service.interceptors.request.use(
(config) => {
if (store.getters.token) {
config.headers['token'] = getCookie('admin-token')
}
return config
},
(error:any) => Promise.reject(error)
)
/**
* 说明:响应拦截
*
*/
service.interceptors.response.use(
(response:any) =>{
if(response.data.errorCode === true){
ElMessage({
showClose: true,
message: response.data.resultMsg,
type: 'error'
});
}else if(response.data.retCode === true){
return response
}
}
)
export default service
5.进行login.vue编写
<template>
<div class="login flex-c-center">
<el-form :model="formData" :hide-required-asterisk="true" class="loginForm">
<el-form-item
prop="username"
:rules="[
{ required: true, message: '账号不能为空'},
]"
>
<el-input placeholder="请输入账号" v-model="formData.username" autocomplete="off">
</el-input>
</el-form-item>
<el-form-item
prop="password"
:rules="[
{ required: true, message: '密码不能为空'},
]"
>
<el-input placeholder="请输入密码" v-model="formData.password" show-password>
</el-input>
</el-form-item>
<el-form-item>
<div class="flex-r-between loginForm">
<el-button class="btn" type="primary" @click="submit">提交</el-button>
<el-button class="btn" @click="reset">重置</el-button>
</div>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts">
import { Vue , Options } from 'vue-class-component'
import {login} from './service'
@Options({
data(){
return{
formData : {
username:'',
password:''
}
}
},
methods:{
reset(){
this.formData.username = "",
this.formData.password = ""
},
submit(){
// ... 登录的逻辑我准备写在vuex里面
}
}
})
export default class extends Vue {
}
</script>
<style lang="scss">
.login{
width: 100%;
height: 100%;
background: linear-gradient(-32deg, #2246BE, #333333 50%, #ff3f00);
opacity: 0.8;
}
.loginForm{
width: 400px;
}
.btn{
width: 150px;
}
</style>
这里的标签类flex-c-center和flex-r-between是外部定义的。
对于页面的请求我是放在页面同级目录下的方便管理
// service.ts
import request from '@/utils/request'
// 登录
export const login = (data:any) => {
request({
url:'/userLogin',
method:'post',
data
})
}
axios的用法还是建议去官网看看axios
6.vuex的使用
首先确定需要进行管理的数据
- 用户信息的数据管理
- 权限业务衍生出的路由进行管理
思路整理
|permission.ts
|vuex.user
|获得用户权限信息
|vuex.permission
|router 获得路由
|接收传入的权限对路由进行筛选
|返回权限路由
// 路由权限配置在meta中的privs,用户直接获取privs然后做出判断
用户信息管理
用户对象起名:user,
其属性结合业务暂定为:
- name 名字
- headImg 头像
- role 角色
- privs 权限 这里直接结合模块化去使用,方便管理
// user.ts
import {login} from '@/views/login/service'
// user对象状态管理
const user = {
namespaced: true,
state:{
username:'',
token:'',
role:'',
privs:[]
},
mutations:{
SET_USER: (state:any,username:string) => {state.username = username},
SET_TOKEN: (state:any,token:string) => {state.token = token},
SET_ROLES: (state:any,role:string) => {state.role = role},
SET_PRIVS: (state:any,privs:string[]) => {state.privs = privs}
},
actions:{
setUser({commit}:any,data:any){
commit("SET_USER",data.username)
},
}
}
export default user
权限管理
权限设计思路:
|在路由注册时在meta中配入权限
|store.user中先给出模拟数据,及对应路由的读写权限
|store.permission中去根据用户权限进行筛选得到对应的路由
|根据筛选的路由进行分配展示路由以及注册路由
代码设计:
// user.ts
import { login,getInfo } from '@/views/login/service';
import { setForeverCookie,getCookie } from '@/utils/cookie';
// user对象状态管理
const user = {
namespaced: true,
state:{
username:'',
token:'',
role:'',
privs:[]
},
mutations:{
SET_USER: (state:any,username:string) => {state.username = username},
SET_TOKEN: (state:any,token:string) => {state.token = token},
SET_ROLES: (state:any,role:string) => {state.role = role},
SET_PRIVS: (state:any,privs:string[]) => {state.privs = privs}
},
actions:{
// 获得用户token
async setUser({commit}:any,data:any){
// let res = await login(data);
let res = {
data:{
token:"ajswiqkxindasdswwrt",
username:'admin',
}
}
if(res.data.token){
console.log('res',res.data.token)
setForeverCookie('token',res.data.token);
console.log('vuex',getCookie('token'))
commit("SET_USER",res.data.username);
commit("SET_TOKEN",res.data.token);
}
},
// 获得用户信息
async getInfo({commit}:any){
const token = getCookie('token');
// let res = await getInfo(token);
let res = {
data:{
role:'0',
privs:["QUESTION_LIST_WRITE","QUESTION_LIST_READ","QUESTION_CLASS_WRITE","QUESTION_CLASS_READ","ORDER_LIST_WRITE","ORDER_LIST_READ","ORDER_CLASS_WRITE","ORDER_CLASS_READ","GOODS_CLASS_WRITE","GOODS_CLASS_READ","GOODS_LIST_WRITE","GOODS_LIST_READ","QUESTION_CLASS_WRITE","QUESTION_CLASS_READ","QOURSE_LIST_WRITE","QOURSE_LIST_READ"]
}
}
commit("SET_ROLES",res.data.role);
commit("SET_PRIVS",res.data.privs);
}
}
}
export default user
// permission.ts
import { RouteRecordRaw,RouteMeta } from 'vue-router'
import { asyncRoutes,constantRoutes } from '@/router/index';
function screen(router:RouteRecordRaw[],privs:string[]):RouteRecordRaw[]{
let res:RouteRecordRaw[] = [];
router.forEach((item:RouteRecordRaw) => {
if(item.children){
item.children = screen(item.children,privs)
res.push(item)
}
// item.meta运行会报错,不知道咋解决可以通过ts配置文件"strict": false,但是这样不符合开发规范
let bo = privs.some((priv:string) => (<Array<string>>item.meta.privs).includes(priv))
if(bo){
res.push(item)
}
})
return res
}
// 权限对象状态管理
const permission = {
namespaced: true,
state:{
routers:[],
addRouter:[]
},
mutations:{
SET_ROUTERS: (state:any,routers:Array<RouteRecordRaw>) => {state.routers = routers},
SET_ADDROUTER: (state:any,addRouter:Array<RouteRecordRaw>) => {state.addRouter = addRouter},
},
actions:{
// 获得权限路由
async screenRouter({commit}:any,data:string[]){
let router = screen(asyncRoutes,data)
commit('SET_ADDROUTER',router)
commit('SET_ROUTERS',router.concat(constantRoutes))
}
}
}
export default permission
筛选过的权限就通过addRouter去注册到路由中就可以正常使用了
7.节流设置
思路:
|点击登录按钮后直接锁死登录按钮等待回调
登录编写完成
项目规划
|系统管理容器
|侧边栏
|navbar
|tagbar
|main