如何使用Egg.js快速搭建一个简单完整的后台管理系统
最近在学习Egg.js,它是阿里推出的基于Koa的node开发框架,是为企业级框架和应用而生;它简单且扩展性强,非常适合做个人项目。
原文参考:https://blog.csdn.net/weixin_41967475/article/details/108712277
一、egg创建项目
1.要求nodejs版本必须大于8.0并且要用LTS版本
2.全局安装egg的环境(只需安装一次)
npm i egg-init -g / cnpm i egg-init -g
3.创建项目
- cd 到目录里面(注意目录不要用中文,不要有空格)
- 创建项目:egg-init 项目名称 --type=simple ;然后一直回车即可
如:egg-init eggdemo --type=simple - cd eggdemo
- cnpm install / npm install


4.运行项目
npm run dev / cnpm run dev

二、router和 controller 分组
1. router分组
- 在app文件夹下,新建router文件夹,且在router文件夹里面再新建admin.js文件,以后主要在admin.js文件里写后台接口;如:
'use strict';
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.get('/admin', controller.admin.main.index);
router.get('/admin/login', controller.admin.login.index);
router.post('/admin/doLogin', controller.admin.login.doLogin);
router.get('/admin/loginOut', controller.admin.login.loginOut);
};
2. controller分组
在controller文件夹下,新建admin、api两个文件夹,以后主要就在admin文件里写后台系统内容,api文件里写前台内容
三、egg模板引擎的配置
1.egg 安装 ejs模块
cnpm install egg-view-ejs --save
2.配置模板引擎模块 >> config/plugin.js
// 第三方的ejs 模板引擎的引入
ejs: {
enable: true,
package: 'egg-view-ejs',
}
3.设置后缀 .html(默认 .ejs) >> config/config.default.js
// 配置模板引擎
config.view = {
mapping: {
'.html': 'ejs',
},
};
4.在app文件夹下,新建一个view文件夹,以后就在view文件夹下存放后台管理系统视图模板
四、egg-mongoose 模块的配置
1.安装egg-mongoose模块
cnpm install egg-mongoose --save
2. config/plugin.js下的配置
mongoose: {
enable: true,
package: 'egg-mongoose'
}
3.config/config.default.js 下的配置
//配置mongoose连接mongodb数据库
//eggdemo为我在mongodb数据库创建的表
exports.mongoose = {
client: {
url: 'mongodb://127.0.0.1/eggdemo',
options: {},
}
};
4.在app文件夹下新建model文件夹,用来存放相关的集合映射
五、在mongodb中创建admin表
1.mongodb 数据中创建 eggdemo 数据库(use eggdemo)
2.新增admin集合
注:“e10adc3949ba59abbe56e057f20f883e” 是“123456”通过md5加密后得到
db.admin.insert({username:'admin',password:'e10adc3949ba59abbe56e057f20f883e'})

