Vue的芝士

Vue介绍

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue组件说明

在这里插入图片描述

MVVM 设计思想

知识回顾: MVC模式 核心思想 减少代码的耦合性
M Model:封装的数据
V View 视图层: 数据的展现
C Contro 控制层 程序的流转的过程
衍生: 3层代码的结构 Controller—Service–Mapper/Dao
针对于: 后端服务器.

MVVM思想说明:
M: Model 封装的数据. 数据层
V: View 数据的展现 视图层
VM: viewModel视图数据的控制层 控制数据流转
MVVM设计思想是前端模拟后端为了解耦的一种设计思想.

双向数据绑定原理

原理步骤:
1.用户修改页面时,通过DOM的监听器感知用户的修改行为,之后通过虚拟DOM对象,第一时间更新Model中的属性.
2.当数据发生变化,由虚拟DOM根据数据绑定的规则,第一事件通知真实的DOM对象.至此页面数据发生变化.

Vue对象的生命周期

周期:
1.初始化周期
1.beforeCreate vue对象实例化之前(刚开始)
2. created
3. beforeMount
4. Mounted 说明VUE对象实例化成功(DIV渲染完成)
2.修改周期

  1. beforeUpdate 用户修改数据之前
  2. updated 用户修改数据之后
    3.销毁周期
  3. beforeDestroy VUE对象销毁前
  4. destroyed VUE对象销毁后(最后一步)

** 生命周期函数的作用:
如果需要对VUE对象中的数据进行额外的操作.则使用生命周期函数.
目的: 框架的扩展性更好.(实现定制化) **
在这里插入图片描述

Vue基础语法

插入表达式 {{Key}}
const 定义常量
let 定义变量,有作用域
var 定义变量,没有作用域

总结:
数据显示:

  • v-text 如果页面没有渲染完成,则不显示
  • v-html 渲染html标签
  • v-pre 跳过预编译直接显示标签中的内容
  • v-once 只渲染一次,更改内存内容也不会更改页面的数据
    双向数据绑定
  • 实现网页与数据的绑定,页面变数据变/数据变页面变
  • v-model 绑定标签与Vue对象属性的绑定
    事件绑定
  • v-on:事件=“函数/直接进行计算”
    • 简写方式:@事件=“函数/直接进行计算”
  • 阻止冒泡.stop
    • 元素的嵌套导致事件可能会发生嵌套,如果事件嵌套那么必然会带来事件的冒泡
    • @事件.stop
  • 阻止默认行为.prevent
    • 阻止标签带来的默认行为,例如标签的跳转页面
    • @事件.prevent
      属性绑定
  • v-bind:属性
    • 简写方式 :属性
  • class绑定 如果用户需要切换class则可以使用该操作,数据是否展现可以通过 {class类型: true/false}
    分支结构
  • 用法:
    • 如果数据为真则展现html标签
  • 语法:
    • v-if / v-else-if / v-else
  • 要求:
    • v-if 可以单独使用,v-else-if / v-else 必须与 v-if配合使用
      循环结构
  • 用法:
    • 通过循环展现标签+数据
  • 语法:
    • value值 key值 index下标
    • v-for((value,index) in array) 遍历数组的值与下标
    • v-for((value,key,index)in array) 遍历对象
    • v-for(user in array) 遍历嵌套结构 数组中的对象
      数组操作
  • push() 结尾追加元素
  • pop() 删除结尾元素
  • shitf() 删除开头元素
  • unshitf() 添加开头元素
  • splice() 替换数组中的数据
    • arg1 起始位置
    • arg2 操作几个
    • arg3 替换成什么
    • 如果只有两个参数那么是删除的意思
  • sort() 数据的排序 数字123 大写字母ABC 小写字母abc
  • reverse() 数组的反转

入门案例

步骤:
1、导入Vue.js文件,位置处于html下部
2、指定区域进行渲染,需要准备div标签,div标签中存放vue.js代码
3、创建Vue.js对象 指定渲染区域,动态调用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>入门案例</title>
	</head>
	<body>
		<!-- 2、指定区域 -->
		<div id="app" >
			<!-- 4.展示Vue对象的属性  {{插入表达式}} -->
			{{msg}}
		</div>
		
		<!-- 1、导入Vue.js文件 -->
		<script src="../js/vue.js"></script>
		
		<!-- 3、创建Vue.js对象 -->
		<script>
			const app = new Vue({
				<!-- 3.1 指定区域 -->
				el: "#app",
				<!-- 3.2 定义属性 -->
				data: {
					msg: "hello Vue"
				}
			})
		</script>
	</body>
</html>

指令

数据显示

v-text 如果页面没有渲染完成,则不显示
v-html 渲染html标签
v-pre 跳过预编译直接显示标签中的内容
v-once 只渲染一次,更改内存内容也不会更改页面中的数据

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>数据显示</title>
	</head>
	<body>
		<div id="app">
			<!-- 特点: 如果页面没有渲染完成,则直接展现给用户
					   插值表达式需要直接显示
				 注意事项:  只有显示时采用,输入操作不可使用
				 1.v-text指令: 如果页面没有渲染完成,则不显示信息
			 -->
			 {{msg}}
			<h1 v-text="msg"></h1>
	
			<!-- 2.v-html 直接渲染html标签 -->
			<div v-html="h3Html"></div>
			
			<!-- 3.v-pre  跳过预编译 显示标签体本身 -->
			<div v-pre>{{msg}}</div>
			
			<!-- 4.v-once 只渲染一次 -->
			<div v-once>{{once}}</div>
			
			
		</div>
	<!--  -->	
		<!-- 1.导入JS文件 -->
		<script src="../js/vue.js"></script>
		
		<!-- 3.创建VUE对象 -->
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					msg: "您好VUE",
					h3Html: "<h3>我需要html渲染</h3>",
					once: "我只能被渲染一次"
				}
			})
		</script>	
	</body>
