vue-cli 搭建后台管理框架(2022-11-22更新)
提示:直接复制地址跳转即可,现已更新到 vue-admin2.0版本(需要配合vue-admin2.0-node使用,否则无法正常运行)
vue-cli-manager为老版本,已经脱离时代,vue-admin2.0的请求,路由,vuex等已做好基础框架搭建
文章目录
码云下载链接 : https://gitee.com/hao_yu_feng/vue-cli-manager
码云下载链接 : https://gitee.com/hao_yu_feng/vue-admin2.0.git
码云下载链接 : https://gitee.com/hao_yu_feng/vue-admin2.0-node.git
思路
先跑项目,然后安装UI框架,然后安装一些乱七八糟的插件,那么既然是后台管理系统,那么首先就需要把路由交给后端,前端再渲染,也就是所谓的动态路由,然后就是…就没了,和平时没什么两样,不要和我说什么vuex,我用不着,一刷新就没的玩意要他干啥,有人说了,你用持久化插件不行吗?持久化插件的原理还是把值存到到localstorg里或者sessionstorg,那我直接存localstorg里他不香吗?要vuex干嘛,而且我再创建一个js文件,然后再main.js里引用,然后把值写进去,不也是全局的吗?是不是和vuex很相似?
但是我一直很想不通为什么要用动态路由,所谓的动态路由就是根据当前登录角色的不同来控制不同的目录列表,那你直接创建n多个路由表,然后根据上面说的方法存起来,然后登录的时候再把对应的路由表使用this.$router.addRoutes(obj)加进去效果不也一样吗?那有人说了,我们这能动态添加路由,然后还能控制哪个页面不出现,这样的话后端是不是得改?那后端改了,前端不改吗?到头来还是都要改,而且你vue项目不是打包上线的吗,编译后你也看不到源码,不也一样吗?
提示:以下是本篇文章正文内容,下面案例可供参考
介绍
一个简单的后台管理框架,用户输入的信息会保存在localstorg中,以此来判断是否登录过,然后路由的话是交给后端保存的,一个是promission.js里面的,另一个是login.js里面的,然后封装了一些工具类(common文件夹)
一、准备工作
1.1 目录结构
这里就是api文件夹下面的js文件
/**
* 用户列表接口
* @param schoolId //学校ID
* @param sysPhone //用户手机号
* @param roleId //用户权限id
*/
userList: function ({
schoolId,
sysPhone,
roleId
}) {
return Axios.get(base.base + "/user/k12main/sysUser/listPCUser", {
params: {
schoolId: schoolId,
sysPhone: sysPhone,
roleId: roleId
}
});
},
用的时候 直接 引入接口js
import YUapi from '../../../apis/YUapi'
直接别名加接口函数名
YUapi.symptomsInsert({参数,因为我接口那里是用的对象接收,这里夜用对象传})
.then((res) => {
console.log(res)
if (res.data.code == 200) {
} else {
}
})
.catch((err) => {
})
router 文件夹
- _import_development.js
module.exports = file => require('@/page/' + file + '.vue').default
- _import_production.js
module.exports = file => () => import('@/page/' + file + '.vue')
注意,这里的@/page/对应着
这个文件夹名,而且所有页面都要放在page下(不包括组件,不包括组件,不包括组件)
3. router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
var constantRouterMap = [
{
path: '/login',
component: () => import('@/page/login'),
// component: 'page/',
name: 'login',
}
]
export default new Router({
routes: constantRouterMap
})
直接把路由定义成数组,/login路由肯定是前端直接写死的,而且404页面也得让后端返回,不要问我为什么,问就是不登录的情况下,不管你在浏览器输入什么路由,统统跳登录页,就算你输入404也给我来登录页
4.promission.js
import router from './router'
import axios from 'axios'
const _import = require('./router/_import_' + process.env.NODE_ENV) //获取组件的方法
const whiteList = ['/login', '/auth-redirect'] // 不需要重定向的路有名称
var getRouter //用来获取后台拿到的路由
// 假装fakeRouter是通过后台接口请求回来的数据
let fakeRouter = {
"router": [{
path: '/index',
component: 'index',
name: 'index',
}, {
path: '/item',
component: 'item',
name: 'item',
}, {
path: '/404',
component: '404',
name: '404',
}, {
path: "*",
redirect: "/404"
}]
}
function routerGo(to, next) { //路由跳转
getRouter = filterAsyncRouter(getRouter) //过滤路由
router.addRoutes(getRouter) //动态添加路由
global.antRouter = getRouter //将路由数据传递给全局变量,做侧边栏菜单渲染工作
next({
...to,
replace: true
})
}
function saveObjArr(name, data) { //localStorage 存储数组对象的方法
localStorage.setItem(name, JSON.stringify(data))
}
function getObjArr(name) { //localStorage 获取数组对象的方法
return JSON.parse(window.localStorage.getItem(name));
}
function filterAsyncRouter(asyncRouterMap) { //遍历后台传来的路由字符串,转换为组件对象
const accessedRouters = asyncRouterMap.filter(route => {
if (route.component) {
route.component = _import(route.component)
}
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
return accessedRouters
}
router.beforeEach(async (to, from, next) => {
//获取用户登录的token,或者其他用户信息
const hasToken = window.localStorage.getItem('user')
if (hasToken) { //判断
if (to.path === '/login') {
// 如果登录过了,直接到首页
next({
path: '/index'
})
} else { //没登录走这个
if (!getRouter) {
//getRouter 用来获取后台拿到的路由 不加这个判断,路由会陷入死循环,不要问我为什么
//问就是 一直routerGo,一直走判断,然后一直routerGo,一直走判断
if (!getObjArr('router')) { //如果localStorage没router 这个字段的话
getRouter = fakeRouter.router //假装模拟后台请求得到的路由数据
//真实情况下,请求接口拿路由
saveObjArr('router', getRouter) //存储路由到localStorage
routerGo(to, next) //执行路由跳转方法
} else { //从localStorage拿到了路由
getRouter = getObjArr('router') //拿到路由
routerGo(to, next) //直接走
}
} else {
next() //拿到就直接走
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) { //如果不写这个,会报什么栈溢出,反正就是死循环
next()
} else {
next('/login')
}
}
})
- main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue' //这不管用
import App from './App' //这不管用
import router from './router' //这不管用
import ElementUI from 'element-ui'; //element 框架
import util from '@/common/util' //工具类
import echarts from 'echarts' //百度echert
import './promission.js' //那个js
import 'babel-polyfill' //解决es6语法
import 'element-ui/lib/theme-chalk/index.css'; //element样式
import '../src/style/index.scss' //覆盖element的样式文件
import Swiper from "swiper"; //Swiper
Vue.prototype.$echarts = echarts //使用echarts
Vue.config.productionTip = false //不知道干嘛的
Vue.use(ElementUI); //使用ElementUI
Vue.use(util); //使用util
Vue.prototype.setCache = function (key, value) { //设置缓存
localStorage.setItem(key, JSON.stringify(value))
}
Vue.prototype.getCache = function (key) { //获取缓存
return JSON.parse(localStorage.getItem(key))
}
Vue.prototype.removeCache = function (key) { //删缓存
localStorage.removeItem(key)
}
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {
App
},
template: '<App/>'
})
1.2、其他文件
- 404.vue (报错页面)
3. index.vue(首页)
4. item.vue(退出登录页面)
5. login.vue(登录页面)
<template>
<div>
登录
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>登录</el-button
>
</el-form-item>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
ruleForm: {
name: '',
},
rules: {
name: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
},
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
// alert('submit!')
// console.log(this.ruleForm.name)
window.localStorage.setItem('user', this.ruleForm.name)
} else {
console.log('error submit!!')
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
},
},
}
</script>
<style scoped>
</style>
二.跑项目
2.1 看效果
没用户信息的时候,他是进不去的,只能看到登录页面
不管在路由里面怎么输入,他都会到登录页面
2.2测试
输入东西
localstorg里有东西了,因为我没写自动跳转函数,所以他不会走,那就手动输入路径
看着没问题,然后我们试试手动跳 login
不管怎么输入都会到index
点击退出登录,清空缓存
手动跳别的页面或者直接刷新,就会回到登录页
差不多框架就是这样
然后既然你能登录进来,那么菜单栏什么的自己拿到路由后,创建siderbar.vue(名字随便起),然后可以套上element或者自己写一个导航菜单(万能的for和if),然后再app.vue里引用,这里注意一下,父子路由,需要父页面上用< router-view >标签来展示子组件,所谓的父子路由就相当于多个app.vue和index.vue ,而且子组件的path前,一般不用加/,但是之前的项目不加不行,然后不知道问题在哪
总结
虽然没什么用,写写还是有好处的码云链接 : https://gitee.com/hao_yu_feng/vue-cli-manager