前端VUE

基础语法

        启动项目npm run serve

安装VUE

 入门Demo

定义的Vue只有id是app的才能使用他的变量值name,age,gender。

+ - 方法非id是app的也不可以调用。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<!-- 引入vue -->
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<div>{{name}}</div>
			<div>{{age}}</div>
			<div>{{gender}}</div>
			<button type="button" @click="add()">+</button>
			<button type="button" @click="sub()">-</button>
		</div>
		<div id="web">
			<button type="button" @click="add()">+</button>
			<button type="button" @click="sub()">-</button>
		</div>

		<script type="text/javascript">
			/*
			{{}}:插值表达式
			*/ 
			var vue = new Vue({
				// el  是vue绑定的页面元素
				el: "#app",
				// data:  是绑定到页面中的数据
				data:{
					name:'musen',
					age:18,
					gender:'男'
				},
				methods:{
					// vue方法中的this代表的vue这个对象
					add:function(){
						this.age++
					},
					sub:function(){
						this.age--
					}
				},
			})
		</script>
	</body>
</html>

指令

常见指令: 
            v-text:往标签中插入文本值
            v-html:往标签中插入html元素
            v-pre:在标签中显示原始文本内容,这里还是显示{{info}}
            v-show:控制元素的显示和隐藏(根据v-show指定的布尔值例来决定)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>

		<div id="box">
			<span>{{user}}</span>
			<span v-text="user"></span>
			<div v-html="info"></div>
			<div v-pre>{{info}}</div>
			<input type="text" v-show="status">
		</div>
		<script type="text/javascript">
			/*
			常见指令: 
			v-text:往标签中插入文本值
			v-html:往标签中插入html元素
			v-pre:在标签中显示原始文本内容,这里还是显示{{info}}
			v-show:控制元素的显示和隐藏(根据v-show指定的布尔值例来决定)
			*/
			var vue = new Vue({
				el: '#box',
				data: {
					user: '小柠檬',
					info: '<h1>python</h1>',
					status:false
				}
			})
		</script>
	</body>
</html>

属性绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

		<style type="text/css">
			.hide {
				width: 100px;
				height: 200px;
				background: red;
			}
		</style>

	</head>
	<body>
		<div id="box">
			<div class="hide">1</div>
			<hr>
			<div :class="cls">2</div>
			<hr>
			<div :class="[cls]">3</div>
			<hr>
			/* 这个hide使用的头部hide,并不是对象里的hide*/
			<div :class="{hide:status}">4 </div>
			 <a :href='addr'>淘宝</a>
			 <a :href="addr2">百度</a>
		</div>

		<script type="text/javascript">
			/**
			 * v-bind  可以简写为 :
			 * v-bind:属性值 = 绑定的数据
			 */
			var vue = new Vue({
				el: '#box',
				data: {
					cls: 'hide',
					status: true,
					addr:'http://www.taobao.com',
					addr2:'http://www.baidu.com',
				}
			})
		</script>
	</body>
</html>

事件绑定

点击事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="box">
			<button type="button" @click="sub()">-</button>
			<input type="text" :value="number">
			<button type="button" v-on:click="add()">+</button>	
		</div>

		<script type="text/javascript">
			/**
			 * v-on:可以简写为 @
			 * v-on:事件名 = 执行的函数
			 */
			var vue = new Vue({
				el: '#box',
				data: {
					number:0
				},
				methods:{
					add:function(){
						this.number++
					},
					// 定义方法时:将function省略,和上面定义的add方法没有区别
					sub(){
						this.number--
					}
					
				}
			})
			
			
		</script>;
	</body>
</html>

条件判断

if

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
				<div>
				<span v-text="user"></span>
				<span v-text="score"></span>
				<span v-if="score>80">优秀</span>
				<span v-else-if="score>60">良好</span>
				<span v-else=>不及格</span>
				</div>
		</div>
		<script type="text/javascript">
			/*
			0-60   不及格
			60--80  良好
			80-100  优秀
			vue中的条件判断语句:根据不同的条件显示不同的内容
			v-if
			v-else-if
			v-else:
			*/	
			var vue = new Vue({
				el:"#app",
				data:{
					stus:[
						{name:'木森',score:100},
						{name:'盼盼达',score:78},
						{name:'好好先生',score:89},
						{name:'枫',score:99},
					],
					score:88,
					user:'musen'
				}
			})
		</script>
	</body>
</html>

for 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<table border="" cellspacing="" cellpadding="">
				<tr>
					<th>姓名</th>
					<th>成绩</th>
					<th>等级</th>
				</tr>
				<!-- // key 需要指定一个数据中唯一的值 -->
				<tr v-for='item in stus' :key='item.score'>
					<td>{{item.name}}</td>
					<td>{{item.score}}</td>
					<td v-if="item.score>80">优秀</td>
					<td v-else-if="item.score>60">良好</td>
					<td v-else>不及格</td>
				</tr>
			</table>

		</div>
		<script type="text/javascript">
			/*
			0-60   不及格
			60--80  良好
			80-100  优秀			
			v-for:循环语句,记得加:key='item.唯一的属性'
			*/
			var vue = new Vue({
				el: "#app",
				data: {
					stus: [{
							name: '木森',
							score: 100
						},
						{
							name: '盼盼达',
							score: 100
						},
						{
							name: '好好先生',
							score: 89
						},
						{
							name: '枫',
							score: 99
						},
					],
					score: 88,
					user: 'musen'
				}

			})
		</script>
	</body>
</html>

数据双向绑定v-model

前端改了,代码的值也改了。代码的值改了,前端也改了。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<input type="text" v-model="info">
			<div>{{info}}</div>
		</div>

		<script type="text/javascript">
			var vue = new Vue({
				el:'#app',
				data:{
					info: 'python'
				}
			})
		</script>
	</body>
</html>

