【Go + Nuxt.js 搭建一个 BBS 系统】11. 使用Element-UI搭建后台管理系统
点击下面链接购买后可获取本课程完整源码,同时提供高大上的在线IDE开发环境,边看教程边动手。
- 购买地址:https://www.shiyanlou.com/courses/1436
- 购买九折优惠邀请码:
ZHwfIjb1
作者简介
大猫猫,互联网公司老码农、不折腾不舒服斯基,多年千万日活服务端研发和架构经验。关注公众号查看更多技术干货:
实验介绍
实验内容
element-ui是由饿了么开源的一套基于Vue.js组件库。本实验我们就适用element-ui
将我们论坛的后台管理的框架搭建起来。
知识点
- 使用vue-cli创建基于element-ui的项目
- 使用element-ui搭建管理后台页面框架
- 实现后台登录功能
安装vue-cli
Element-ui
官方为vue-cli
准备了相应的插件,你可以使用它快速的搭建一个基于Element-ui
的项目。所以我们首先需要安装vue-cli
。
开始之前请先确认我们的环境,Nuxt.js 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。
环境确认无误后,执行以下命令来安装vue-cli
npm install -g @vue/cli
安装之后,你就可以在命令行中访问 vue
命令。你可以通过简单运行 vue
,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。
你还可以用这个命令来检查其版本是否正确:
vue --version
创建Element-UI项目
假设我们基于element-ui
的后台项目名称叫做admin
那么我们可以使用以下命令来创建我们的项目。
vue create admin
执行命令后,会要求选择一个预设配置,这里我们选择Manually select features
,进行手动配置,手动配置中会要求我们做一些选择,我们的选择如下:
接下来等该命令执行完成之后,执行下面命令添加element-ui
依赖:
cd admin
vue add element
执行该命令的时候有一些选项,需要我们选择一下,我们按照提示信息选择即可,如下图,我们的选择如下:
添加完成element-ui
依赖之后,我们接着来添加vue-router
执行以下命令即可添加:
vue add router
然后执行以下命令即可启动服务:
npm run serve
服务启动成功后,打开浏览器即可预览,如下图:
后台页面框架搭建
管理后台的页面我们采用顶部菜单导航,下面正文内容的形式,如下图:
element-ui
为我们提供了丰富的组件库,接下来我们就利用el-container
进行整个页面的布局、利用el-menu
作为顶部导航菜单来完成后台框架的搭建。
打开文件admin/src/App.vue
文件,修改代码,修改后完整代码如下:
<template>
<div id="app">
<el-container style="height:100%;">
<el-header>
<el-menu
class="main-menu"
mode="horizontal"
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
default-active="/"
:router="true"
>
<el-menu-item index="/">首页</el-menu-item>
<el-submenu index>
<template slot="title">内容管理</template>
<el-menu-item index="/topics">话题管理</el-menu-item>
<el-menu-item index="/comments">跟帖管理</el-menu-item>
</el-submenu>
<el-menu-item index="/users">用户管理</el-menu-item>
<el-menu-item index="/about">关于</el-menu-item>
</el-menu>
</el-header>
<el-main class="main-container">
<router-view />
</el-main>
</el-container>
</div>
</template>
<script>
export default {
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath);
},
handleClose(key, keyPath) {
console.log(key, keyPath);
}
}
};
</script>
<style lang="scss" scoped>
</style>
<style lang="scss">
html,
body {
height: 100%;
margin: 0px;
}
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
height: 100%;
.el-header {
text-align: center;
line-height: 60px;
padding: 0px !important;
}
.main-menu {
width: 100%;
}
.main-container {
overflow: auto;
}
}
</style>
接下来我们运行项目,可在浏览器中看到效果图如下:
整个管理后台页面布局完成之后,接下来就可以逐个功能模块去完善功能了。
用户登录功能
后台管理系统我们采用的是前后端分离的方案,后台用户登录功能和我们之前章节讲解的使用Nuxt.js
开发的bbs前台页面登录处理方式相同。他们的登录原理为:
- 调用登录接口,验证用户名密码,验证成功后接口返回授权令牌(userToken);
- 前端网页收到授权令牌(userToken)后,将他们存储到cookie中;
- 前端网页在每次请求后台接口的时候检查cookie中是有有
userToken
,如果有就带上; - 服务端在收到网页中的接口请求时,检查请求中是否有合法的
userToken
,否则就返回错误要求网页进行登录;
接下来我们逐步来实现后台的登录功能:
第一步:基于之前Go语言的服务端代码进行修改,新建文件server/admin_user_controller.go
,内容如下:
package main
import (
"github.com/kataras/iris/context"
"github.com/mlogclub/simple"
)
type AdminUserController struct {
Ctx context.Context
}
// 登录
func (this *AdminUserController) PostLogin() *simple.JsonResult {
var (
username = this.Ctx.PostValue("username")
password = this.Ctx.PostValue("password")
)
user, token := UserService.Login(username, password)
if user == nil {
return simple.JsonErrorMsg("用户名密码错误")
}
// 登录成功返回用户信息和授权令牌
return simple.NewRspBuilder(user).Put("token", token).JsonResult()
}
// 获取当前登录用户
func (this *AdminUserController) GetCurrent() *simple.JsonResult {
user := UserService.GetCurrent(this.Ctx)
if user == nil {
return simple.JsonError(simple.ErrorNotLogin)
}
return simple.JsonData(user)
}
同时修改server/main.go
文件,将刚刚定义的AdminUserController
添加到路由中,同时使用iris
的middleware
功能实现后台登录拦截,修改后的完整代码如下:
package main
import (
"github.com/jinzhu/gorm"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/kataras/iris/mvc"
"github.com/mlogclub/simple"
"github.com/iris-contrib/middleware/cors"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
var db *gorm.DB
func main() {
initDB()
app := iris.New()
// 跨域配置
app.Use(cors.New(cors.Options{
AllowedOrigins: []string{"*"}, // allows everything, use that to change the hosts.
AllowCredentials: true,
MaxAge: 600,
AllowedMethods: []string{iris.MethodGet, iris.MethodPost, iris.MethodOptions, iris.MethodHead, iris.MethodDelete, iris.MethodPut},
AllowedHeaders: []string{"*"},
}))
app.AllowMethods(iris.MethodOptions)
mvc.Configure(app.Party("/api/user"), func(mvcApp *mvc.Application) {
mvcApp.Handle(new(UserController))
})
mvc.Configure(app.Party("/api/topic"), func(mvcApp *mvc.Application) {
mvcApp.Handle(new(TopicController))
})
mvc.Configure(app.Party("/api/comment"), func(mvcApp *mvc.Application) {
mvcApp.Handle(new(CommentController))
})
mvc.Configure(app.Party("/api/admin"), func(mvcApp *mvc.Application) {
// 使用middleware实现登录校验
mvcApp.Router.Use(func(context context.Context) {
if context.Path() == "/api/admin/user/login" { // 登录接口不做校验
context.Next()
return
}
user := UserService.GetCurrent(context)
if user == nil { // 如果用户没登陆,那么返回错误码1,要求登录
_, _ = context.JSON(simple.JsonError(simple.ErrorNotLogin))
context.StopExecution()
return
}
context.Next()
})
mvcApp.Party("/user").Handle(new(AdminUserController))
})
_ = app.Run(iris.Addr(":8081"), iris.WithoutServerError(iris.ErrServerClosed))
}
// 初始化数据库链接
func initDB() {
var err error
db, err = gorm.Open("mysql", "root@tcp(localhost:3306)/test_db?charset=utf8mb4&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
err = db.AutoMigrate(&User{}, &UserToken{}, &Topic{}, &Comment{}).Error
if err != nil {
panic(err)
}
db.LogMode(true)
}
第二步:接下来我们修改前端页面,实现登录功能。
登录功能需要安装以下两个依赖:
- axios 用于接口请求
- js-cookie Cookie操作工具,用于读取和写入
userToken
在我们admin前端项目目录中执行下面命令来来添加axios
和js-cookie
依赖
vue add axios
npm install --save js-cookie
axios
插件添加完成之后会自动生成文件:admin/src/plugins/axios.js
,我们修改修改一下该文件,让axios
在每次请求的时候都在header中带上userToken
,修改之后的完整内容如下:
"use strict";
import Vue from 'vue';
import axios from "axios";
import qs from 'qs'
import cookies from 'js-cookie'
// Full config: https://github.com/axios/axios#request-config
// axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
// axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
let config = {
// baseURL: process.env.baseURL || process.env.apiUrl || ""
// timeout: 60 * 1000, // Timeout
// withCredentials: true, // Check cross-site Access-Control
// 接口host,请根据实际情况配置
baseURL: 'http://localhost:8081'
};
const _axios = axios.create(config);
_axios.interceptors.request.use(
function (config) {
const userToken = cookies.get('userToken');
if (userToken) { // 如果cookie中有userToken,那么放到请求header中
config.headers.common['X-User-Token'] = userToken
}
config.transformRequest = [
function (data) {
if (process.client && data instanceof FormData) { // 如果是FormData就不转换
return data
}
data = qs.stringify(data)
return data
}
]
return config;
},
function (error) {
// Do something with request error
return Promise.reject(error);
}
);
// Add a response interceptor
_axios.interceptors.response.use(
function (response) {
if (response.status !== 200) {
return Promise.reject(response);
}
if (response.data.success) {
return Promise.resolve(response.data.data);
} else {
return Promise.reject(response.data);
}
},
function (error) {
// Do something with response error
return Promise.reject(error);
}
);
_axios.onRequest
Plugin.install = function (Vue) {
Vue.axios = _axios;
window.axios = _axios;
Object.defineProperties(Vue.prototype, {
axios: {
get() {
return _axios;
}
},
$axios: {
get() {
return _axios;
}
},
});
};
Vue.use(Plugin)
export default Plugin;
第三步:实现登录页面
新增文件admin/src/views/Login.vue
,在该页面中实现登录操作,登录成功之后将服务端返回的userToken
存储到cookie
中,完整代码如下:
<template>
<div>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>登录</span>
</div>
<div class="text item">
<el-form>
<el-form-item label="用户名">
<el-input v-model="username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="doLogin">登录</el-button>
</el-form-item>
</el-form>
</div>
</el-card>
</div>
</template>
<script>
import cookies from 'js-cookie'
export default {
data () {
return {
username: '',
password: ''
}
},
methods: {
async doLogin () {
try {
const ret = await this.axios.post('/api/admin/user/login', {
username: this.username,
password: this.password
})
cookies.set('userToken', ret.token)
this.$message('登录成功')
this.$router.push('/') // 跳转到首页
} catch (error) {
this.$message.error(error.message || error)
}
}
}
}
</script>
<style lang="scss" scoped>
</style>
第四步:配置登录页面路由
然后修改admin/src/router/index.js
文件,将Login.vue
页面注册到vue-router
路由中,代码片段如下:
...
const routes = [
...
{
path: '/login',
name: 'login',
component: () => import('../views/Login.vue')
},
...
]
...
经过以上几个步骤我们就完成了后台的登录功能了,接下来我们分别启动Go语言编写的接口服务和后台页面服务即可预览效果。
注意:登录用户名和密码请去前端页面自行注册,或者手动去数据库添加数据初始化。
一. 未登录状态页面
二. 登录页面
三. 登录成功页面
总结
跟着本章节的讲解,我们完成了后台管理功能的框架搭建,接下来我们就可以基于该框架逐个模块的去完善后台管理功能了。下面我们看下本章节实例完整代码目录结构:
.
├── admin
│ ├── README.md
│ ├── babel.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── postcss.config.js
│ ├── public
│ │ ├── favicon.ico
│ │ └── index.html
│ └── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── components
│ │ └── HelloWorld.vue
│ ├── element-variables.scss
│ ├── main.js
│ ├── plugins
│ │ ├── axios.js
│ │ └── element.js
│ ├── router
│ │ └── index.js
│ ├── store
│ │ └── index.js
│ └── views
│ ├── About.vue
│ ├── Home.vue
│ └── Login.vue
└── server
├── admin_user_controller.go
├── comment_controller.go
├── comment_model.go
├── comment_service.go
├── go.mod
├── go.sum
├── main.go
├── topic_controller.go
├── topic_model.go
├── topic_service.go
├── user_controller.go
├── user_model.go
└── user_service.go
文章转载请注明出处,原文链接:https://mlog.club/topic/653