一、前端登录页面的编写及与后端登录接口的交互

前言

前面的文章已经把后台登录接口准备完毕,接下来就是前端页面的编写以及前后端交互了,这里前后端交互我们用的是 axios。axios 是通过 promise 实现对 ajax 技术的一种封装,就像 jQuery 实现 ajax 封装一样。既然底层仍然是 ajax 通过异步请求与后台交互,就自然会遇到跨域的问题,这篇文章后面也会提及如何解决跨域问题。

解决跨域问题主要是有两个方向

这里我们选择第二种,接下来就详细描述下前端登录功能的实现.

1.在 components 目录下新建 Login 组件

(1).新建 Login.vue

<template>
    <div>
        登录组件
    </div>
</template>

<script>
    export default {

    }
</script>

<style lang="less" scoped>
</style>

(2).在 router/index.js 路由文件里导入 Login 组件

import Login from '../components/Login.vue'

(3).在路由文件 router/index.js 文件的 routes 数组里增加登录路由

{
    path: '/login',
    component: Login
  }

(4).在 app.vue 根组件中增加路由占位符

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

(5).打开地址http://localhost:8080/#/loginLogin 组件了便能成功访问到我们增加的

2.在 router/index.js 路由文件的 routes 数组里 增加默认路由 (这样访问地址/就会自动跳转到 Login 组件)

{
    path: '/',
    redirect: '/login'
  }

3.在 cmd 窗口使用vue ui命令,在打开的项目管理页面里面点击依赖安装 less-loader 和 less 开发依赖库,安装完成之后需要重启项目

4.在 assets 目录下新建 css 目录,然后在 css 目录新建 global.css 文件

html,body,#app{
    height: 100%;
    margin: 0;
    padding: 0;
}

在 main.js 文件里导入 global.css
import './assets/css/global.css'

5.在 plugins/element.js 文件里按需导入 element ui 组件

import Vue from 'vue'
import { Button,Form,FormItem,Input } from 'element-ui'

Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)