作业

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<table border="" cellspacing="" cellpadding="">
				<tr>
					<th>ID</th>
					<th>接口名</th>
					<th>测试人员</th>
					<th>项目名</th>
					<th>项目ID</th>
					<th>描述信息</th>
					<th>创建时间</th>
					<th>用例数</th>
					<th>操作</th>
				</tr>
				<tr :key='item.id' v-for="item in lists">
					<td>{{item.id}}</td>
					<td>{{item.name}}</td>
					<td>{{item.tester}}</td>
					<td>{{item.project}}</td>
					<td>{{item.project_id}}</td>
					<td>{{item.desc}}</td>
					<td>{{item.create_time}}</td>
					<td>{{item.testcases}}</td>
					<td><button @click="del(item.id)">删除</button></td>
				</tr>
			</table>
			<hr>
		
		</div>
		<script type="text/javascript">
			/*
			给绑定的事件传递参数
			*/ 
			var vue = new Vue({
				el: '#app',
				data: {
					lists: [{
							"id": 1,
							"name": "登录接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "登录接口",
							"create_time": "2019-11-06 14:50:30",
							"testcases": 9,
						},
						{
							"id": 2,
							"name": "注册接口_自动化测试平台项目",
							"tester": "可可",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "自动化测试平台项目, 注册接口",
							"create_time": "2019-11-06 14:51:00",
							"testcases": 0,
						},
						{
							"id": 3,
							"name": "创建项目接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "这是自动化测试平台创建项目接口",
							"create_time": "2019-11-06 14:51:45",
							"testcases": 1,
						},
						{
							"id": 4,
							"name": "注册接口_前程贷P2P金融项目",
							"tester": "小可可",
							"project": "前程贷P2P金融项目",
							"project_id": 2,
							"desc": "",
							"create_time": "2019-11-06 14:52:22",
							"testcases": 0,
						},
						{
							"id": 5,
							"name": "登录接口_前程贷P2P金融项目",
							"tester": "柠檬小姐姐",
							"project": "前程贷P2P金融项目",
							"project_id": 2,
							"desc": "",
							"create_time": "2019-11-06 14:52:40",
							"testcases": 0,
						},
						{
							"id": 6,
							"name": "查看项目列表接口_前程贷P2P金融项目",
							"tester": "柠檬小姐姐",
							"project": "前程贷P2P金融项目",
							"project_id": 2,
							"desc": "",
							"create_time": "2019-11-06 17:22:50",
							"testcases": 1,
						}
					],
					
				},
				methods:{
					del:function(id){
						// 删除数据的方法
						console.log('删除一行数据',id)
						// 从lists中删除对应的数据
						// 通过过滤的方式删除数组中的数据
						// this.lists= this.lists.filter(function(item,index){
						// 	return item.id !=id
						// })
						
						// 查找要删除的数据索引值
						let index = this.lists.findIndex(function(item){
							return item.id==id
						})
						// 根据数组的索引去删除数组中对应的数据
						this.lists.splice(index,1)
						
					}
				}
			})
		</script>
	</body>
</html>

高级特性

修饰符

事件修饰符

事件冒泡就是指父元素和子元素有相同的事件,当触发子元素事件时,会向上冒泡,同时也会触发父元素事件。

vue事件修饰符:
   stop: 阻止事件冒泡
   prevent:阻止元素默认的事件行为

可以两个一起用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<div @click="work3">
				<div @click="work2()">
					<button type="button" @click.stop="work1()">按钮1</button>
					<a href="http://www.baidu.com" @click.prevent.stop="handleA()">百度</a>
				</div>
			</div>
		</div>

		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {},
				methods: {
					work1: function() {
						console.log('work1-----')
					},
					work2: function() {
						console.log('work2-----')
					},
					work3: function() {
						console.log('---work30000')
					},
					handleA:function(){
						console.log('点击了a标签')
					}
				}
			})
		</script>

	</body>
</html>

按键修饰符

监听操作键盘的按键内容来触发某些函数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<form action="">
				账号:<input type="text" v-model="loginForm.user"> <br>
				密码:<input type="password" v-model="loginForm.pwd" @keyup.enter="login_btn()"><br>
				<button type="button" @click="login_btn()">点击登录</button>
			</form>
		</div>

		<script type="text/javascript">
			Vue.config.keyCodes.a = 65
			var vm = new Vue({
				el: '#app',
				data: {
					loginForm:{
						user:'',
						pwd:''
					}
				},
				methods: {
					login_btn:function(){
						alert('点击了登录')
					}
				}
			})
		</script>
	</body>
</html>

表单输入绑定,配合数据双向绑定使用

.lazy - 取代input监听change事件不会是输入一个数字就数据同步,变成回车或者脱离输入框才同步
.number - 输入字符串转为有效的数字
.trim - 输入首尾空格过滤
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<form action="">
				账号:<input type="text" v-model.lazy="loginForm.user"> <br>
				密码:<input type="password" v-model.trim="loginForm.pwd" @keyup.enter="login_btn()"><br>
				验证码:<input type="text" v-model.number="loginForm.user"> <br>
				<button type="button" @click="login_btn()">点击登录</button>
			</form>
		</div>

		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
					loginForm:{
						user:'',
						pwd:''
					}
				},
				methods: {
					login_btn:function(){
						alert('点击了登录')
					}
				}
			})
		</script>
	</body>
</html>

计算属性

计算属性:通过computed进行定义
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<h3>产品名:{{name}}</h3>
			<h3>单价:{{price}}</h3>
			<h3>
				数量:
				<button type="button" @click="sub()">-</button>
				<span>{{num}}</span>
				<button type="button" v-on:click="add()">+</button>
			</h3>
			<hr>
			<!-- <h2>合计金额:{{sum_func()}}</h2> -->
			<h2>合计金额:{{price_result}}</h2>
		</div>
		<script type="text/javascript">
			var vue = new Vue({
				el: '#app',
				data: {
					name: '小柠檬',
					price: 8,
					num: 0,
				},
				methods: {
					add: function() {
						this.num++
					},
					// 定义方法时:将function省略,和上面定义的add方法没有区别
					sub() {
						this.num--
					},
					// sum_func(){
					// 	return this.price * this.num
					// }
				},
				// 定义计算属性,
				computed: {
					price_result: function() {
						return this.price * this.num
					}
				},
			})
		</script>
	</body>
</html>

侦听器

watch 监测数据的值是否发生变化
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="box">
			数量:
			<button type="button" @click="sub()">-</button>
			<input type="text" :value="number">
			<button type="button" v-on:click="add()">+</button>
			<hr>
			<input type="text" v-model.lazy="name">
		</div>

		<script type="text/javascript">
			/**
			 *  侦听器 监测数据的值是否发生变化
			 */
			var vue = new Vue({
				el: '#box',
				data: {
					number:0,
					name :'musen'
				},
				methods:{
					add:function(){
						this.number++
					},
					// 定义方法时:将function省略,和上面定义的add方法没有区别
					sub(){
						this.number--
					}
				},
				// 侦听器 
				watch:{
					number:function(value){
						console.log('监测到number的值发生了变化',value)
						if (value<0){
							alert('数量不能少于0')
							this.number=0
						}	
					},
					name:function(value){
						console.log('监测到name的值发生了变化',value)	
					}
				}
			})
			
		</script>;
	</body>
</html>

过滤器