</html>
双向数据绑定

实现网页与数据的绑定,页面变数据变/数据变页面变

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>数据显示</title>
	</head>
	<body>
		<div id="app">
			<!-- 双向数据绑定 v-model
				1.数据端---页面
				2.页面-----数据
			   -->
			<input name="msg" v-model="msg"/><br>
			{{msg}}
			
		</div>
		<!-- 1.导入JS文件 -->
		<script src="../js/vue.js"></script>
		
		<!-- 3.创建VUE对象 -->
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					msg: "数据随时修改"
				}
			})
		</script>	
	</body>
</html>
事件绑定

v-on:click=“函数/直接进行计算”

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>事件绑定</title>
	</head>
	<body>
		
		<div id="app" >
			<h1>{{num}}</h1>
			<button v-on:click="num++">自增v-on</button>
			<button @click="num--">简化版本自减@</button>
			<button @click="addNum()">函数自增</button>
			<button @click="nuaddNum()">函数自减</button>
			
		</div>
		
		<script src="../js/vue.js" ></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					msg: "随时改变",
					num: 100
				},
				methods: {
					addNum: function(){
						this.num++
					},
					nuaddNum(){
						this.num--
					}
				}
			})
			
		</script>
	</body>
</html>
按键触发机制
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>按键触发操作</title>
	</head>
	<body>
		<div id="app">
			<!-- 
				 语法:	
					1.v-on:keydown="" 按下触发
					2.v-on:keyup=""   弹起来触发
					3.v-on:keypress="" 小键盘触发
				 按键支持:
					.enter  .tab
					.delete (捕获“删除”和“退格”键)
					.esc   .space
					.up .down .left .right
				 
				 需求:用户通过输入 按特殊的键位触发函数 
				 要求1. 按钮实现加法操作 num = num + num2
				 要求2. 用户按回车按钮实现触发 
				 要求3. 用户按空格键实现触发 
			-->
			<h3>用户数据:{{num}}</h3><br>
			<!-- <input type="text" v-on:keyup.enter="addNum" v-model="num2" /> -->
			<input type="text" v-on:keyup.space="addNum" v-model="num2" />
			<button @click="addNum">计算</button>
			
			
		</div>
		<script src="../js/vue.js"></script>
		
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					num: 100,
					num2: 0
				},
				methods: {
					addNum(){
						//this.num = this.num + this.num2
						//将字符串转化为数值类型
						this.num +=   parseInt(this.num2) 
					}
				}
			})
		</script>	
	</body>
</html>
计算机练习
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>计算器案例</title>
	</head>
	<body>
		
		<div id="app">
			<!-- 要求
				1.准备两个文本输入框 num1/num2
				2.要求准备一个按钮 "计算" 当点击按钮时实现
				  count=num1+num2
				  将得到的结果通过 总数输出count
				3.当输入num2时可以通过回车按键 计算.
				注意事项: input框默认是字符串
			 -->
			 
			 数值1: <input type="text" v-model="num1" /><br>
			 数值2: <input type="text" v-model="num2" 
				@keyup.enter="addNum"
			 /><br>
			 总数:  {{count}} <br>
			 <button @click="addNum">计算</button>
			
		</div>
		<script src="../js/vue.js"></script>
		
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					num1: 0,
					num2: 0,
					count: 0
				},
				methods: {
					addNum(){
						this.count = 
							parseInt(this.num1) +  parseInt(this.num2)
					}
				}
			})
		</script>	
	</body>
</html>
按键修饰符
阻止冒泡 .stop
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>按键修饰符</title>
	</head>
	<body>
		
		<div id="app">
			<!-- 难点: 元素可能需要嵌套,事件可能嵌套
				 说明: 如果事件嵌套则必然带来事件的冒泡.
				 解决方案: 阻止事件冒泡  .stop属性
			 -->
			数值: {{num}}
			<div @click="num++">
				嵌套结构
				<button @click.stop="num++">计算</button>
			</div>
		<script src="../js/vue.js"></script>
		
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					num: 0
				},
				methods: {
					
				}
			})
		</script>	
	</body>
</html>
阻止默认行为 .prevent
<!-- 需求2:
				 a标签作用中的href的跳转是默认规则
				 要求: 用户点击a标签 不跳转页面,同时触发事件
				 解决: 阻止标签的默认行为  @click.prevent	
			 -->
			<a href="http://baidu.com" @click.prevent="aClick">百度</a>
			
			<!-- 用途: prevent阻止页面跳转  a标签/form表单 action同步请求 -->
属性绑定