6.登录页面布局 (界面上的 el-form,el-button,el-input 等组件的用法可以打开 element-ui 官网查看用法,官网文档地址https://element.eleme.cn/#/zh-CN/component/installation)

(1).修改文件./components/Login.vue

<el-form ref="loginFormRef" label-width="0px" class="login_form">
               <!--用户名-->
               <el-form-item>
                   <el-input prefix-icon="iconfont icon-user"></el-input>
               </el-form-item>
               <!--密码-->
               <el-form-item>
                   <el-input prefix-icon="iconfont icon-3702mima"></el-input>
               </el-form-item>
               <!--按钮区域-->
               <el-form-item class="btns">
                   <el-button type="primary">登录</el-button>
                   <el-button type="info">重置</el-button>
               </el-form-item>
           </el-form>

(2).由于密码的 Input 框是密文所以密码对应的 input 框要加 type="password"属性
<el-input prefix-icon="iconfont icon-3702mima" type="password"></el-input>

7.数据绑定,需要为用户名密码输入框绑定数据

(1) 在 data 添加绑定数据

data(){
            return {
                loginForm:{
                    username: '',
                    password: ''
                }
            };
        }

(2) form 表单加上:model="loginForm"绑定 loginForm

<el-form :model="loginForm" label-width="0px" class="login_form">
(3) 用户名输入框加上 v-model="loginForm.username"绑定 loginForm.username

<el-input v-model="loginForm.username" prefix-icon="iconfont icon-user"></el-input>
(4) 密码输入框加上 v-model="loginForm.password"绑定 loginForm.password

<el-input v-model="loginForm.password" prefix-icon="iconfont icon-3702mima" type="password"></el-input>

8.添加表单验证

(1) data 里添加表单验证规则

data(){
            return {
                loginForm:{
                    username: '',
                    password: ''
                },
                loginFormRules:{
                    username: [
                        { required: true, message: '请输入登录名称', trigger: 'blur' },
                        { min: 3, max: 11, message: '长度在 3 到 11 个字符', trigger: 'blur' }
                    ],
                    password: [
                        { required: true, message: '请输入登录密码', trigger: 'blur' },
                        { min: 6, max: 15, message: '长度在 6 到 16 个字符', trigger: 'blur' }
                    ]
                }
            };
        },

(2) form 添加:rules="loginFormRules"关联验证规则
<el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">

(3) 用户名 input 框通过 el-form-item 添加 prop="username"来关联 username 验证规则
<el-form-item prop="username">

(4) 密码 input 框通过 el-form-item 添加 prop="password"来关联 password 验证规则
<el-form-item prop="password">

9.通过 el-form 添加 ref="loginFormRef"并且通过 this.$refs 来获取当前表单对象

重置表单数据

(1) 在 methods 添加 resetLoginForm 方法

(2) 通过表单的 resetFields 方法来重置表单数据 (包括表单验证结果)

methods:{
            resetLoginForm(){
                this.$refs.loginFormRef.resetFields();
            }
        }

(3) 为重置按钮绑定 resetLoginForm
<el-button type="info" @click="resetLoginForm">重置</el-button>

10.登录组件的预验证

(1) 在 methods 里面添加 login 方法

(2) 调用表单的 validate 方法来预验证表单数据

login(){
                this.$refs.loginFormRef.validate((valid)=>{
                    if (!valid) return;
                });
            }

(3) 为登录按钮绑定 login 方法

<el-button type="primary" @click="login">登录</el-button>

11.请求后端 login 接口

(1).在 main.js 文件里导入 axios

import axios from 'axios'
Vue.prototype.$http = axios

(2).在 main.js 里设置请求根路径
axios.defaults.baseURL = 'http://127.0.0.1:8082/api/v1/'

(3) 在 Login 组件的 login 方法里发起网络请求调用后台登录接口
const{data:res} = await this.$http.post("login",this.loginForm);

12.配置弹窗提示,在 element.js 文件中导入 element ui 的 Message 组件然后在组件里就可以通过 this.$message 调用弹窗方法弹出提示框

import { Button,Form,FormItem,Input,Message} from 'element-ui'

Vue.prototype.$message = Message

经过以上配置我们点击登录按钮,结果发现前端接口报错了
是不是一脸懵逼,403 是个什么鬼!
我们点开 console 终于发现了问题所在:提示跨域访问不被允许,接下来我们配置跨域访问

13.配置跨域访问

我们需要在后端增加跨域允许配置

package com.syy.testPlatform.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowCredentials(true)
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                .maxAge(3600);
    }
}

配置好跨域允许之后,我们再次点击登录按钮,看到后端接口调用成功并返回用户信息

14.完善 login 方法

login(){
                this.$refs.loginFormRef.validate(async valid=>{
                    // this.$message.success("登录成功")
                    if (!valid) return;
                    const{data:res} = await this.$http.post("user/login",this.loginForm);
                    if (!res.success) return  this.$message.error(res.message);
                    this.$message.success("登录成功");
                });
            }

(1) 登录成功之后的 token 保存到 sessionStorage 中
window.sessionStorage.setItem("token",res.data.token);

(2) 保存好 token 之后跳转到首页
this.$router.push("/home");

二、首页编写

前言

后端和前端的基础架构都已经搭建完成,为了相对容易理解,上手快,小白也能上手,而且本身就是公司内部系统,也没太大必要做的很完美,所以在我们初版系统的架构里很多东西都简化了,比如注册中心,网关代理,配置中心,负载均衡,授权认证,用户权限控制到页面按钮,消息队列,缓存,elk 等都未引入我们初版系统的架构里。如果有时间后面会讲下 JmeterEngine 相关 api 的使用、android 原生应用 mvp 及 mvvc 架构搭建及 React-native 构建 android 项目。

我们这篇文章就是关于 home 页面的编写实现,对于 home 页面比较主要的两个组件就是 container 和 menu 了,其中 container 较为简单,menu 一般要配合后台的权限校验来决定展示的内容,由于我们没做权限控制功能,menu 菜单显示直接写死了,所以也不复杂了。

1.在 components 目录下新建 Home 组件

<template>
    <div>
        Home
    </div>
</template>

<script>
    export default {

    }
</script>
<style lang="less" scoped>
</style>

2.在 router/index.js 文件中新增路由规则