保留两位小数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<h3>产品名:{{name}}</h3>
			<h3>单价:{{price | dubboFloat}}</h3>
			<h3>
				数量:
				<button type="button" @click="sub()">-</button>
				<span>{{num}}</span>
				<button type="button" v-on:click="add()">+</button>
			</h3>
			<hr>
			<!-- <h2>合计金额:{{sum_func()}}</h2> -->
			<h2>合计金额:{{sum | dubboFloat}}</h2>
			<h2>{{info| upper}}</h2>
		</div>
		<script type="text/javascript">
		
			var vue = new Vue({
				el: '#app',
				data: {
					name: '小柠檬',
					price: 8,
					num: 0,
					info:'python'
				},
				methods: {
					add: function() {
						this.num++
					},
					// 定义方法时:将function省略,和上面定义的add方法没有区别
					sub() {
						this.num--
					}
				
				},
				// 定义计算属性,
				computed: {
					sum: function() {
						return this.price * this.num
					}
				},
				// 定义过滤器
				/*
				主要用来对页面显示的数据,做一些格式化的处理
				*/
				filters:{
					dubboFloat:function(value){
						
						// 格式化数值,显示两位小数
						return value.toFixed(2)
					},
					upper:function(value){
						// 将字符串中的小写字符转换为大写
						return value.toUpperCase()
					}
				}
			})
		</script>
	</body>
</html>

 全局组件


1、定义组件:
	全局组件:使用Vue.component定义组件
2、在页面中使用组件 <组件名></组件名>
			
3、组件名的命名注意点:
	如果定义组件的之后组件名,使用的是大驼峰的命名风格,在页面中引用组件的时候 ,
	要使用中划线命名风格(xx-xx)
				
4、定义的全局组件 可以再其他的组件中直接引用
	注意点:在组件的版本中引用其他组件可以使用大驼峰命名法
			
建议:组件命名尽量使用中划线命名风格  xxx-xxx
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<style>
			.title {
				background: #0000FF;
				height: 80px;
				margin-bottom: 5px;
			}
			.content {
				background: #FAEBD7;
				height: 1000px;
			}
			.footer {
				margin-top: 10px;
				background: #9ACD32;
				height: 100px;
			}
			.left {
				width: 15%;
				background: #00FFFF;
				height: 100%;
				float: left;
				margin-right: 0.5%;
			}
			.right {
				width: 84%;
				background: #FF0000;
				height: 100%;
				float: left;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<!-- 顶部菜单栏 -->
			<div class="title">
				<header-con></header-con>
				<!-- <HeaderCon></HeaderCon> -->
			</div>
			<!-- 中间的主题内容 -->
			<div class="content">
				<!-- 左边的菜单 -->
				<div class="left">
					<left-con></left-con>
				</div>
				<!-- 右边的内容 -->
				<div class="right">
					<right-con></right-con>
					
				</div>
			</div>
		</div>

		<script type="text/javascript">
			//  全局的组件定义:
			Vue.component('header-con', {
			 	template: `
			 	<div><h1>这个是页面头部组件</h1></div>
			 	`
			 })
			Vue.component('HeaderCon', {
				template: `
				<div><h1>这个是页面头部组件9999</h1></div>
				`
			})
			Vue.component('left-con', {
				template: `
				<div> <h1>这个是页面左边内容的组件</h1>
				<my-button></my-button></div>
				`
			})
			Vue.component('right-con', {
				template: `
				<div> 
				<h1>这个是页面左边内容的组件</h1>
				<my-button></my-button>
				<MusenButton></MusenButton>
				</div>
				`
			})
			Vue.component('my-button',{
				template:`
				<button>mybutton</button>
				`
			})
			Vue.component('MusenButton',{
				template:`
				<button>musen</button>
				`
			})
			var vm = new Vue({
				el: '#app',
				data: {
				},
			})
		</script>
	</body>
</html>

 局部组件

// 定义局部组件:只能在父组件(页面)中使用,不能在其他的组件中引用
// 组件名要使用引号包起来,不然会报语法错误

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

	</head>
	<body>
		<div id="app">
			<header-con></header-con>
			<left-con></left-con>
		</div>
		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
				},
				// 定义局部组件:只能在父组件(页面)中使用,不能在其他的组件中引用
				components: {
					// 组件名要使用引号包起来,不然会报语法错误-
					'header-con': {
						template: `
						<button>按钮1</button>
						`
					},
					'left-con': {
						template: `
						<div>
							<span>python666</span>
						</div>
						`
					}
				}
			})
		</script>
	</body>
</html>

组件中的数据和方法定义

1、组件中的数据 同样放在data字段中,
	注意点:组件中的data是一个方法(函数),数据为函数return返回出来的内容
	注意点:组件的模板内容,必须有一个根节点(最外层只有一个标签)
2、组件中的方法:定义在methods中
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<header-con></header-con>
			<left-con></left-con>
		</div>
		<script type="text/javascript">
			var vm = new Vue({
				el: '#app',
				data: {
					name: '木森',
					age: 99
				},
				// 定义局部组件:只能在父组件(页面)中使用,不能在其他的组件中引用
				components: {
					// 组件名要使用引号包起来,不然会报语法错误-
					'header-con': {
						template: `
						<button @click='handleClick'>按钮1</button>
						`,
						methods: {
							handleClick: function() {
								console.log('----handleClick-----')
							}
						},
					},
					'left-con': {
						template: `
						<div>
							<h2>名字{{name}}</h2>
							<h2>名字{{age}}</h2>
							<h2>计算属性sum:{{sum}}</h2>
							<span>python666</span>
						</div>
						`,
						// 组件中的数据 同样放在data字段中,
						// 注意点:组件中的data是一个方法(函数),数据为函数return返回出来的内容
						data: function() {
							return {
								name: 'musen',
								age: 18
							}
						},
						computed: {
							sum: function() {
								return this.name + this.age
							}
						},
						watch: {
							age: function(val) {
								console.log(val)
							}
						}
					}
				}
			})
		</script>
	</body>
</html>

父组件往子组件中传递数据