属性绑定 v-bind:xxxx 动态为属性赋值
class绑定 如果用户需要切换class 则可以使用该操作
class绑定 数据是否展现 可以通过 {class类型: true/false}

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>属性绑定</title>
		<style>
			
			/* red 红色 宽度50  高度50 */
			.red {
				background-color: red;
				width: 50px;
				height: 50px;
			}
			
			.blue {
				background-color: aqua;
				width: 100px;
				height: 100px;
			}
			
		</style>
	</head>
	<body>
		<div id="app">
			<!-- a标签的属性绑定
				需求: href中的属性动态赋值
				语法: v-bind:href="VUE中的属性"
			 -->
			<a v-bind:href="url">百度</a>
			<!-- 简化写法 -->
			<a :href="url">百度</a>
			<hr />
			
			<!-- 2.class类型绑定 
				class中可以定义多个样式.简化程序的调用
				需求: 需要动态的为class赋值
				规则: :class是属性的绑定,绑定之后查找对应的属性
				colorClass: "blue" 之后根据value值 blue 查找对应的CSS样式
				15上课
			-->
			<div :class="colorClass">我是class修饰</div>
			<hr >
			
			<!-- 3. 属性切换 
				    需求: 通过按钮控制样式是否展现 属性
					语法: :class={class类型的名称: false}
			-->
			<div :class="{red: flag}">我是class修饰</div>
			<button @click="flag = !flag">切换</button>
			
		</div>
		<script src="../js/vue.js"></script>
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					url: "http://www.baidu.com",
					colorClass: "blue",
					flag: true
				}
			})
		</script>	
	</body>
</html>
分支结构

用法: 如果数据为真则展现html标签
语法: v-if/v-else-if/v-else
要求: v-if可以单独使用
另外2个必须与v-if连用

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>属性绑定</title>
		<style>
			
		</style>
	</head>
	<body>
		<div id="app">
			<!-- 分支结构
				语法: 
					1.v-if   如果为真则展现标签
					2.v-else-if  必须与v-if连用
					3.v-else 	 必须与v-if连用	取反
				案例:
					要求: 按照用户的考试成绩 评级
						  >=90分  优秀
						  >=80分  良好
						  >=70分  中等
						  >=60分  及格
						  否则    不及格
			 -->
			<h3>评级</h3>
			请录入分数: <input v-model="score" />
			<div v-if="score >= 90 ">优秀</div>
			<div v-else-if="score >= 80 ">良好</div>
			<div v-else-if="score >= 70 ">中等</div>
			<div v-else-if="score >= 60 ">及格</div>
			<div v-else>不及格</div>
			
		</div>
		<script src="../js/vue.js"></script>
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					score: 70
				}
			})
		</script>	
	</body>
</html>
循环结构

用法: 通过循环 展现标签+数据
语法:
v-for((value,index) in array)
v-for((value,key,index) in obj)
v-for(user in userList) 后续通过user.属性取值

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>循环结构</title>
		<style>
			
		</style>
	</head>
	<body>
		<div id="app">
			<!-- 
				1.什么时候使用循环
					多次重复的执行同一个操作.
				2.什么数据使用循环
					1.数组
					2.对象
					3.数组套对象(集合)
			 -->
			 
			 <!--
					1. 遍历数据 将数组中的数据在页面中展现
			  -->
			 <p v-for="item in array" v-text="item">
				<!-- {{item}} -->
			 </p>
			 
			 <!-- 2. 获取下标  30上课
				  语法: v-for="(遍历的元素,遍历的下标) in array"
			  -->
			 <p v-for="(item,index) in array">
					下标:{{index}}~~~数据值:{{item}}
			 </p>
			 <hr >
			 <!-- 2. 遍历对象 
				v-for="(value,key,index下标)
			 -->
			 <p v-for="(value,key,index) in user">
				 {{index}}~~~~{{key}}~~~~{{value}}
			 </p>
			 
			 <!-- 3. 遍历"集合" -->
			 <p v-for="user in userList">
				 ID: {{user.id}}
				 | name: {{user.name}} 
				 | age:{{user.age}}
				<!-- <p v-for="(value,key,index) in user">
					 
				 </p> -->
			 </p>
			 
			 <!-- 总结:
				 1. 如果遍历数组 参数 (value,index)
				 2. 如果遍历对象 参数 (value,key,index)
				 特点: 遍历数据在页面中展现
			 -->
			 
		</div>
		<script src="../js/vue.js"></script>
		<script>
			const APP = new Vue({
				el: "#app",
				data: {
					array: ["郭晶晶","马龙","姚明"],
					user: {
						id: 100,
						name: "tomcat",
						age: 18
					},
					userList: [
						{
							id: 100,
							name: "tomcat",
							age: 18
						},
						{
							id: 200,
							name: "mysql",
							age: 20
						}
					]
				}
			})
		</script>	
	</body>