六、cors跨域
安装egg-cors
npm install egg-cors --save
此时可能会报错,“egg-bin”不是内部或外部命令…
解决方法:卸载node_modules,重新cnpm install
配置egg-cors
config/plugin.js下配置:
cors: {
enable: true,
package: 'egg-cors',
},
config/config.default.js下配置:
// 配置什么域名可以访问后台服务器
//配置允许跨域
exports.cors = {
// origin: '*', //任意源可访问后台服务器
origin: 'http://localhost:8080',
credentials: true, // 允许cookie跨越,不能写origin: '*'
allowMethods: 'GET,PUT,POST,DELETE'
};
七、jwt单点登录
安装jwt
npm install egg-jwt --save
配置jwt
config/plugin.js下配置:
// jwt 单点登录
jwt: {
enable: true,
package: "egg-jwt"
}
config/config.default.js下配置:
// JWT的原理:服务器端根据secret生成token
//即secret只有服务器端才知道是多少,也就让token只能有服务端签发
exports.jwt = {
secret: "myeggdemo" //自定义token的加密条件字符串
};
前端环境中使用Vuex
1.安装Vuex
npm install vuex --save
2.新建store文件夹,并创建index.js文件
import Vue from 'vue'
import * as type from './mutations-type.js'
import storage from '@/assets/js/storage'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { // 定义数据
token: null,
},
getters: { // 过滤的方法, 类似computed
token(state) {
state.token = storage.get('token') || ''; // 获得本地存储用户信息
return state.token;
},
},
mutations: { // 同步的提交方法(唯一修改state的方法)
[type.SETTOKEN](state, token) {
state.token = token;
storage.set('token', state.token); //本地存储 token
},
[type.REMOVETOKEN](state) {
state.token = '';
storage.remove("token"); //本地移除 token 的键
},
},
actions: { // 异步方法}
})
3.在main.js中全局引入
import store from './store'
4.在store文件夹下创建mutations-type.js文件
export const SETTOKEN = "setToken";
// REMOVENAME
export const REMOVETOKEN = "removeToken";
在vue中就可以通过this.setToken设置token,this.removeToken删除token
5.在assets/js文件夹下创建storage.js,对本地存储进行一个简单封装
const storage = window.localStorage;
export default {
set(key, val) { //存
if (val === undefined) {
return;
}
storage.setItem(key, serialize(val));
},
get(key, def) { //获取
const val = deserialize(storage.getItem(key));
return val === undefined ? def : val;
},
remove(key) {
//删除一个key
storage.removeItem(key);
},
clear() {
//删除整个
storage.clear();
}
};
function serialize(val) {
// 存储时转字符串
return JSON.stringify(val);
}
function deserialize(val) {
// 获取时转为对象
try {
//'{"username":"tom","age":18}'
return JSON.parse(val);
} catch (e) {
//如果不是对象的字符串而是纯字符串,那就不用再转对象了
return val || undefined;
}
}
前端环境中使用axios
1.安装axios
npm install axios --save
2.在assets/js文件夹下创建axios.js文件
import axios from 'axios'
import store from '../../store'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// 请求拦截器
axios.interceptors.request.use((req) => {
try {
req.url = 'http://localhost:7001' + req.url; //拼接url
if (store.getters.token) { // 将token 以http请求头形式传递给服务器
req.headers.authorization = store.getters.token
}
return req;
} catch (error) {
console.log(error);
}
}, (error) => {
return Promise.reject(error);
});
// 响应拦截器
axios.interceptors.response.use(
response => {
return response
},
error => {
if (error.response) {
if (error.response.status == 401) {
// token 过期本地存储删除,然后重新登录
store.commit('removeToken')
window.location.href = '/login'
}
}
return Promise.reject(error.response.data) // 返回接口返回的错误信息
})
src文件夹下创建api.js文件(与main.js同级)
import axios from './assets/js/axios'
// 所有接口的api封装
export default class Api {
// 获取轮播图
static carousels() {
return axios('/api/index/carousels', 'get')
}
}
// 获取门店展示信息
static shop(page) {
return axios(`/api/index/shop?page=${page}`, 'get')
}
//用户是否收藏
static userIsLike({
...args
}) {
return axios('/api/item/userIsLike', 'post', args)
}
在vue中使用封装好的api,直接调用即可
this.Api.carousels();
后端环境中处理token
1.中间件:middleware/isLogin.js
const url = require('url')
// JWT方案
module.exports = (options, app) => {
return async (ctx, next) => {
let pathname = url.parse(ctx.request.url).pathname;
// ctx.header.authorization
let token = ctx.request.header['authorization']; //拿到前端的token
if (pathname == '/api/loginOut' || pathname == '/api/login' ||
pathname == '/api/messageLogin' || pathname == '/api/verify' ) {
// 给不需要token操作的请求放行
await next();
} else {
if (!token) {
ctx.status = 401;
ctx.body = {
success: false,
message: '没有token',
code: -10000
}
return;
} else {
//app.config.secret是在config/config.default.js里面自定义的token加密条件字符串
let decode = app.jwt.verify(token, app.config.secret); //解码token
let username = decode.userToken.username
let hasUser = await ctx.model.User.findOne({ //数据库中获取用户名,验证是否
username
})
if (hasUser) {
//定义token解码后的用户id存为全局变量
ctx.state.userId = decode.userToken._id;
await next()
} else {
ctx.status = 401;
ctx.body = {
success: false,
message: '登录过期,请重新登录',
code: -10001 //自定义code码
};
}
}
}
};
};
版权声明:本文为weixin_41967475原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。