场景:父组件中引用子组件的时候,给子组件传递数据
实现步骤:
	1、在子组件中通过props来定义接收数据的参数名(子组件的属性名)
	2、父组件在引用子组件时,通过属性绑定的形式传递参数
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<data-views :lists="cases1"></data-views>
			<data-views :lists="cases2"></data-views>
		</div>
		<script type="text/javascript">
			// 子组件
			Vue.component('data-views', {
				// 指定父组件中引用该组件时,传递数据的参数名,使用props
				props:['lists'],
				template: `
				<table border="" cellspacing="" cellpadding="">
					<tr>
						<th>ID</th>
						<th>接口名</th>
						<th>测试人员</th>
						<th>项目名</th>
						<th>项目ID</th>
						<th>描述信息</th>
						<th>创建时间</th>
						<th>用例数</th>
					</tr>
					<tr :key='item.id' v-for="item in lists">
						<td>{{item.id}}</td>
						<td>{{item.name}}</td>
						<td>{{item.tester}}</td>
						<td>{{item.project}}</td>
						<td>{{item.project_id}}</td>
						<td>{{item.desc}}</td>
						<td>{{item.create_time}}</td>
						<td>{{item.testcases}}</td>
					</tr>
				</table>
				`
			})
			// 父组件
			var vm = new Vue({
				el: '#app',
				data: {
					cases1:[{
							"id": 1,
							"name": "登录接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "登录接口",
							"create_time": "2019-11-06 14:50:30",
							"testcases": 9,
						},
						{
							"id": 2,
							"name": "注册接口_自动化测试平台项目",
							"tester": "可可",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "自动化测试平台项目, 注册接口",
							"create_time": "2019-11-06 14:51:00",
							"testcases": 0,
						}],
					cases2:[
						{
							"id": 3,
							"name": "创建项目接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "这是自动化测试平台创建项目接口",
							"create_time": "2019-11-06 14:51:45",
							"testcases": 1,
						},
						{
							"id": 4,
							"name": "注册接口_前程贷P2P金融项目",
							"tester": "小可可",
							"project": "前程贷P2P金融项目",
							"project_id": 2,
							"desc": "",
							"create_time": "2019-11-06 14:52:22",
							"testcases": 0,
						},
						{
							"id": 5,
							"name": "登录接口_前程贷P2P金融项目",
							"tester": "柠檬小姐姐",
							"project": "前程贷P2P金融项目",
							"project_id": 2,
							"desc": "",
							"create_time": "2019-11-06 14:52:40",
							"testcases": 0,
						},
						{
							"id": 6,
							"name": "查看项目列表接口_前程贷P2P金融项目",
							"tester": "柠檬小姐姐",
							"project": "前程贷P2P金融项目",
							"project_id": 2,
							"desc": "",
							"create_time": "2019-11-06 17:22:50",
							"testcases": 1,
						}
					]
				}
			})
		</script>
	</body>
</html>

子组件往父组件中传递数据

场景:一般子组件在操作某个数据之后,要将数据传递给父组件,就要用到子组件给父组件传递数据,
	实现步骤:
	1、在子组件中通过$emit来触发一个自定义的事件,并把数据传递过去
		$emit('自定义的事件名',传递的数据)
	2、父组件在引用子组件时,通过事件监听机制,来监听子组件自定义的事件,并指定方法去处理这个事件
		@自定义的事件名 = 处理事件的方法($event)
	3、在处理事件的方法中接收数据,并处理
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<data-views :lists="cases1" @run='recvData($event)'></data-views>
			<hr>
			<div>
				<h3>执行的用例信息:{{info}}</h3>
			</div>
		</div>
		
		<script type="text/javascript">
			Vue.component('data-views', {
				// 指定父组件中引用该组件时,传递数据的参数名
				props:['lists'],
				template: `
				<table border="" cellspacing="" cellpadding="">
					<tr>
						<th>ID</th>
						<th>接口名</th>
						<th>测试人员</th>
						<th>项目名</th>
						<th>项目ID</th>
						<th>描述信息</th>
						<th>创建时间</th>
						<th>用例数</th>
						<th>操作</th>
					</tr>
					<tr :key='item.id' v-for="item in lists">
						<td>{{item.id}}</td>
						<td>{{item.name}}</td>
						<td>{{item.tester}}</td>
						<td>{{item.project}}</td>
						<td>{{item.project_id}}</td>
						<td>{{item.desc}}</td>
						<td>{{item.create_time}}</td>
						<td>{{item.testcases}}</td>
						<th><button @click="$emit('run',item)">执行</button></th>
					</tr>
				</table>
				`
			})
		
			var vm = new Vue({
				el: '#app',
				data: {
					cases1:[{
							"id": 1,
							"name": "登录接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "登录接口",
							"create_time": "2019-11-06 14:50:30",
							"testcases": 9,
						},
						{
							"id": 2,
							"name": "注册接口_自动化测试平台项目",
							"tester": "可可",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "自动化测试平台项目, 注册接口",
							"create_time": "2019-11-06 14:51:00",
							"testcases": 0,
						}],
					info:''
				},
				methods:{
					// 父组件中监听到子组件触发的事件之后,接收数据的方法
					recvData:function(value){
						console.log(value)
						this.info = value
					}
				}
		
			})
		</script>
	</body>
</html>

插槽

插槽:定义组件时,给父组件预留填充内容(html)的插口(空白)
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<data-views :lists="cases1" @run='recvData($event)'>
				<template>
					<span>项目名:柠檬班</span>
					<span>版本:V1.0</span>
					<span>时间:2021-04-02</span>
				</template>
			</data-views>
			<hr>
			<div>
				<h3>执行的用例信息:{{info}}</h3>
			</div>
		</div>
		<script type="text/javascript">
			Vue.component('data-views', {
				// 指定父组件中引用该组件时,传递数据的参数名
				props: ['lists'],
				template: `
				<div>
					<h1>-------------子组件---------------</h1>
					//插槽
					<slot></slot>
					<table border="" cellspacing="" cellpadding="">
						<tr>
							<th>ID</th>
							<th>接口名</th>
							<th>测试人员</th>
							<th>项目名</th>
							<th>项目ID</th>
							<th>描述信息</th>
							<th>创建时间</th>
							<th>用例数</th>
							<th>操作</th>
						</tr>
						<tr :key='item.id' v-for="item in lists">
							<td>{{item.id}}</td>
							<td>{{item.name}}</td>
							<td>{{item.tester}}</td>
							<td>{{item.project}}</td>
							<td>{{item.project_id}}</td>
							<td>{{item.desc}}</td>
							<td>{{item.create_time}}</td>
							<td>{{item.testcases}}</td>
							<th><button @click="$emit('run',item)">执行</button></th>
						</tr>
					</table>
					</div>
					`
			})
			var vm = new Vue({
				el: '#app',
				data: {
					cases1: [{
							"id": 1,
							"name": "登录接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "登录接口",
							"create_time": "2019-11-06 14:50:30",
							"testcases": 9,
						},
						{
							"id": 2,
							"name": "注册接口_自动化测试平台项目",
							"tester": "可可",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "自动化测试平台项目, 注册接口",
							"create_time": "2019-11-06 14:51:00",
							"testcases": 0,
						}
					],
					info: ''
				},
				methods: {
					// 父组件中监听到子组件触发的事件之后,接收数据的方法
					recvData: function(value) {
						console.log(value)
						this.info = value
					}
				}

			})
		</script>
	</body>
</html>

具名插槽