</html>
form表单数据绑定
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>常用表单属性</title>
	</head>
	<body>
		<h1>本案例练习 表单提交数据时  数据如何与vue进行数据绑定</h1>
		<div id="app">
			<form id="userForm"action="http://www.baidu.com">
				<div>
					<span>
						姓名:
					</span>
					<span>
						<input type="text" name="name" v-model="name"/>
					</span>
				</div>
				<div>
					<span>性别:</span>
					<span>
						<!-- 单选框: name属性必须一致 -->
						<input type="radio" name="gender" value="男" id="man" v-model="gender"/>
						<label for="man"></label>
						<input type="radio" name="gender" value="女" id="women" v-model="gender"/>
						<label for="women"></label>
					</span>
				</div>
				<div>
					<span>爱好:</span>
					<input type="checkbox" name="hobbies" value="吃" v-model="hobbies"/><input type="checkbox" name="hobbies" value="喝" v-model="hobbies"/><input type="checkbox" name="hobbies" value="玩" v-model="hobbies"/></div>
				<div>
					<span>职业</span>
					<!-- 如果需要设置为多选 则添加属性 -->
					<select name="occupation" v-model="occupation" multiple="true">
						<option value="工人">工人</option>
						<option value="教师">教师</option>
						<option value="工程师">工程师</option>
					</select>
				</div>
				<div>
					<span>个人简介</span>
					<textarea name="userInfo" style="width: 200px;height: 50px;" v-model="userInfo"></textarea>
				</div>
				<div>
					<!-- 阻止默认提交事件 -->
					<input type="submit"  value="提交" v-on:click.prevent="submitForm"/>
				</div>
			</form>
		</div>
		
		
		<!-- 引入JS文件 -->
		<script src="../js/vue.js"></script>
		<script>
			const app = new Vue({
				el:	"#app",
				data: {
					name: '输入名称',
					gender: '女',
					//多个数据定义时 应该使用数组
					hobbies:	['吃','喝','玩'],
					occupation: ['工人'],
					userInfo: ''
				},
				methods: {
					submitForm(){
						//数据提交
						console.log("姓名:"+this.name)
						console.log("性别:"+this.gender)
						console.log('爱好:'+this.hobbies)
						console.log('职业:'+this.occupation)
						console.log('用户详情:'+this.userInfo)
						console.log('封装好数据之后,可以使用ajax方式实现数据提交')
					}
				}
			})
		</script>
	</body>
</html>
表单修饰符

一般数据进行提交时都会使用表单.
每个表单几乎都写action. action现在几乎不用(同步操作)
一般通过 阻止默认行为的方式 禁用action,之后手写点击事件触发后续操作(Ajax)
用户录入标签体 1.文本框 2.单选 3.多选 4.下拉框 5.文本域
掌握各个标签的双向数据绑定的写法. 值有多个 使用数组.
表单修饰符 1.number 2.trim 3.lazy

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>表单修饰符</title>
	</head>
	<body>
		<h1>表单修饰符number/trim/lazy</h1>
		<div id="app">
			<!-- 
				语法:
					.number 只能输入数值类型
					.trim   去除左右空格
					.lazy   离焦事件才触发
			 -->
			 <h3>数据展现: {{age}}</h3>
			 年龄: <input type="text" v-model.number="age" />
			 <button @click="addNum">增加</button>
			 <hr />
			 用户输入的长度: {{name.length}} <br>
			 用户名: <input type="text" v-model.trim="name" />	
			 <hr />
			 展现数据lazy~~{{msg}}  <br>
			 <input type="text" v-model.lazy="msg"/>
		</div>
		
		
		<!-- 引入JS文件 -->
		<script src="../js/vue.js"></script>
		<script>
			const app = new Vue({
				el:	"#app",
				data: {
					age: 18,
					name: '',
					msg: ''
				},
				methods: {
					addNum(){
						this.age += 1
					}
				}
			})
		</script>
	</body>
</html>
计算属性

复杂的操作如果通过{{}} 插值表达式封装 比较冗余.
如果将复杂的操作封装为方法 调用一次执行一次 效率低.
计算属性:
1.可以封装复杂操作
2.内部有缓存机制,只需要计算一次.多次调用 效率高

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>计算属性</title>
	</head>
	<body>
		<h1></h1>
		<div id="app">
			<!-- 需求:
				 将用户的输入内容进行反转
				 API:
					1.字符串转化为数组 拆串 split('')
					2.将数组倒序		.reverse()
					3.将数组转化为字符串 .join('')
					
				 计算属性功能用法:
					1.插值表达式中应该写简单的算数计算,如果复杂应该封装
					2.如果数据操作相同则应该简化过程.
				 总结: 计算属性相对于方法 效率高(从虚拟DOM中直接获取结果)
			 -->
			<h3>数据展现:</h3> 
			{{reverse()}}<br>  <!-- 方法多次执行-->
			{{reverse()}}<br>
			{{reverse()}}<br>
			{{reverse()}}<br>
			{{reverseCom}}<br> <!-- 计算属性只执行一次-->
			{{reverseCom}}<br>
			{{reverseCom}}<br>
			{{reverseCom}}<br>
			<input type="text" v-model="msg"/>
		</div>
		
		<!-- 引入JS文件 -->
		<script src="../js/vue.js"></script>
		<script>
			const app = new Vue({
				el:	"#app",
				data: {
					msg: 'abc'
				},
				methods: {
					reverse(){
						 console.log("方法执行!!!!!")
						 return this.msg.split('').reverse().join('')
					}
				},
				computed: {
					//key:value  必须添加返回值
					reverseCom(){
						console.log("计算属性!!!!")
						return this.msg.split('').reverse().join('')
					}
				}
			})
		</script>
	</body>
</html>
数组操作

