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 语言编写的接口服务和后台页面服务即可预览效果。
注意:登录用户名和密码请去前端页面自行注册,或者手动去数据库添加数据初始化。