插槽增加name属性

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<div id="app">
			<data-views :lists="cases1" @run='recvData($event)'>
				<template slot="title">
					<span>项目名:柠檬班</span>
					<span>版本:V1.0</span>
					<span>时间:2021-04-02</span>
				</template>
				<template slot='body'>
					<h4>python+vue真好用</h4>
				</template>
			</data-views>
			<hr>
			<div>
				<h3>执行的用例信息:{{info}}</h3>
			</div>
		</div>
		<script type="text/javascript">
			Vue.component('data-views', {
				// 指定父组件中引用该组件时,传递数据的参数名
				props: ['lists'],
				template: `
				<div>
					<slot name='title'></slot>
					<h1>-------------子组件---------------</h1>
					<slot name='body'></slot>
					<table border="" cellspacing="" cellpadding="">
						<tr>
							<th>ID</th>
							<th>接口名</th>
							<th>测试人员</th>
							<th>项目名</th>
							<th>项目ID</th>
							<th>描述信息</th>
							<th>创建时间</th>
							<th>用例数</th>
							<th>操作</th>
						</tr>
						<tr :key='item.id' v-for="item in lists">
							<td>{{item.id}}</td>
							<td>{{item.name}}</td>
							<td>{{item.tester}}</td>
							<td>{{item.project}}</td>
							<td>{{item.project_id}}</td>
							<td>{{item.desc}}</td>
							<td>{{item.create_time}}</td>
							<td>{{item.testcases}}</td>
							<th><button @click="$emit('run',item)">执行</button></th>
						</tr>
					</table>
					</div>
					`
			})

			var vm = new Vue({
				el: '#app',
				data: {
					cases1: [{
							"id": 1,
							"name": "登录接口_自动化测试平台项目",
							"tester": "可优",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "登录接口",
							"create_time": "2019-11-06 14:50:30",
							"testcases": 9,
						},
						{
							"id": 2,
							"name": "注册接口_自动化测试平台项目",
							"tester": "可可",
							"project": "自动化测试平台项目",
							"project_id": 1,
							"desc": "自动化测试平台项目, 注册接口",
							"create_time": "2019-11-06 14:51:00",
							"testcases": 0,
						}
					],
					info: ''
				},
				methods: {
					// 父组件中监听到子组件触发的事件之后,接收数据的方法
					recvData: function(value) {
						console.log(value)
						this.info = value
					}
				}

			})
		</script>
		

	</body>
</html>

接口



from flask import Flask, request, jsonify

from flask_cors import CORS

app = Flask(__name__)

#  测试数据
user_info = {"user": 'python01', 'pwd': 'lemonban'}

project_data = {"code": "1",
                "data": [{"title": "前程贷", "id": "1001"},
                         {"title": "智慧金融", "id": "1002"},
                         {"title": "生鲜到家", "id": "1003"},
                         {"title": "柠檬班app", "id": "1004"}],
                "msg": "四个项目",
                }
# 接口数据
interface_data = {
    "1001": {"code": "1",
             "data": [{"name": "前程贷登录1001"},
                      {"name": "前程贷注册1001"}],
             "msg": "2个接口", },

    "1002": {"code": "1",
             "data": [{"name": "智慧-登录1002"},
                      {"name": "智慧-注册1002"},
                      {"name": "智慧-贷款1004"}, ],
             "msg": "3个接口", },

    "1003": {"code": "1",
             "data": [{"name": "生鲜-登录1003"},
                      {"name": "生鲜-注册1003"},
                      {"name": "生鲜下单1003"}, ],
             "msg": "3个接口", },

    "1004": {"code": "1",
             "data": [{"name": "app登录1004"},
                      {"name": "app注册1004"},
                      {"name": "app报名1004"},
                      {"name": "app缴费1004"},
                      ],
             "msg": "4个接口", },
}


# 登录
@app.route('/api/user/login', methods=['post'])
def login():
    """
    接口地址:http://127.0.0.1:5000/api/user/login
    请求方法:post
    参数: {user:账号,pwd:密码}
    参数类型:表单 、json都支持
    返回:该项目的所有接口
    """
    data = request.form or request.json
    # 判断账号,密码是否正确
    if user_info.get('user') == data.get('user') and user_info.get('pwd') == data.get('pwd'):
        return jsonify({'code': "1", "data": None, "msg": "成功"})
    else:
        return jsonify({'code': "0", "data": None, "msg": "密码有误"})


# 获取项目列表
@app.route('/api/projects', methods=['get'])
def pro_list():
    """
    接口地址:http://127.0.0.1:5000/api/projects
    请求方法:get
    参数:无
    返回所有的项目
    :return:
    """
    return jsonify(project_data)


# 获取接口列表
@app.route('/api/interface', methods=['get'])
def interface():
    """
    接口地址:http://127.0.0.1:5000/api/interface
    请求方法:get
    参数: id(项目的id)
    参数类型:查询字符串
    返回:该项目的所有接口

    """
    inter_id = request.args.get('id')

    if inter_id:
        res_data = interface_data.get(inter_id)
        if res_data:
            return jsonify(res_data)
        else:
            return jsonify({"code": "0", "data": None, "msg": "没有该项目"})
    else:
        return jsonify({"code": "0", "data": None, "msg": "请求参数不能为空"})


if __name__ == '__main__':
    cors = CORS(app)
    app.run(debug=True)

前端发送请求,使用axios

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// 使用axios发送一个get请求
			 const pro = axios.get('http://127.0.0.1:5000/api/projects11')
			 // 此处的res并不是接口的响应  它是一个Promise对象(异步事件的对象)
			 console.log(pro)
			// ----------------获取接口返回的数据(请求成功)-------------------
            // response是自己定义的变量,接收返回内容
			 pro.then(function(response){
			 	// 这个回调函数的中的response才是接口返回的响应对象
			 	console.log('接口的响应数据:',response)
			 	// 获取响应体
			 	console.log(response.data)
			 	//获取响应的状态码
			 	console.log((response.status))
			 })
			 console.log('999999999999999999')

			// ----------------获取接口返回的数据(请求失败:返回的状态码是4,5系列的)-------------------
			 pro.catch(function(error) {
			 	// 获取请求失败的响应对象
                // error是自己定义的变量,接收返回内容
			 	console.log(error.response)
			 	let response = error.response
			 	console.log(response.data)
			 	console.log(response.headers)
			 })


			// 自定义HTTP状态码错误的范围
			const pro = axios.get('http://127.0.0.1:5000/api/projects11', {
				validateStatus: function(status) {
					// 指定HTTP状态码错误的范围
					// return status < 500;
					return true
				}
			})

			pro.then(function(response) {
				// 这个回调函数的中的response才是接口返回的响应对象
				console.log('接口的响应数据:', response)
				// 获取响应体
				console.log(response.data)
				//获取响应的状态码
				console.log((response.status))
			})
		</script>
	</body>
</html>

axios设置公用属性

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// 使用axios创建请求对象,类似python实例化类
			const request = axios.create({
				// 指定请求HTTP响应码错误范围
				validateStatus: function(status) {
					return true
				},
				// 指定基本的url地址,后面地址会自动拼接上
				baseURL: "http://127.0.0.1:5000",
				// 添加固定的请求头
				headers: {
					'X-Custom-Header': 'foobar'
				},
			})

			//使用请求对象,url自动拼接baseURL
			request.get('/api/projects').then(function(response) {
				console.log(response.status)
			})
			request.get('/api/projects11').then(function(response) {
				console.log(response.status)
			})
		</script>
	</body>