push() 在结尾追加元素
pop() 删除最后一个元素
shift() 删除第一个元素
unshift() 在开头追加元素
splice() 替换数组中的数据 !!!
sort() 数据排序
reverse() 数组反转

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>数组操作</title>
	</head>
	<body>
		<h1>数组操作</h1>
		<div id="app">
			
			<!-- 数组的方法  java中的叫法push:入栈 pop弹栈
				push() 	在结尾追加元素
				pop()	删除最后一个元素
				shift()	删除第一个元素
				unshift() 在开头追加元素
				splice() 替换数组中的数据 !!!!
				sort()	 数据排序
				reverse() 数组反转
			 -->
			 输入框: <input type="text" v-model="msg"/><br>
			<span v-for="(value) in array">
				{{value}},
			</span><br>
			<button @click="push">push</button>
			<button @click="pop">pop</button>
			<button @click="shift">shift</button>
			<button @click="unshift">unshift</button>
			<button @click="splice">替换</button>
			
		</div>
		
		<!-- 引入JS文件 -->
		<script src="../js/vue.js"></script>
		<script>
			const app = new Vue({
				el:	"#app",
				data: {
					array: ["a","b","c"],
					msg: ''
				},
				methods: {
					push(){
						this.array.push(this.msg)
					},
					pop(){
						//数组数据会自动的更新
						this.array.pop()
					},
					shift(){
						this.array.shift()
					},
					unshift(){
						//在开头追加
						this.array.unshift(this.msg)
					},
					splice(){
						/**
						 * 参数: 3个参数
						 * 		arg1: 操作数据的起始位置 从0开始
						 * 		arg2: 操作的数量     阿拉伯数字
						 * 		arg3: 替换后的数据.可以有多个(可变参数类型)
						 * 案例:
						 * 		1.将第一个元素,替换为msg
						 * 			this.array.splice(0,1,this.msg)
						 * 		2.将前2个元素替换为msg
						 * 			this.array.splice(0,2,this.msg) 前2个替换
						 * 			this.array.splice(0,2,this.msg,this.msg) 前2个替换,补齐2个数据
						 * 		3.将最后一个替换为msg
						 * 			let index = this.array.length - 1;
									this.array.splice(index,1,this.msg)
								4.删除第二个元素
						 */
							//如果只有2个参数,则表示删除
							this.array.splice(1,1) 
					}
				}
			})
		</script>
	</body>
</html>

Axios 学习

Axios介绍

** 特点: 调用简洁 解决了 “回调地狱问题”!!!**
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
特点:
1.从浏览器中创建 XMLHttpRequests
2.从 node.js 创建 http 请求
3.支持 Promise API
4.拦截请求和响应
5.转换请求数据和响应数据
6.取消请求
7.自动转换 JSON 数据
8.客户端支持防御 XSRF

结构说明:
	1. JS中原生提供了Ajax操作.  弊端: 操作特别的复杂 易用性较差.
	2. jQuery中的Ajax    封装了原生的JS Ajax    提高了开发的效率  
	3. Axios是VUE中默认支持的Ajax的请求的方式

Axios 发展史

Js原生Ajax操作 处理复杂,不便于使用
JQuery 是Js的高级函数类库,封装了很多API,简化程序调用的过程,但是有回调地狱(Ajax嵌套)的问题
promise对象,将Ajax嵌套的结构转化为链表加载的结构,Ajax.get().then(方法体)
Axios 主要封装了promise对象,将调用变得更加简化,整合VUE.Js中大部分条件下都整合了Axios发起Ajax请求

回调地狱问题

说明: 前端中如果需要发起大量的Ajax请求,并且Ajax 请求有嵌套的关系.则可能引发回调地狱问题.
例子: 请求 参数A --1–结果B/参数B—2–结果C/参数C—3— 结果D
在这里插入图片描述

SpringMVC 参数传递方式

RestFul风格

特点:

  1. 参数需要使用/ 进行分割
  2. 参数的位置是固定的.
  3. restFul请求方法路径不能出现动词
  4. restFul的优化:
    • 如果{参数名称}与对象中的属性名称一致,
    •  则SpringMVC动态的为对象赋值,
      
    •  @PathVariable 可以省略
      
    • 注意事项:
    •  前后端的参数的传递必须保持一致!!!!
      
  5. RestFul语法:
    •  1.参数的位置固定.
      
    •  2.参数必须使用{}包裹
      
    •  3.必须使用@PathVariable 动态的接收参数
      
    •  注意事项: {参数名称}必须与方法中的名称一致.
      

作用:
用户可以通过一个URL请求的地址,可以实现不同的业务操作
知识回顾:
查询: http://localhost:8090/getUserById?id=100 类型:get
新增: http://localhost:8090/insertUser 类型:post
更新: http://localhost:8090/updateUser 类型:post
删除: http://localhost:8090/deleteUserById?id=200 类型:get
意图明显: 常规的请求的方式其中包含了动词,导致操作的意图非常明显.

RestFul风格实现CURD操作:
1.查询: http://localhost:8090/user/100 type:GET
2.新增: http://localhost:8090/user/tomcat/18/男 type:POST
3.删除: http://localhost:8090/user/100 type:DELETE
4.更新: http://localhost:8090/user/mysql/100 type:PUT

