需要安装git和node
官方文档:https://panjiachen.github.io/vue-element-admin-site/zh/guide/
1.安装及目录
安装步骤
# 克隆项目
git clone https://github.com/PanJiaChen/vue-element-admin.git
# 进入项目目录
cd vue-element-admin
# 安装依赖
npm install
# 本地开发 启动项目
npm run dev
# 打包正式环境
npm run build:prod
# 打包预发布环境
npm run build:stage
目录文件
├── build // 构建相关
├── config // 配置相关
├── src // 源代码
│ ├── api // 所有请求
│ ├── assets // 主题 字体等静态资源
│ ├── components // 全局公用组件
│ ├── directive // 全局指令
│ ├── filtres // 全局 filter
│ ├── icons // 项目所有 svg icons
│ ├── lang // 国际化 language
│ ├── mock // 项目mock 模拟数据
│ ├── router // 路由
│ ├── store // 全局 store管理
│ ├── styles // 全局样式
│ ├── utils // 全局公用方法
│ ├── vendor // 公用vendor
│ ├── views // view
│ ├── App.vue // 入口页面
│ ├── main.js // 入口 加载组件 初始化等
│ └── permission.js // 权限管理
├── static // 第三方不打包资源
│ └── Tinymce // 富文本
├── .babelrc // babel-loader 配置
├── eslintrc.js // eslint 配置项
├── .gitignore // git 忽略项
├── favicon.ico // favicon图标
├── index.html // html模板
└── package.json // package.json
布局图片
2. 路由与侧导航
侧边栏和路由是绑定在一起的。 配置路由后会自动添加到侧导航。如果不需要测导航,需要到Layout文件的文件中修改源码
配置项举例
{
path: '/permission',
component: Layout,
redirect: '/permission/index', //重定向地址,在面包屑中点击会重定向去的地址
hidden: true, // 不在侧边栏线上
alwaysShow: true, //一直显示根路由
meta: { roles: ['admin','editor'] }, //在根路由设置权限,下面的子路由都继承了这个权限
children: [{
path: 'index',
component: ()=>import('permission/index'),
name: 'permission',
meta: {
title: 'permission',
icon: 'lock', //图标
role: ['admin','editor'], //或者你可以给每一个子路由设置自己的权限
noCache: true , // 不会被 <keep-alive> 缓存
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
}
}]
}
路由种类:constantRoutes和asyncRoutes
export const constantRoutes = [ //代表那些不需要动态判断权限的路由,如登录页、404、等通用页面。
{
path: '/redirect',
component: Layout,
hidden: true,
children: [
{
path: '/redirect/:path*',
component: () => import('@/views/redirect/index')
}
]
},
];
export const asyncRoutes = [ //代表那些需求动态判断权限并通过 addRoutes 动态添加的页面。
{
path: '/permission',
component: Layout,
redirect: '/permission/page',
alwaysShow: true,
name: 'Permission',
meta: {title: 'Permission',icon: 'lock',roles: ['admin', 'editor']
},
children: [
{
path: 'page',
component: () => import('@/views/permission/page'),
name: 'PagePermission',
meta: {title: 'Page Permission',roles: ['admin'] }
}
]
},
]
3. 路由页面权限
- 验证流程:
提交账号密码——返回token(存储)——请求获取用户信息(userInfo)——得到用户名称,头像,roles等(存储)——通过roles动态生成路由并添加
主要涉及登录流程文件夹:
router/index.js(封装路由)
store/index.js (建立vuex实例和相关导入模板)
store/getters.js(使用getter获取store数据)
store/modules /user.js (进行发送登录请求等及存储vuex及cookie)
api/user.js (封装好的登录请求,获取用户信息请求,退出登录请求等)
store/modules/permission.js (进行路由筛选判断等。生成动态路由)
permission.js ( 包含全局路由导航钩子router.beforeEach(),也就是添加路由的操作)
- 点击提交:
- 进行登录请求,存储token (store/modules /user.js)
- 获取用户信息请求及动态生成路由
生成相关路由判断文件(store/modules/permission.js)
//permission.js
import { asyncRoutes, constantRoutes } from '@/router' //导入路由两个路由数组
function hasPermission(roles, route) {// 判断路由是否包含roles
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
export function filterAsyncRoutes(routes, roles) { // 判断逻辑
const res = []
routes.forEach(route => { // 循环动态添加的路由钩子
const tmp = { ...route }
if (hasPermission(roles, tmp)) { // 判断路由是否满足roles
if (tmp.children) { // 有子路由判断子路由
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => { // 添加路由
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) { // 超级管理员左右路由都可看
accessedRoutes = asyncRoutes || []
} else { // 其它权限进行判断
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
添加路由的文件(permission.js)
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
NProgress.start()
document.title = getPageTitle(to.meta.title)
const hasToken = getToken();//判断用户是否登录,获取token。
let flag = 0;
if (hasToken) {
if (to.path === '/login') { // 有token且路由为login
next({ path: '/' })
NProgress.done()
} else {
const hasGetUserInfo = store.getters.name
if (hasGetUserInfo) { // 本地储存有用户名
next()
} else {//首次登录的情况下
try {
if (flag == 0) {
const { roles } = await store.dispatch('user/getInfo')
// 动态生成路由
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
router.addRoutes(accessRoutes)// 动态添加路由
router.options.routes = store.state.permission.routes;// 渲染侧导航
flag++;
next({ ...to, replace: true })
} else { // 解决页面刷新问题
next()
}
} catch (error) { // 重新登录
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {//没有token返回登录页,重新登录
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done()
})
4. 按钮级别权限
跟路由相似,我们在获取用户信息的时候获取当前用户借用的按钮标识码。每一个按钮都有标识。
将路由存在store中,在对页面按钮进行判断。
推荐地址:https://blog.csdn.net/acoolper/article/details/97375142
5. 引入插件(echarts,百度地图)
1.Echarts
官方文档:https://www.echartsjs.com/examples/zh/index.html
//全部引入
var echarts = require('echarts')
// 按需引入 引入 ECharts 主模块
var echarts = require('echarts/lib/echarts')
// 引入柱状图
require('echarts/lib/chart/bar')
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')
//使用
template:
<div id="barchart1" class="echarts"></div>
js:
this.barchart1 = echarts.init(document.getElementById('barchart1'));
this.barchart1.setOption({ 配置})
2.百度地图(vue-baidu-map)
官方文档:https://dafrok.github.io/vue-baidu-map/#/zh/start/installation
//安装
$ npm install vue-baidu-map --save
bgcolor=#000322
//全局引用
import BaiduMap from 'vue-baidu-map'
Vue.use(BaiduMap, { // ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
ak: 'YOUR_APP_KEY'
})
//引用(建议按需引用)
import BaiduMap from 'vue-baidu-map/components/map/Map.vue'
import BmScale from 'vue-baidu-map/components/controls/Scale'
import BmNavigation from 'vue-baidu-map/components/controls/Navigation'
import BmGeolocation from 'vue-baidu-map/components/controls/Geolocation.vue'
import BmMarkerClusterer from 'vue-baidu-map/components/extra/MarkerClusterer'
import BmMarker from 'vue-baidu-map/components/overlays/Marker'
import BmInfoWindow from 'vue-baidu-map/components/overlays/InfoWindow'
export default {
data () {
return {
center: {lng: 0, lat: 0},
zoom: 3
}
},
components: { //注册组件
BaiduMap,
BmScale,
BmNavigation,
BmGeolocation,
BmMarkerClusterer,
BmMarker,
BmInfoWindow,
},
methods: {
handler ({BMap, map}) {
console.log(BMap, map)
this.center.lng = 116.404
this.center.lat = 39.915
this.zoom = 15
}
}
}
//组件使用使用
<baidu-map :center="center" :zoom="zoom" @ready="handler" ak="开发密钥" scroll-wheel-zoom="true">
<!--比例尺控件-->
<bm-scale anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-scale>
<!--缩放控件-->
<bm-navigation anchor="BMAP_ANCHOR_BOTTOM_RIGHT" ></bm-navigation>
</baidu-map>
注意:
1.BaiduMap 组件容器本身是一个空的块级元素,必须定义高度。
2.没有设置 center 和 zoom 属性的地图组件是不进行地图渲染的。
3.在组件的 ready 事件执行地图 API 加载完毕后才能执行的代码,不要在 vue 自身的生命周期中调用 BMap 类,更不要在这些时机修改 model 层。
6. 环境变量
主要用于不同环境下公共变量的配置,比如接口路径,下载文件地址等
admin这个框架默认就是cli3。以下扩展一下cli2的方法
1. 环境变量
- Cli2:
首先需要安装:cnpm i -D cross-env
或npm i -D cross-env
然后配置不同打包指令变量值:在prod.env.js中:
配置打包的指令:在package.json中:
这样使用 npm run build:test则对应变量是test的变量值。 npm run build为默认设置的变量值
- Cli3:
添加不同模式的环境文件:.env # 在所有的环境中被载入 .env.[mode] # 只在指定的模式中被载入。如.env.staging文件
.env后的模式将用于package.json中打包指令所指向的模式文件。development模式是用于本地开发
环境变量必须以VUE_APP_为开头。创建变量:VUE_APP_WEBPACK_PATH='ws://XXX.com/socketServer.do' 获取:console.log(process.env.VUE_APP_WEBPACK_PATH)
项目中有两个特殊变量:
NODE_ENV - 是 "development"、"production" 或 "test" 中的一个。具体的值取决于应用运行的模式。
BASE_URL - 会和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径。