</html>

get入参

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// 使用axios创建请求对象
			const request = axios.create({
				// 指定请求HTTP响应码错误范围
				validateStatus: function(status) {
					return true
				},
				// 指定基本的url地址
				baseURL: "http://127.0.0.1:5000",
				// 添加固定的请求头
				headers: {
					'X-Custom-Header': 'foobar'
				},
			})
			
			//get方法传递查询字符串参数
			// 方式一 :通过params传递   get('url',{params:{key:value,key:value}})
			
			 request.get('/api/interface',{
			 	params:{id:1001}
			 }).then(function(response) {
			 	console.log(response.status)
			 	console.log(response.data)
			 })
			// 方式二:直接在url后面拼接  url?key=value&key=value
			
			 request.get('/api/interface?id=1001').then(function(response) {
			 	console.log(response.status)
			 	console.log(response.data)
			 })
		</script>



	</body>
</html>

post入参

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// 使用axios创建请求对象
			const request = axios.create({
				// 指定请求HTTP响应码错误范围
				validateStatus: function(status) {
					return true
				},
				// 指定基本的url地址
				baseURL: "http://127.0.0.1:5000",
				// 添加固定的请求头
				headers: {
					'X-Custom-Header': 'foobar'
				},
			})
			// 发送post请求
			// 第一种,json格式的参数传递: content-Type:application/json
			 request.post('/api/user/login',{user:'python01',pwd:'lemonban'}).then(function(response){
			 	console.log(response.data)
			 	console.log(response.status)
			 })

			// 第二种,表单参数传递:content-Type:application/x-www-form-urlencoded format
			// 创建表单参数对象
			 const formData = new URLSearchParams();
			 formData.append('user', 'python01')
			 formData.append('pwd', 'lemonban')
			 request.post('/api/user/login', formData).then(function(response) {
			 	console.log(response.data)
			 	console.log(response.status)
			 })
		</script>
	</body>
</html>

axios请求拦截器

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// 使用axios创建请求对象
			const request = axios.create({
				// 指定请求HTTP响应码错误范围
				validateStatus: function(status) {
					return true
				},
				// 指定基本的url地址
				baseURL: "http://127.0.0.1:5000",
				// 添加固定的请求头
			})
			
			// 添加请求拦截器:每次请求接口都会自动调用
			request.interceptors.request.use(function (config) {
			    // 在发送请求之前做些什么
				// 接口需要鉴权:token
				console.log('请求拦截器:',config)
			    return config;
			  });

			// 添加响应拦截器:每次请求完之后,A返回响应数据之前会调用。
			request.interceptors.response.use(function (response) {
			    // 对响应数据做点什么
			    return response.data;
			  }, function (error) {
			    // 对响应错误做点什么
			    return error.response;
			  });

			//使用请求对象
			request.get('/api/projects').then(function(data) {
				console.log(data)
			})
		</script>
	</body>
</html>

async和await发起请求

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// 使用axios创建请求对象
			const request = axios.create({
				// 指定请求HTTP响应码错误范围
				validateStatus: function(status) {
					return true
				},
				// 指定基本的url地址
				baseURL: "http://127.0.0.1:5000",
				// 添加固定的请求头
			})

			// 添加请求拦截器:每次请求接口都会自动调用
			request.interceptors.request.use(function(config) {
				// 在发送请求之前做些什么
				// 接口需要鉴权:token
				console.log('请求拦截器:', config)
				return config;
			});

			// 添加响应拦截器:每次请求完之后,A返回响应数据之前会调用。
			request.interceptors.response.use(function(response) {
				// 对响应数据做点什么
				return response;

			}, function(error) {
				// 对响应错误做点什么
				return error.response;
			});

			// 使用请求对象
			// 注意点:await 和只能在通过async定义的函数中使用
			async function getProjec() {
				const response = await request.get('/api/projects')
				console.log(response)
			}
			getProjec()
		</script>
	</body>
</html>

登录Demo

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <!-- 引入vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!-- 引入/element-ui -->
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
    <!-- 引入axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <style>
        #app {
            width: 300px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        #buttonLogin {
            width: 200px;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
    </style>
</head>
<body>
<div id="app">
    <el-form ref="form" :model="form" label-width="80px">
        <el-form-item label="账号">
            <el-input v-model="formLogin.user"></el-input>
        </el-form-item>
        <el-form-item label="密码">
            <el-input v-model="formLogin.pwd" type='password'></el-input>
        </el-form-item>
        <el-form-item>
            <el-button id='buttonLogin' type="primary" @click="loginHandle">点击登录</el-button>
        </el-form-item>
    </el-form>
</div>
</body>

<script type="text/javascript">
    const request = axios.create({
        // 指定请求HTTP响应码错误范围
        validateStatus: function (status) {
            return true
        },
        // 指定基本的url地址
        baseURL: "http://127.0.0.1:5000",
        // 添加固定的请求头
        headers: {
            'X-Custom-Header': 'foobar'
        },
    })

    // 添加请求拦截器:每次请求接口都会自动调用
    request.interceptors.request.use(function (config) {
        // 在发送请求之前做些什么
        // 接口需要鉴权:token
        console.log('请求拦截器:', config)
        token = window.sessionStorage.getItem('token')
        console.log(token)

        // 在请求头中添加token
        return config;
    });

    var vm = new Vue({
        el: '#app',
        data: {
            formLogin: {
                user: '',
                pwd: ''
            }
        },
        methods: {
            // 点击登录之后,处理登录的方法
            loginHandle: async function () {
                // 请求登录接口
                const response = await request.post('/api/user/login', this.formLogin)
                if (response.data.code === '1') {
                    alert('登录成功')
                    window.sessionStorage.setItem('token', 'asasasasasas')
                } else {
                    alert(response.data.msg)
                }
            }
        }
    })
</script>
</html>

前端路由

单页面应用spa

第一步:定义展示页面内容的组件
第二步:定义路由规则
第三步:初始化路由对象
第四步:将路由对象绑定到vue实例中去
第五步:在根组件中定义路由视图的展示位置
注意点:如果在html页面中使用vuerouter  在使用script引入的时候 一定要放在vue下面
			
