Vue implements automation platform (2) - implements login page & home page

Previous chapter, creation of vue project:

Vue scaffolding Vue CLI usage_Testing Meow Jiang’s Blog-CSDN Blog

github site: https://github.com/18713341733/vuemiaotest 

This is currently only used for practice, and the project has not yet been completed. I will update the project link after I finish writing it.​ 

Table of contents

1. System design

2. Project initialization

2.1 Project creation and initialization:

2.2 Create components

2.3 Configure routing

2.4 Component placement

3. Login page style and function implementation

3.1 Prerequisite:

3.1 Sending login request

3.2 Login page style

3.3 Login page function

3.3.1. Implement form input verification

3.3.2. Submit form pre-verification

3.3.3. Implement the function of remembering the account

3.3.4. Login page login.vue overall code

4. Routing access permission restrictions

5. Home page style and function implementation

5.1 Page layout

5.2 Log out

5.2.1 Logout style display

5.2.2 Implementation of logout function


1. System design

Use vue to write an interface automation project.

1. The page is divided into homepage, project page, use case page, and login page.

2. The sub-routes of the home page are: project page, use case page, and login page. (Because for future page display, these sub-routes need to be displayed on the homepage)

2. Project initialization

2.1 Project creation and initialization:

Vue project practice (1)_Miaojiang’s blog for testing-CSDN blog

2.2 Create components

The pages are divided into home page, project page, use case page, and login page. these four components.

Cases.vue use case page component

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

<script>
</script>

<style>
</style>

Home.vue home page component

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

<script>
</script>

<style>
</style>

Interface.vue interface component

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

<script>
</script>

<style>
</style>

Project.vue project component

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

<script>
</script>

<style>
</style>

Login.vue login page component

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

<script>
</script>

<style>
</style>

2.3 Configure routing

 router/index.js

There are a total of 5 components and 5 routes need to be configured.

Because we want to display the three components cases, interface, and projects in the home component.

So we need to set 3 of them as sub-routes of 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 Component placement

Where should these four components be displayed?

The homepage and login page components need to be displayed in App.vue. Use <router-view></router-view> placeholder

app.vue

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

<script>


export default {

}
</script>

<style>

</style>

Case pages, interface pages, etc. should be displayed in the homepage component. Add placeholder <router-view></router-view> to the home page

Home.vue

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

<script>
	export default{
		
	}
</script>

<style>
</style>

The overall project structure, that's it.

3. Login page style and function implementation

3.1 Prerequisite:

Create a login interface using 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 request:

http://127.0.0.1:8001/login/

Return value after successful login:

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

3.1 Sending login request

On the login page, when our front-end clicks the login button, it needs to send a post request.

Build a post request.

 1. In the src folder, create a new api folder and create the index.js file.

Two functions are implemented.

Function 1: Send http request.

Function 2: Before sending the request, check whether there is a token in the local session. If so, bring the token when making the request.

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. Bind axios (the created request object) to the vue prototype object. After binding, in vue, you can call axios to send a request through this.$http.

In main.js, bind axios to the vue prototype object

 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 page style

Login page style display:

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. Login style, using element ui

2. Form input box, bind the input data. (two-way binding)

v-model="formLogin.username"

3. Call http request

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

4. After successful login, put the token in the response into the browser's session (not into the cookie)

response:

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

5. When the status returned by the request is 200, a successful pop-up window will pop up and /jump to the home page.

				// 判断登录请求是否成功 
				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. Login box style. css needs to be written in Login.vue 

<style> </style>中。

The css style only controls the current page and does not want to affect the display of other pages. Add scoped

In style, add the scoped attribute to indicate the css style, which only takes effect on the current component.

<style scoped>

---------login_box

margin: 200px auto; 

The top margin is 200px, and the left and right auto are automatically centered.

------title

3.3 Login page function

3.3.1. Implement form input verification

a. On the el-form tag, bind the rules attribute and specify the rule object for verification.

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

The verification object is: rules="loginRules"

b. In data, define binding verification rules

	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. Specify the verification fields in the el-form-iem tag

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

Specify the field for verification: prop="username"

3.3.2. Submit form pre-verification

When clicking submit, the input box is first verified. After the verification passes, the login request is sent.

a. Set the form reference object through the ref attribute in the el-form tag.

ref='loginRef'

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

b. In the processing function of click login, obtain the form object through this.$resf. form reference object, and call the validate method of the form object for verification.

In the login function, the form verification is called first, and then the request is sent after the verification is passed.

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

Valid is the verification result, a Boolean value, true or false. When it is true, the verification is passed and the login method can be called.

3.3.3. Implement the function of remembering the account

Store account information in Local Storage.

Check Remember Account, click Login, and store the account information in Local Storage.

Visit the login page next time, read the account in Local Storage, and the data will be echoed.

a. Add a switch to record login in the form

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

b. Before logging in, determine whether the remember account is set. If it is set, save the account in LocalStrge. If it is not set, clear the account information in LocalStrge.

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

c. Assign the value of username in LocalStrge to formLogin.username to implement data echo.

Implemented through hook function mounted()

After the data in the component is mounted into the template, this life cycle hook function will be triggered.

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

3.3.4. Login page login.vue overall code

<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>

4. Routing access permission restrictions

The login page can be accessed directly by users. However, other pages such as the home page and use case page can only be accessed after logging in and having a token in the session.

Control access to routes through route guards.

Set routing guards in router/index.js

index.js full code:

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

In index.js, the routing guard controls access rights code:

// 添加路由导航守卫
// 添加路由导航守卫
// 用来对访问的路由进行权限控制
// 除了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')
})

When there is no token, redirect to the login page.

5. Home page style and function implementation

5.1 Page layout

Home page style display, log out, fixed in the upper right corner.

Project management, interface management, and use case management are fixed in the left list.

 5.1.1 Overall code of home page

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 Log out

5.2.1 Logout style display

Logout style, using element ui

When you click to log out, a secondary confirmation pops up.

			<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 Implementation of logout function

    1. Click the logout button to trigger the click event
    2. In the processing function, delete the token in sessionStorage and redirect the route to the login page.

			<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 Left navigation bar style

The left menu bar implements hierarchical nesting.

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

The index attribute cannot be repeated.

submenu icon

Submenu jump route

In the left navigation bar, click on a navigation to close other navigations, use unique-opened

Next chapter:

Vue Automation Platform (3)_Testing Meow Jiang’s Blog-CSDN Blog

Guess you like

Origin blog.csdn.net/qq_39208536/article/details/129870768