0


Vue实现自动化平台(二)--实现登录页面&首页

上一章,vue项目的创建:

Vue脚手架Vue CLI 使用_做测试的喵酱的博客-CSDN博客

github地址:https://github.com/18713341733/vuemiaotest

这个目前只是用来练手的,项目还没成型。等以后我写完了,再更新一下项目链接。

一、系统设计

使用vue编写一个接口自动化项目。

1、页面分为首页、项目页、用例页面、登录页面。

2、首页的子路由是:项目页、用例页、登录页面。(因为将来页面展示,需要将这几个子路由展示在首页里面)

二、项目初始化

2.1 项目创建及初始化:

Vue项目实战(一)_做测试的喵酱的博客-CSDN博客

2.2 创建组件

页面分为首页、项目页、用例页面、登录页面。这四个组件。

Cases.vue 用例页面组件

<template>
    <div>
        用例
    </div>
</template>

<script>
</script>

<style>
</style>

Home.vue 首页组件

<template>
    <div>
        首页
    </div>
</template>

<script>
</script>

<style>
</style>

Interface.vue 接口组件

<template>
    <div>
        接口
    </div>
</template>

<script>
</script>

<style>
</style>

Project.vue 项目组件

<template>
    <div>
        项目
    </div>
</template>

<script>
</script>

<style>
</style>

Login.vue登录页面组件

<template>
    <div>
        登录
    </div>
</template>

<script>
</script>

<style>
</style>

2.3 配置路由

** router/index.js**

一共5个组件,需要配置5个路由。

因为我们想要将cases、interface、projects这三个组件,显示在home组件中。

所以要将他们3个设置为home的子路由,children:[]

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from "../components/Login.vue"
import Home from "../components/Home.vue"
import Interface from "../components/Interface.vue"
import Cases from "../components/Cases.vue"
import Projects from "../components/Projects.vue"

Vue.use(VueRouter)

const routes = [{
    path: '/login',
    name: 'login',
    component: Login
    },{
    path: '/home',
    name: 'home',
    component: Home,
    children:[
        {
        path: '/cases',
        name:'cases',
        component: Cases
        },{
        path: '/interface',
        name: 'interface',
        component: Interface
        },{
        path: '/projects',
        name:'/projects',
        component: Projects
        }
        
    ]},    
]

const router = new VueRouter({
  routes
})

export default router

2.4 组件展示位置

将这4个组件,要展示在什么位置。

首页与登录页组件需要展示在App.vue中。使用<router-view></router-view> 占位

App.vue

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

<script>

export default {

}
</script>

<style>

</style>

case页面、接口页面等要展示在首页组件里。在首页里添加占位<router-view></router-view>

Home.vue

<template>
    <div>
        <router-view></router-view>
    </div>
</template>

<script>
    export default{
        
    }
</script>

<style>
</style>

整体项目结构,就是这样。

三、登录页面样式与功能实现

3.1 前提:

使用Django创建一个登录接口

https://blog.csdn.net/qq_39208536/article/details/129892740?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22129892740%22%2C%22source%22%3A%22qq_39208536%22%7D

post请求:

http://127.0.0.1:8001/login/

登录成功后的返回值:

{"code": 200, "msg": "\u64cd\u4f5c\u6210\u529f", "token": "1234567890"}

3.1 登录请求发送

登录页面,我们前端在点击登录按钮时,要发送一个post请求。

构建post请求。

1、在src文件夹下,新建api文件夹,创建index.js 文件。

实现了两个功能。

功能1:发送http请求。

功能2:在发送请求之前,检测本地session中是否有token,如果有,则请求的时候带上token。

import axios from 'axios'

const request = axios.create({
    // 指定请求HTTP响应码错误范围
    validateStatus: function(status) {
        return true
    },
    // 指定基本的url地址
    baseURL: 'http://127.0.0.1:8001',
})

// 给请求添加token用的
// 添加请求拦截器:每次请求接口都会自动调用
request.interceptors.request.use(function(config) {
    // 在发送请求之前,判断是否有token
    if (window.sessionStorage.getItem('token')) {
        config.headers.Authorization = 'JWT ' + window.sessionStorage.getItem('token')
    }
    console.log('请求头', config.headers)
    return config;
})

export default request

2、将axios(创建的请求对象)绑定到vue原型对象中。绑定之后,在vue中,才可以通过this.$http 来调用axios 发送请求。