路由配置:
	path:指定路由路径
	name:给路由命名
	redirect:指定路由重定向的路径
    component:指定该路由渲染的组件
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<!-- 引入vue -->
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<!-- 引入vue-router -->
		<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js" type="text/javascript"></script>
	</head>
	<body>
		<div id="app">
			<router-link to="/home">主页跳转按钮</router-link>
			<router-link to="/login">登录跳转按钮</router-link>
			<!-- 路由视图,第五步:在根组件中定义路由视图的展示位置 -->
			<router-view></router-view>
		</div>
		<script type="text/javascript">
			// 首页,第一步:定义展示页面内容的组件
			const home = {
				template: `<h1>这个是项目首页</h1>
				`
			}
			// 登录页面,第一步:定义展示页面内容的组件
			const login = {
				template: `
				<h1>这个是项目登录页面</h1>
				`
			}
			// 第三步:初始化路由对象
			const router = new VueRouter({
				//通过路由routes指定路由规则,第二步:定义路由规则
				routes: [{
						path: '/',
						// 设置路由重定向
						redirect: '/login'
					},
					{
						path: '/login',
						component: login,
						// 给路由设置名字
						name:'login'
					},
					{
						path:'/home',
						component:home
					}

				]
			})

			var vm = new Vue({
				el: '#app',
				// 第四步:将路由对象绑定到vue实例中去
				router
			});
		</script>
	</body>
</html>

编程式路由和声明式路由

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
		<script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js" type="text/javascript"></script>
		<!-- 引入vue -->
	</head>
	<body>
		<div id="app">
			<div class="box">
				<!-- 这个路由访问的方式,叫做声明式路由 -->
				<router-link to="/home"><button type="button">用户页面</button></router-link>
				<router-link to="/login"><button type="button">登录页面</button> </router-link>
				<router-link to="/user/1"><button type="button">用户</button> </router-link>
				<router-link to="/user/2"><button type="button">用户</button> </router-link>
				<input type="text" v-model="number">
				<button type="button" @click="handle">提交数据</button>
			</div>

			<router-view></router-view>
		</div>
		<script type="text/javascript">
			// 首页
			const home = {
				template: `<h1>这个是项目首页</h1>
				`
			}
			const cases = {
				template: `<h1>case页面</h1>
				`
			}
			// 登录页面
			const login = {
				template: `
				<h1>这个是项目登录页面</h1>
				`
			}
			const user = {
				template: `
				<h1>这个是项目user页面---{{ $route.params.id }}</h1>
				`
			}
			// 创建一个路由对象
			const router = new VueRouter({
				//通过路由route指定路由规则
				routes: [{
						path: '/login',
						// 给路由设置名字
						name: 'login',
						component: login
					},
					{
						path: '/home',
						component: home
					},
					{
						path: '/case',
						component: cases
					},
					{	// 路由地址上匹配的参数,在路由对应的组件中可以使用 $route.params.参数名  获取
						path: '/user/:id',
						component: user,
						name: 'user'
					},
				]
			})

			var vm = new Vue({
				el: '#app',
				data: {
					number: 0
				},
				methods: {
					handle: function() {
						if (this.number > 5) {
							// 编程式路由
							//跳转到另外一个页面
							this.$router.push({
								name: 'user',
								params: {
									id: this.number
								}
							})
						}
					}
				},
				// 将路由对象绑定到vue实例中
				router
			});
		</script>
	</body>
</html>

表单相关处理

<template>
	<div style="background: #55aaff; height: 900px;">
		<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>
	</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('/user/login/', this.formLogin)
					console.log(response)
					// 判断登录请求是否成功 
					if (response.status === 200) {
						this.$message({
							message: '登录成功',
							type: 'success',
							duration:1000
						});
						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;
		position: absolute;
		top: 200px;
		left: 500px;
	}

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

包含分页,创建弹窗

<template>
	<div class="project_list">
		<el-card class="box-card">
			<!-- 顶部的面包屑 -->
			<div slot="header" class="clearfix">
				<el-breadcrumb separator-class="el-icon-arrow-right">
					<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
					<el-breadcrumb-item>项目管理</el-breadcrumb-item>
					<el-breadcrumb-item>项目列表</el-breadcrumb-item>
				</el-breadcrumb>
			</div>
			<el-card class="box-card">
				<!-- 添加项目的按钮 -->
				<el-button type="primary" icon='el-icon-plus'>创建项目</el-button>
				<!-- 项目列表页 -->
				<el-table :data="projectList" style="width: 100%;margin-bottom: 10px;">
					<el-table-column prop="id" label="ID" width="80" sortable>
					</el-table-column>
					<el-table-column prop="name" label="项目名" width="200">
					</el-table-column>
					<el-table-column prop="desc" label="描述信息" width="280">
					</el-table-column>
					<el-table-column prop="leader" label="负责人" width="100" sortable>
					</el-table-column>
					<el-table-column prop="tester" label="测试人员" width="100">
					</el-table-column>
					<el-table-column prop="interfaces" label="接口数量" width="120" sortable>
					</el-table-column>
					<el-table-column prop="testcases" label="用例数量" width="80">
					</el-table-column>
					<el-table-column prop="testsuits" label="套件数量" width="80">
					</el-table-column>
					<el-table-column label="操作">
						<template slot-scope="scope">
							<el-button size="mini" @click="proEdit(scope.row)">编辑</el-button>
							<el-button size="mini" type="danger" @click="proDelete(scope.row.id)">删除
							</el-button>
						</template>
					</el-table-column>
				</el-table>
				<!-- 项目翻页管理 -->
				<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
					:current-page="page" :page-sizes="[5, 10, 20, 30]" :page-size="size"
					layout="total, sizes, prev, pager, next, jumper" :total="count">
				</el-pagination>
			</el-card>
		</el-card>

		<!-- 编辑项目的弹框 -->
		<el-dialog title="编辑项目" :visible.sync="dialogEdit">
			<el-form :model="editProject">
				<el-form-item label="项目名">
					<el-input v-model="editProject.name" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="负责人">
					<el-input v-model="editProject.leader" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="测试人员">
					<el-input v-model="editProject.tester" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="开发人员">
					<el-input v-model="editProject.programmer" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="发布应用">
					<el-input v-model="editProject.publish_app" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="描述信息">
					<el-input v-model="editProject.desc" autocomplete="off"></el-input>
				</el-form-item>
			</el-form>
			<div slot="footer" class="dialog-footer">
				<el-button @click="dialogEdit = false">取 消</el-button>
				<el-button type="primary" @click="updateProject">确 定</el-button>
			</div>
		</el-dialog>


	</div>
</template>