import Home from '../components/Home.vue'

{
    path: '/home',
    component: Home
  },

3.路由导航守卫控制访问权限

如果我们没有进行登录,直接访问 home 也能正常访问,在实际项目里是不允许的,未登录访问 home 需要指定跳转到登录页面

router.beforeEach((to, from, next) => {
  if (to.path === '/login') return next()
  //获取token
  const tokenStr = window.sessionStorage.getItem('token')
  if (!tokenStr) return next('/login')
  next()
})

4.首页增加退出功能

<el-button type="info" @click="logout">退出</el-button>
methods:{
            logout(){
                window.sessionStorage.clear()
                this.$router.push("/login")
            }
        }

5.引入 Container 布局容器

import { Button,Form,FormItem,Input,Message,Container,Header,Aside,Main } from 'element-ui'


Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)

6.引入左边导航菜单

(1) 导入菜单相关组件

import { Button,Form,FormItem,Input,Message,Container,Header,Aside,Main,Menu, Submenu,MenuItem } from 'element-ui'

Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)

(2) 实现菜单相关代码

<el-container>
            <el-aside width="200px">
                <el-menu background-color="#333744" text-color="#fff" active-text-color="#ffd04b">
                    <el-submenu index="1">
                        <template slot="title">
                            <i class="el-icon-location"></i>
                            <span>性能测试</span>
                        </template>
                        <el-menu-item index="1-1">
                            <template slot="title">
                                <i class="el-icon-location"></i>
                                <span>用例管理</span>
                            </template>
                        </el-menu-item>


                    </el-submenu>
                </el-menu>
            </el-aside>
            <el-main>Main</el-main>
        </el-container>
    </el-container>

7.实现首页路由重定向

(1) 新建组件 Welcome.vue

<template>
    <div>
        <h3>Welcome</h3>
    </div>
</template>

(2) 导入组件 Welcome

import Welcome from '../components/Welcome.vue'

{
    path: '/home',
    component: Home,
    redirect: '/welcome',
    children:[{path:'/welcome',component:Welcome}]
  }

(3) Home.vue 放置路由占位符

<el-main>
  <router-view>

  </router-view>
</el-main>

8.左侧菜单改为路由链接

(1) el-menu 设置 router 为 true
<el-menu background-color="#333744" text-color="#fff" active-text-color="#409EFF" :collapse="isCollapse" :collapse-transition="false" router>

(2) el-menu-item index 属性设置路由地址

<el-menu :default-active="activeNav" background-color="#333744" text-color="#fff" active-text-color="#409EFF" :collapse="isCollapse" :collapse-transition="false" :unique-opened="true" router>
                    <el-submenu index="1">
                        <template slot="title">
                            <i class="el-icon-menu"></i>
                            <span>性能测试</span>
                        </template>
                        <el-menu-item index="/performanceTestCaseManage">
                            <template slot="title">
                                <i class="el-icon-menu"></i>
                                <span>用例管理</span>
                            </template>
                        </el-menu-item>


                        <el-menu-item index="/performanceScriptManage">
                            <template slot="title">
                                <i class="el-icon-menu"></i>
                                <span>脚本及文件管理</span>
                            </template>
                        </el-menu-item>

                        <el-menu-item index="/performanceTestReportManage">
                            <template slot="title">
                                <i class="el-icon-menu"></i>
                                <span>测试报告管理</span>
                            </template>
                        </el-menu-item>

                        <el-menu-item index="/performanceDistributedNodeManage">
                            <template slot="title">
                                <i class="el-icon-menu"></i>
                                <span>分布式节点管理</span>
                            </template>
                        </el-menu-item>

                        <el-menu-item index="/pressureTestScenarioManage">
                            <template slot="title">
                                <i class="el-icon-menu"></i>
                                <span>压测场景管理</span>
                            </template>
                        </el-menu-item>

                        <el-menu-item index="/testMonitor">
                            <template slot="title">
                                <i class="el-icon-menu"></i>
                                <span>测试监控</span>
                            </template>
                        </el-menu-item>
                    </el-submenu>
                </el-menu>


↙↙↙阅读原文可查看相关链接,并与作者交流