在main.js中,将axios绑定到vue原型对象中

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
import axios from 'axios'

// 导入我们创建的用于请求的request对象
import request from './api/index.js'

// 将请求对象,绑定到vue的原型上
// $request 这个是我们自定义的变量名称
Vue.prototype.$request = request

Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

3.2 登录页面样式

登录页面样式展示:

Login.vue

<template>
    <div class="login_box" style="width: 600px;height: 400px; margin: 50px auto;text-align: center;">
        <el-card class="box-card">
            <h1>用 户 登 录</h1>
            <el-form ref="form" :model="formLogin" label-width="80px">
                <el-form-item label="账号">
                    <el-input v-model="formLogin.username"></el-input>
                </el-form-item>
                <el-form-item label="密码">
                    <el-input v-model="formLogin.password" type='password'></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="loginHandle">点击登录</el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>

</template>

<script>
    export default {
        data() {
            return {
                formLogin: {
                    username: '',
                    password: ''
                }
            }
        },
        methods: {
            // 点击登录之后,处理登录的方法
            loginHandle: async function() {
                // 请求登录接口
                console.log('请求登录接口')
                const response = await this.$request.post('/login/', this.formLogin)
                console.log('发送请求成功')
                console.log(response)
                // 判断登录请求是否成功 
                if (response.status === 200) {
                    this.$message({
                        message: '登录成功',
                        type: 'success'
                    });
                    window.sessionStorage.setItem('token', response.data.token)
                    this.$router.push('/home')
                } else {
                    this.$message.error('登录失败');
                }
            }
        }
    }
</script>

<style>
</style>

1、登录样式,用的是element ui

2、表单输入框,绑定输入的数据。(双向绑定)

v-model="formLogin.username"

3、调用http请求

const response = await this.$request.post('/login/', this.formLogin)

4、登录成功之后,将response中的 token,放到了浏览器的session中(不是cookie中)

response:

{"code": 200, "msg": "\u64cd\u4f5c\u6210\u529f", "token": "1234567890"}

5、请求返回的状态为200时,弹出一个成功的弹窗,并/跳转home页

                // 判断登录请求是否成功 
                if (response.status === 200) {
                    this.$message({
                        message: '登录成功',
                        type: 'success'
                    });
                    window.sessionStorage.setItem('token', response.data.token)
                    this.$router.push('/home')
                } else {
                    this.$message.error('登录失败');
                }

6、登录框样式。css 需要写在Login.vue 的

<style> </style> 中。

css的样式,只控制当前页面,不想影响到其他页面的展示,添加scoped

在style中,添加scoped属性,表示css样式,只对当前组件生效。

<style scoped>

---------login_box

margin: 200px auto;

上边距200px,左右auto自动居中。

------title

3.3 登录页面功能

3.3.1、实现表单输入校验

a、在el-form标签上,绑定rules属性,指定校验的规则对象

<el-form ref="form" :model="formLogin" :rules="loginRules">

校验对象为:rules="loginRules"