Get类型简单参数传递

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>get请求的各种用法</title>
	</head>
	<body>
		
		<script src="../js/axios.js"></script>
		<script>
			<!-- 简单参数传递 simple -->
			axios.defaults.baseURL="http://localhost:8090"
			let url = "/get/simple?id=100"
			axios.get(url).then(function(result){
				console.log(result)
			})
		</script>
	</body>
</html>
后端
package com.jt.controller;
@RestController
@RequestMapping("/get")
@CrossOrigin
public class GetController {
    @Autowired
    private GetService service;
    @GetMapping("simple")
    public String Simple(Integer id){
        return "Get简单参数的请求";
    }
}

Get类型对象参数传递

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>get请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			<!-- 对象方式传递 -->
			let user = {
				id: 100,
				name: "jack",
				age: 16,
				sex: "男"
			}
			let url = "/get/object"
			axios.get(url,{params: user}).then(function(result){
				console.log(result.data)
			})
		</script>
	</body>
</html>
后端
package com.jt.controller;
@RestController
@RequestMapping("/get")
@CrossOrigin
public class GetController {
    @Autowired
    private GetService service;

    @GetMapping("object")
    public GetUser Object(GetUser user){
        return user;
    }
}

Get类型对RestFul参数传递

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>get请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			<!-- RestFul参数传递 -->
			let url = "get/restful/100/rows/19/女"
			axios.get(url).then(function(result){
				console.log(result)
			})
		</script>
	</body>
</html>
后端
package com.jt.controller;
@RestController
@RequestMapping("/get")
@CrossOrigin
public class GetController {
    @Autowired
    private GetService service;
    @GetMapping("/restful/{id}/{name}/{age}/{sex}")
    public GetUser RestFul(GetUser user){
        return user;
    }
}

Get类型对RestFul参数传递 模板字符串

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>get请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			<!-- RestFul参数传递 模板字符串 -->
			let name="rows"
			let age=18
			let id=100
			let sex="女"
			let url=`/get/restful/${id}/${name}/${age}/${sex}`
			axios.get(url).then(function(result){
				console.log(result)
			})
		</script>
	</body>
</html>
后端
package com.jt.controller;
@RestController
@RequestMapping("/get")
@CrossOrigin
public class GetController {
    @Autowired
    private GetService service;
    @GetMapping("/restful/{id}/{name}/{age}/{sex}")
    public GetUser RestFul(GetUser user){
        return user;
    }
}

Post类型简单参数传递

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>post请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			let url="/post/PostSimple?id=100"
			axios.post(url).then(function(result){
				console.log(result)
			})
			
		</script>
	</body>
</html>

后端
package com.jt.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@CrossOrigin
@RequestMapping("/post")
public class PostController {
    @PostMapping("/PostSimple")
    public Integer Simple(Integer id){
        return id;
    }
}

Post类型对象参数传递

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>post请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			let url ="post/object"
			let post = {
				id: 100,
				name: "jack",
				age: "33",
				sex: "男"
			}
			axios.post(url,post).then(function(result){
				console.log(result)
			})
		</script>
	</body>
</html>

后端
package com.jt.controller;
@RestController
@CrossOrigin
@RequestMapping("/post")
public class PostController {
    @PostMapping("object")
    public PostUser Object(@RequestBody PostUser user){
        return user;
    }
}

Post类型RestFul参数传递

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>post请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			let url = "post/restful/100/rows/26/女"
			axios.post(url).then(function(result){
				console.log(result)
			})
		</script>
	</body>
</html>

后端
package com.jt.controller;
@RestController
@CrossOrigin
@RequestMapping("/post")
public class PostController {
    @PostMapping("/restful/{id}/{name}/{age}/{sex}")
    public PostUser RestFul(PostUser user){
        return user;
    }
}

Post类型RestFul参数传递 模板字符串

前端
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>post请求的各种用法</title>
	</head>
	<body>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			let post = {
				id: 100,
				name: "jack",
				age: 19,
				sex: "男"
			}
			let url = `/post/restfulmoban/{id}/{name}/{age}/{sex}`
			axios.post(url,post).then(function(result){
				console.log(result)
				})
		</script>
	</body>
</html>

后端
package com.jt.controller;
@RestController
@CrossOrigin
@RequestMapping("/post")
public class PostController {
    @PostMapping("/restfulmoban/{id}/{name}/{age}/{sex}")
    public PostUser RestFulmoban(@RequestBody PostUser user){
        return user;
    }
}

箭头函数

箭头函数 主要简化回调函数的写法
思路: 重复的 固定的可以简化
规则: 如果参数只有一个则括号可以省略

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>async-await语法</title>
	</head>
	<body>
		<h1>Axios练习</h1>
		<!-- 引入JS文件 -->
		<script src="../js/axios.js"></script>
		<script>
					
					/**
					 * axios的get请求语法
					 * 知识点:
					 * 		1.箭头函数 主要简化回调函数的写法
					 * 		思路: 重复的 固定的可以简化
					 * 		规则: 如果参数只有一个则括号可以省略
					 */
					let url = "http://localhost:8090/axios/getUserById?id=100"
					axios.get(url)
							 .then( result => {
								 alert(result.data)
					})
					<!-- 箭头函数与fun的区别 -->
					axios.get(url)
							 .then(funciton(result){
								 alert(result.data)
					})
		</script>
	</body>
</html>