<script>
	export default {
		data() {
			return {
				projectList: [],
				// 当前选择的页码
				page: 1,
				// 数据总数
				count: 0,
				//每页的数据量
				size: 10,
				//编辑窗口显示
				dialogEdit: false,
				editProject: {}
			}
		},
		methods: {
			// 编辑项目
			proEdit(value) {
				console.log(value)
				// 把接收到的项目数据,
				this.editProject = {...value}
				// 显示编辑框
				this.dialogEdit = true
			},
			
			// 请求修改项目的接口
			async updateProject(){
				const response = await this.$request.put('/projects/' +this.editProject.id  +'/',this.editProject)
				if (response.status===200){
					this.$message({
						message: '修改项目成功',
						type: 'success',
						duration: 1000
					});
					this.getProject()
					this.dialogEdit = false
				}else{
					this.$message({
						message: '修改失败',
						type: 'error',
						duration: 1000
					});
				}
			},
			
	
			// 删除项目
			async proDelete(id) {
				console.log('当前删除的数据id为:', id)
				// 通过接口删除后端数据
				const response = await this.$request.delete('/projects/' + id +'/')
				//  后端接口是安装resetful规范设计的,delete方法成功时,返回的状态码为204
				if (response.status === 204) {
					// 删除成功
					this.$message({
						message: '删除成功',
						type: 'success',
						duration: 1000
					});
					// 重写加载数据
					this.getProject()
				} else {
					this.$message({
						message: '删除失败',
						type: 'error',
						duration: 1000
					});
				}
			},
			// 获取项目
			async getProject() {
				// 请求项目列表的接口,获取所有的项目
				const response = await this.$request.get('/projects/', {
					params: {
						page: this.page,
						size: this.size
					}
				})
				if (response.status !== 200) return this.$message.error('服务器异常')
				// 保存接口返回的项目列表
				this.projectList = response.data.results
				// 保存数据总数
				this.count = response.data.count
				console.log(response)
			},
			// 处理每页数量大小变化的方法
			handleSizeChange(size) {
				this.size = size
				this.page = 1
				this.getProject()
			},
			// 处理页码变化的方法
			handleCurrentChange(page) {
				this.page = page
				this.getProject()
			}
		},

		// vue实例数据挂载之后,出触发这个钩子函数
		mounted() {
			this.getProject()
		}




	}
</script>

<style>
</style>

格栅,删除列表,监听数据,写了个postman

<template>
	<div class="caseEdit">
		<el-card class="box-card">
			<!-- 顶部的面包屑 -->
			<div slot="header" class="clearfix">
				<el-breadcrumb separator-class="el-icon-arrow-right">
					<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
					<el-breadcrumb-item>用例管理</el-breadcrumb-item>
					<el-breadcrumb-item>用例编辑</el-breadcrumb-item>
				</el-breadcrumb>
			</div>
			<!-- 显示主体内容的卡片 -->
			<el-card class="box-card">
				<el-divider content-position="left"><span style="color: #409EFF; font-weight: bold;">Api</span>
				</el-divider>
				<!-- api请求的基本信息 -->
				<el-row :gutter="20">
					<!-- 请求方法选择 -->
					<el-col :span="3">
						<el-select v-model="caseInfo.method" placeholder="请求方法">
							<el-option label="GET" value="GET"></el-option>
							<el-option label="POST" value="POST"></el-option>
							<el-option label="PUT" value="PUT"></el-option>
							<el-option label="DELETE" value="DELETE"></el-option>
							<el-option label="PATCH" value="PATCH"></el-option>
							<el-option label="HEAD" value="HEAD"></el-option>
							<el-option label="OPTION" value="OPTION"></el-option>
						</el-select>
					</el-col>
					<!-- host地址输入 -->
					<el-col :span="9">
						<el-input placeholder="host地址" v-model="caseInfo.host">
							<template slot="prepend">Host</template>
						</el-input>
					</el-col>
					<!-- 接口地址输入 -->
					<el-col :span="9">
						<el-input placeholder="接口路径" v-model="caseInfo.interface">
							<template slot="prepend">接口地址</template>
						</el-input>
					</el-col>
					<!-- 运行按钮 -->
					<el-col :span="3">
						<el-button type="primary" icon="el-icon-s-promotion">Run</el-button>
					</el-col>
				</el-row>
				<el-divider content-position="left"><span style="color: #409EFF; font-weight: bold;">Request</span>
				</el-divider>
				<!--用例信息 -->
				<el-tabs type="border-card">
					<!-- 请求头 -->
					<el-tab-pane label="请求头">
						<el-row :gutter="20" v-for='header in caseInfo.headers' :key='header.key' style="margin: 10px;">
							<el-col :span="6">
								<el-input v-model.lazy="header.key" placeholder="KEY"></el-input>
							</el-col>
							<el-col :span="12">
								<el-input v-model.lazy="header.value" placeholder="VALUE"></el-input>
							</el-col>
							<el-col :span="6">
								<el-button type="danger" icon="el-icon-delete" @click='deleteRow(header)'></el-button>
							</el-col>
						</el-row>
					</el-tab-pane>
					<!-- 请求参数 -->
					<el-tab-pane label="请求参数">
						<el-tabs>
							<el-tab-pane label="application/json" name="second">
								<editor height="300" width="100%" ref="editor" :content="caseInfo.json"
								    v-model="caseInfo.json" :options="{
								    enableBasicAutocompletion: true,
								    enableSnippets: true,
								    enableLiveAutocompletion: true,
								    tabSize:2,
								    fontSize:20,
								    showPrintMargin:false,}" :lang="'json'" @init="editorInit">
								</editor>
							</el-tab-pane>
							<el-tab-pane label="Params" name="first">查询字符串参数</el-tab-pane>
							<el-tab-pane label="application/X-www-urlencode" name="third">表单参数</el-tab-pane>
						</el-tabs>

					</el-tab-pane>
					<el-tab-pane label="响应提取">响应提取</el-tab-pane>
					<el-tab-pane label="用例断言">用例断言</el-tab-pane>
					<el-tab-pane label="数据库校验">数据库校验</el-tab-pane>
				</el-tabs>

			</el-card>
		</el-card>

	</div>
</template>

<script>
	import Editor from 'vue2-ace-editor'
	
	export default {
		data() {
			return {
				caseInfo: {
					method: 'GET',
					host: '',
					interface: '',
					headers: [{
						key: '',
						value: ''
					}],
					params:[{
						key: '',
						value: ''
					}],
					data:[{
						key: '',
						value: ''
					}],
					json:'{}'
				}
			}
		},
		methods: {
			deleteRow(header) {
				console.log(header)
				// 删除一行内容
				const newHeaders = this.caseInfo.headers.filter(function(item, index) {
					return item !== header
				})
				this.caseInfo.headers = newHeaders
			},
			editorInit() {
			    require('brace/theme/chrome')
			    require('brace/ext/language_tools')
			    require('brace/mode/yaml')
			    require('brace/mode/json')
			    require('brace/mode/less')
			    require('brace/snippets/json')
			}
		},
		watch: {
			// 监听headers中的数据是否发送变化,当发送变化时,则判断最后一行是否有值,
			'caseInfo.headers': {
				handler: function(value, oldVal) {
					if (value.length === 0) {
						this.caseInfo.headers.push({
							key: '',
							value: ''
						})
					}
					// 判断最后一行是否有值,
					if (value[value.length - 1].key || value[value.length - 1].value) {
						this.caseInfo.headers.push({
							key: '',
							value: ''
						})
					}

				},
				deep: true
			}

		},
		components:{
			Editor
		}
		
		



	}
</script>

<style scoped>
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秦朝胖子得加钱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值