b、在data中,定义绑定校验规则

    export default {
        data() {
            return {
                formLogin: {
                    username: '',
                    password: '',
                    status: false,
                },
                loginRules: {
                    username: [{
                        required: true,
                        message: '账号不能为空',
                        trigger: 'blur'
                    }],
                    password: [{
                            required: true,
                            message: '密码不能为空',
                            trigger: 'blur'
                        },
                        {
                            min: 6,
                            max: 18,
                            message: '密码的长度在6到18之间',
                            trigger: 'blur'
                        }
                    ]
                }
            }
        },

c、在el-form-iem标签中指定校验的字段

                <el-form-item prop="username">
                    <el-input v-model="formLogin.username" prefix-icon="el-icon-user" placeholder="请输入账号"></el-input>
                </el-form-item>

指定校验的字段:prop="username"

3.3.2、提交表单预验证

在点击提交时,先对输入框做校验,校验通过后,再去发送登录请求。

a、在el-form标签通过ref属性,设置表单引用对象

ref='loginRef'

<el-form  :model="formLogin" :rules="loginRules" ref='loginRef'>

b、在点击登录的处理函数中,通过this.$resf.表单引用对象,获取表单对象,调用表单对象的validate方法进行校验.

在登录函数中,先调用表单的验证,验证通过后再发送请求。

                this.$refs.loginRef.validate(async (valid) => {
                    // 判断是否验证通过,没有通过则,终止函数执行
                    if (!valid) return
                    //调用登录函数

valid为校验结果,布尔值,true或者false。为true时,验证通过,可以调用登录方法。

3.3.3、实现记住账号功能

将账号信息存在Local Storage 中。

勾选记住账号,点击登录,将账号信息存在Local Storage 中。

下次再访问登录页面,读取Local Storage 中的账号,数据回显。

a、在表单中添加一个记录登录的开关

                <el-form-item label="记住账号">
                    <el-switch v-model="formLogin.status"></el-switch>
                </el-form-item>
                formLogin: {
                    username: '',
                    password: '',
                    status: false,
                },

b、登录之前判断,是否设置了记住账号,如果设置了,将账号保存到LocalStroge中,没有设置则清空LocalStroge中账号信息。

                    // -----判断是否要记住账号-----
                    if (this.formLogin.status) {
                        // 勾选则保存账号到localStorage中
                        window.localStorage.setItem('username', this.formLogin.username)
                    } else {
                        // 没有勾选则删除localStorage中的账号
                        window.localStorage.removeItem('username')
                    }

c、将LocalStroge 中的username的值赋给formLogin.username 实现数据回显。

通过勾子函数mounted() 实现

组件中的数据挂载到模板中之后,会触发这个生命周期钩子函数

        // 组件中的数据挂载到模板中之后,会触发这个生命周期钩子函数
        mounted(){
            // 获取localStorage中的账号,设置到data中
            const username = window.localStorage.getItem('username')
            if(username){
                this.formLogin.username = username
                this.formLogin.status = true
            }
        }

3.3.4、登录页面login.vue 整体代码

<template>
    <div class="login_box">
        <el-card class="box-card">
            <div class="title">
                自 动 化 平 台 登 录
            </div>
            <el-form :model="formLogin" :rules="loginRules" ref='loginRef'>
                <el-form-item prop="username">
                    <el-input v-model="formLogin.username" prefix-icon="el-icon-user" placeholder="请输入账号"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input v-model="formLogin.password" type='password' prefix-icon="el-icon-lock"
                        placeholder="请输入密码"></el-input>
                </el-form-item>
                <el-form-item label="记住账号">
                    <el-switch v-model="formLogin.status"></el-switch>
                </el-form-item>
                <el-form-item style="text-align: center;">
                    <el-button type="primary" @click="loginHandle">点击登录</el-button>
                </el-form-item>
            </el-form>
        </el-card>
    </div>

</template>

<script>
    /*
    一、输入框数据验证
        1、在 el-form 标签上绑定rules属性,指定校验的规则对象
        2、在data中定义绑定校验规则
        3、在 el-form-item 标签中通过prop指定校验的字段
    
    二、点击登录对表单进行预验证
        1、在 el-form 标签通过ref属性,设置表单引用对象
        2、在点击登录的处理函数中,通过this.$resf.表单引用对象,获取表单对象,调用表单对象的validate方法进行校验
    */
    export default {
        data() {
            return {
                formLogin: {
                    username: '',
                    password: '',
                    status: false,
                },
                loginRules: {
                    username: [{
                        required: true,
                        message: '账号不能为空',
                        trigger: 'blur'
                    }],
                    password: [{
                            required: true,
                            message: '密码不能为空',
                            trigger: 'blur'
                        },
                        {
                            min: 6,
                            max: 18,
                            message: '密码的长度在6到18之间',
                            trigger: 'blur'
                        }
                    ]
                }
            }
        },
        methods: {
            // 点击登录之后,处理登录的方法
            loginHandle: function() {
                // 验证表单,验证通过再发送登录请求
                this.$refs.loginRef.validate(async (valid) => {
                    console.log('表单验证的结果', valid)
                    // 判断是否验证通过,没有通过则,终止函数执行
                    if (!valid) return

                    // -----判断是否要记住账号-----
                    if (this.formLogin.status) {
                        // 勾选则保存账号到localStorage中
                        window.localStorage.setItem('username', this.formLogin.username)
                    } else {
                        // 没有勾选则删除localStorage中的账号
                        window.localStorage.removeItem('username')
                    }
                    // 验证通过的情况下,发送请求登录
                    console.log('请求登录接口')
                    const response = await this.$request.post('/login/', this.formLogin)
                    console.log(response)
                    // 判断登录请求是否成功 
                    if (response.status === 200) {
                        this.$message({
                            message: '登录成功',
                            type: 'success',
                            duration: 1000
                        });
                        // duration: 1000,弹窗停留1s消失
                        window.sessionStorage.setItem('token', response.data.token)
                        this.$router.push('/home')
                    } else {
                        this.$message.error('登录失败');
                    }
                })
            }
        },
        // 组件中的数据挂载到模板中之后,会触发这个生命周期钩子函数
        mounted(){
            // 获取localStorage中的账号,设置到data中
            const username = window.localStorage.getItem('username')
            if(username){
                this.formLogin.username = username
                this.formLogin.status = true
            }
        }
    }
</script>

<style scoped>
    /**
     * 在style中,添加scoped属性,表示css样式,只对当前组件生效。
     */
    .login_box {
        width: 600px;
        height: 400px;
        margin: 200px auto;
    }

    .title {
        color: #409eff;
        font: bold 28px/60px "microsoft yahei";
        width: 100%;
        text-align: center;
        margin-bottom: 25px;
    }
</style>

四、 路由访问权限限制

login页面,用户可以直接访问。但是其他页面如首页、用例页,只有登录之后,session中有token才可以访问。

通过路由守卫来控制访问路由的权限。

router/index.js 中设置路由守卫

index.js 全部代码:

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from "../components/Login.vue"
import Home from "../components/Home.vue"
import Interface from "../components/Interface.vue"
import Cases from "../components/Cases.vue"
import Projects from "../components/Projects.vue"

Vue.use(VueRouter)

const routes = [{
    path: '/login',
    name: 'login',
    component: Login
    },{
    path: '/home',
    name: 'home',
    component: Home,
    children:[
        {
        path: '/cases',
        name:'cases',
        component: Cases
        },{
        path: '/interface',
        name: 'interface',
        component: Interface
        },{
        path: '/projects',
        name:'/projects',
        component: Projects
        }
        
    ]},    
]

const router = new VueRouter({
  routes
})

// 添加路由导航守卫
// 添加路由导航守卫
// 用来对访问的路由进行权限控制
// 除了login这个路由其他的路由都要进行了登录之后才能访问
router.beforeEach((to, from, next) => {
    // console.log(to)
    // console.log(from)
    // console.log(next)
    // 判断访问的是否是登录页面
    // if (to.path === '/login') {
    //     return next()
    //     // 判断当前sessionStorage中是否有token(判断是否登录过)
    // } else if (window.sessionStorage.getItem('token')) {
    //     return next()
    // } else {
    //     return next('/login')
    // }
    
    if(to.path=== '/login' || window.sessionStorage.getItem('token')) return next()
    return next('/login')
})

export default router

index.js中,路由守卫控制访问权限代码:

// 添加路由导航守卫
// 添加路由导航守卫
// 用来对访问的路由进行权限控制
// 除了login这个路由其他的路由都要进行了登录之后才能访问
router.beforeEach((to, from, next) => {
    // console.log(to)
    // console.log(from)
    // console.log(next)
    // 判断访问的是否是登录页面
    // if (to.path === '/login') {
    //     return next()
    //     // 判断当前sessionStorage中是否有token(判断是否登录过)
    // } else if (window.sessionStorage.getItem('token')) {
    //     return next()
    // } else {
    //     return next('/login')
    // }
    
    if(to.path=== '/login' || window.sessionStorage.getItem('token')) return next()
    return next('/login')
})

没有token时,重定向到login页面。

五、首页页面样式与功能实现

5.1 页面布局

首页样式展示,退出登录,固定在右上角。

项目管理、接口管理、用例管理,固定在左侧列表。

5.1.1 首页整体代码

Home.vue

<template>

    <el-container>
        <!-- 页面顶部 -->
        <el-header>
            <div class="title">
                接 口 自 动 化 测 试 平 台
            </div>
            <div class="logonout">
                <el-popconfirm title="确认退出登录?" @confirm='loginout()'>
                    <div slot="reference">退出登录</div>
                </el-popconfirm>
            </div>

        </el-header>
        <el-container>
            <!-- 侧边菜单栏 -->
            <el-aside width="250px">
                <el-menu :router='rou' background-color='#555500' class="el-menu-demo" default-active='/cases'
                    text-color="#fff" active-text-color="#00aaff" unique-opened>
                    <!-- 项目管理 -->
                    <el-submenu index="projectManage">
                        <template slot="title">
                            <i class="el-icon-s-home"></i>
                            <span>项目管理</span>
                        </template>
                        <el-menu-item index="/projects">
                            <template slot="title">
                                <i class="el-icon-document-copy"></i>
                                <span>项目列表</span>
                            </template>
                        </el-menu-item>
                    </el-submenu>
                    <!-- 接口管理 -->
                    <el-submenu index="interfacaseManage">
                        <template slot="title">
                            <i class="el-icon-folder-opened"></i>
                            <span>接口管理</span>
                        </template>
                        <el-menu-item index="/interface">
                            <template slot="title">
                                <i class="el-icon-tickets"></i>
                                <span>接口列表</span>
                            </template>
                        </el-menu-item>
                    </el-submenu>
                    <!-- 用例管理 -->
                    <el-submenu index="caseManage">
                        <template slot="title">
                            <i class="el-icon-notebook-2"></i>
                            <span>用例管理</span>
                        </template>
                        <el-menu-item index="/cases">
                            <template slot="title">
                                <i class="el-icon-notebook-1"></i>
                                <span>用例列表</span>
                            </template>
                        </el-menu-item>
                    </el-submenu>
                </el-menu>
            </el-aside>
            <!-- 主体内容显示区域 -->
            <el-main>
                <router-view></router-view>

            </el-main>
        </el-container>
    </el-container>
</template>

<script>
    /*
    退出登录的实现
    1、点击退出登录按钮,触发点击事件
    2、在处理函数中,删除sessionStorage中的token,并将路由重定向到login页面
    
    */

    export default {
        data() {
            return {
                rou: true
            }
        },
        methods: {
            // 退出登录的方法
            loginout() {
                window.sessionStorage.removeItem('token')
                this.$router.push('/login')
            }
        },

    }
</script>

<style scoped>
    /* --------页面顶部的样式-------- */
    .el-header {
        background: #555500;
        margin-bottom: 5px;
    }

    .title {
        width: 90%;
        color: #fff;
        font: normal 28px/60px "microsoft yahei";
        text-align: center;
        float: left;
    }

    .logonout {
        width: 60px;
        color: #fff;
        font: normal 14px/60px "microsoft yahei";
        float: right;
        text-align: center;
    }

    .logonout:hover {
        background: #000;
    }

    /* ----------侧边菜单的样式---------- */
    .el-menu {
        height: 900px;
    }
</style>

5.2 退出登录

5.2.1 退出登录样式展示

退出登录样式,使用的element ui

点击退出登录时,弹出一个二次确认。

            <div class="logonout">
                <el-popconfirm title="确认退出登录?" @confirm='loginout()'>
                    <div slot="reference">退出登录</div>
                </el-popconfirm>
            </div>
    .logonout {
        width: 60px;
        color: #fff;
        font: normal 14px/60px "microsoft yahei";
        float: right;
        text-align: center;
    }

    .logonout:hover {
        background: #000;
    }

5.2.2 退出登录功能实现

1、点击退出登录按钮,触发点击事件
 2、在处理函数中,删除sessionStorage中的token,并将路由重定向到login页面。
            <div class="logonout">
                <el-popconfirm title="确认退出登录?" @confirm='loginout()'>
                    <div slot="reference">退出登录</div>
                </el-popconfirm>
            </div>

    export default {
        data() {
            return {
                rou: true
            }
        },
        methods: {
            // 退出登录的方法
            loginout() {
                window.sessionStorage.removeItem('token')
                this.$router.push('/login')
            }
        },

    }

5.3 左侧导航栏样式

左侧菜单栏,实现层级嵌套。

                    <!-- 项目管理 -->
                    <el-submenu index="projectManage">

index属性,不能重复。

子菜单图标

子菜单跳转路由

左侧导航栏,点开一个导航,将收起其他导航,使用unique-opened

下一章:

Vue实现自动化平台(三)_做测试的喵酱的博客-CSDN博客

标签: 前端 自动化 运维

本文转载自: https://blog.csdn.net/qq_39208536/article/details/129870768
版权归原作者 做测试的喵酱 所有, 如有侵权,请联系我们删除。

“Vue实现自动化平台(二)--实现登录页面&首页”的评论:

还没有评论