async - await

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>async-await语法</title>
	</head>
	<body>
		<h1>Axios练习</h1>
		<!-- 引入JS文件 -->
		<script src="../js/axios.js"></script>
		<script>
					/**
					 * axios的get请求语法
					 * 知识点:
					 * 		1.箭头函数 主要简化回调函数的写法
					 * 		思路: 重复的 固定的可以简化
					 * 		规则: 如果参数只有一个则括号可以省略
					 *  	
					 * 		2.async-await简化  解构赋值
					 * 		2.1 async 需要标识函数
					 * 		2.2 await 需要标识ajax请求
					 *    上述的操作可以将多行js 封装为一行执行 简化代码操作
					 */
					
					//1.定义一个方法
					async function getUserById(){
							let url = "http://localhost:8090/axios/getUserById?id=100"
							//2.发起ajax请求  获取promise对象
							//let promise = await axios.get(url)
							//console.log(promise)
							//console.log(promise.data)
							
							//解构赋值 提取对象中有价值的数据
							let {data: resultData,status: code} = await axios.get(url)
							console.log(resultData)
							console.log(code)
					}
					//2.调用方法
					getUserById()		
		</script>
	</body>
</html>

前后端调用流程入门案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>VUE-Axios练习</title>
	</head>
	<body>
		<div id="app" >
			<div align="center">
				<h1>用户新增操作</h1>
				姓名:<input type="text" v-model.trim="UserList.name" />
				年龄:<input type="text" v-model.number="UserList.age"/>
				性别:<input type="text" v-model.trim="UserList.sex"/>
				<button @click="insetUser" >新增</button>
			</div>
			<hr/>
			<table align="center" border="1px" width="70%">
				<tr>
					<td>编号</td>
					<td>姓名</td>
					<td>年龄</td>
					<td>性别</td>
					<td>选项</td>
				</tr>
				<tr v-for="user in ArrayUserList">
					<td v-text="user.id"></td>
					<td v-text="user.name"></td>
					<td v-text="user.age"></td>
					<td v-text="user.sex"></td>
					<td>
						<button @click="updatedata(user.id)">修改</button>
						<button @click="deleteUserById(user.id)">删除</button>
					</td>
				</tr>
			</table>
			
		</div>
		
		<script src="../js/vue.js"></script>
		<script src="../js/axios.js"></script>
		<script>
			axios.defaults.baseURL="http://localhost:8090"
			const app = new Vue({
				el: "#app",
				data: {
					ArrayUserList: [],
					UserList: {
						id: 0,
						name: '',
						age: 0,
						sex: ''
					},
				},
				methods: {
					async getUserList(){
						let {data: result} = await axios.get("/vue/getUserList")
						this.ArrayUserList = result
					},
					async insetUser(){
						let {data: result} =await axios.post("/vue/insertUser",this.UserList)
						this.getUserList()
					},
					async deleteUserById(rows){
						await axios.delete(`/vue/deleteUserById/${rows}`)
						this.getUserList()
						
					},
					async updatedata(rows){
						this.UserList.id = rows
						this.UserList.name = prompt("名字修改为?")
						this.UserList.age = prompt("年龄修改为?")
						this.UserList.sex = prompt("性别修改为?")
						let {data: result} = await axios.put("/vue/updateDataUser",this.UserList)
						this.getUserList()
						console.log(result)
					}
				},
				mounted() {
					this.getUserList()
				}
			})
			
			
			
		</script>
	</body>
</html>

组件

组件化思想

说明:
传统的页面开发,会将大量的HTML/CSS/JS进行引入,但是引入之后结构混乱不便于管理,开发维护成本较高
组件化思想:
在Vue中可以将一个组件看作为一个页面,在其中可以引入独立的CSS/JS/HTML进行单独的管理,组件可以进行复用

全局组件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>练习全局组件</title>
	</head>
	<body>
		<!-- 2、指定渲染空间 -->
		<div id="app">
			<!-- 使用组件标签-->
			<hello-com></hello-com>
			<hello-com></hello-com>
			<hello-com></hello-com>
		</div>
		<!-- 1、导入vue包 -->
		<script src="../js/vue.js"></script>
		
		<!-- 4.3、定义标签组件的模板 -->
		<template id="helloTem">
			<!-- 4.3.1定义根标签 -->
			<div>
				<!-- 4.3.2 定义标签组件 -->
				<h3>静夜思</h3>
				床前明月光,疑是地上霜。
				举头望明月,低头思故乡。
				<!-- 4.3.3 引入属性组件 -->
				引入属性: {{msg}}
			</div>
		</template>
		
		<script>
			//4、定义组件
			Vue.component("helloCom",{
				//4.1定义属性
				data() {
					return {
						msg: "组件-属性"
					}
				},
				//4.2定义标签
				template: "#helloTem"
			})
			//3、创建Vue对象,指定渲染空间
			const app = new Vue({
				el: "#app",
			})
		</script>
	</body>
</html>

局部组件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>练习全局组件</title>
	</head>
	<body>
		<!-- 2、指定渲染空间 -->
		<div id="app">

		<hello-com></hello-com>
		<hello-com></hello-com>
		<hello-com></hello-com>
		</div>
		
		<!-- 定义标签组件 -->
		<template id="helloTem">
			<div>
				<h3>静夜思</h3>
				瓦达西瓦,静夜思
			</div>
		</template>
		<!-- 1、导入包 -->
		<script src="../js/vue.js"></script>
		<script>
			
			let helloCom = {
				//定义属性
				data(){
					return {
						msg: "局部属性组件"
					}
				},
				//定义标签组件
				template: "#helloTem"
			}
			
			//3、创建Vue对象,指定渲染空间
			const app = new Vue({
				//3.1 定义指定渲染空间
				el: "#app",
				//3.2 定义局部组件
				components: {
					// 组件key : 组件体 如果Ket-Value相同,可以简写为Key
					helloCom
				}
			})
		</script>
	</body>
</html>

转发与重定向

转发与重定向都是服务端行为

转发

说明:
用户访问服务器,但是目标服务器无法处理该请求,由服务器内部将请求交给其他服务器处理,这个过程称之为转发
特点:
用户请求一次,响应一次
用户请求的URL地址不发生变化
请求可以携带参数

重定向

说明:
用户访问服务器,但是目标服务器无法处理该请求,目标服务器返回一个能够处理请求的地址,由用户再次发起请求,访问服务器获取数据
特点:
请求多次,响应多次
URL地址信息发生变化
不可以传递数据
路由关键字:
redirect: 路径
在这里插入图片描述

路由机制

用户发起一个请求,在互联网中经过多个站点的跳转,最终获取服务端的数据,把互联网中的网络链路称之为路由
Vue中的路由:
根据用户请求的URL地址,展现特定的组件(页面)信息,控制用户程序跳转过程

路由步骤

1、导入路由.JS
2、指定路由的跳转连接
3、定义路由的填充位
4、封装组件信息,指定路由对象
5、在Vue对象中声明路由

路由案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>练习全局组件</title>
	</head>
	<body>
		<div id="app">

			<router-link to="/user">用户</router-link>
			<router-link to="/dog">狗子</router-link>
			<router-view></router-view>
		</div>
		
		
		<template id="userTem">
			<div>
				用户信息
			</div>
		</template>
		<template id="dogTem">
			<div>
				狗狗信息
			</div>
		</template>
		
		<!-- 1.导入路由JS    先导入vue.js  再导入路由.js 顺序问题 -->
		<script src="../js/vue.js"></script>
		<script src="../js/vue-router.js"></script>
		<script>
			let userCom = {
				template: "#userTem"
			}
			
			let dogCom = {
				template: "#dogTem"
			}
			
			let vueRouter = new VueRouter({
				routes: [
					{path: "/user", component: userCom},
					{path: "/dog", component: dogCom}
				]
			})
			
			const App = new Vue({
				el:"#app",
				router: vueRouter
			})
			
		</script>
	</body>
</html>

路由嵌套案例

  1. 使用children属性
<html>
	<head>
		<meta charset="utf-8" />
		<title>路由入门案例</title>
	</head>
	<body>
		<!-- 创建渲染空间 -->
		<div id="app">
			<!-- 定义连接 -->
			<router-link to="/user">用户</router-link>
			<router-link to="/dog">狗狗</router-link>
			<!-- 占位 -->
			<router-view></router-view>
		</div>
		<!-- 模板 -->
		<template id="userTem">
			<div>
				<h1>用户</h1>
			</div>
		</template>
		<template id="dogTem">
			<div>
				<h1>狗狗</h1>
				<router-link to="/smo">萨摩耶</router-link>
				<router-link to="/spi">沙皮</router-link>
				<router-view></router-view>
			</div>
		</template>
		
		<template id="smoTem">
			<div>
				<h1>萨摩耶</h1>
			</div>
		</template>
		<template id="spiTem">
			<div>
				<h1>沙皮</h1>
			</div>
		</template>
		
		<!-- 1、导包 -->
		<script src="../js/vue.js"></script>
		<script src="../js/vue-router.js"></script>
		
		<script>
			let userCom = {
				template: "#userTem"
			}
			let dogCom = {
				template: "#dogTem"
			}
			let smoCom = {
				template: "#smoTem"
			}
			let spiCom = {
				template: "#spiTem"
			}
			
			// 创建router对象
			let vueRouter = new VueRouter({
				routes:[
					{path:"/user" , component: userCom},
					{path:"/dog" , component: dogCom, children:[
						{path:"/smo" , component:smoCom},
						{path:"/spi" , component:spiCom}
					]}
				]
			})
			
			
			// 创建Vue对象 指定渲染空间
			const app = new Vue({
				el: "#app",
				router: vueRouter
			})
		</script>
		
	</body>
</html>

路由导航守卫

  1. 控制访问的路径地址
//配置路由对象
const router = new VueRouter({
  routes
})

/* 配置路由导航守卫 控制权限
  1.to 要跳转的网址
  2.from 请求从哪里来
  3.next 回调函数  放行/跳转
 */
router.beforeEach((to,from,next) => {
  //1.如果用户访问 /login  请求应该放行 终止程序
  if(to.path === '/login') {
    return next()
  }

  //2.如果用户访问不是login 则需要校验是否登录 检查是否有token
  let token = window.sessionStorage.getItem('token')
  if(token !== null && token.length > 0){
    return next()
  }else {
    //没有token 应该跳转到登录页面 "/login"
    return next("/login")
  }
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值