DAY12_VUE基本用法详细版

目录

  • 0 HBuilderX酷黑主题修改注释颜色
  • 1 VUE
    • 1.1 VUE介绍
    • 1.2 Vue优点
    • 1.3 VUE入门案例
      • 1.3.1 导入JS文件
      • 1.3.2 VUE入门案例
    • 1.4 VUE基本用法
      • 1.4.1 v-cloak属性
      • 1.4.2 v-text指令
      • 1.4.3 v-html指令
      • 1.4.4 v-pre指令
      • 1.4.5 v-once指令
      • 1.4.6 v-model指令
      • 1.4.7 MVVM思想
    • 1.5 事件绑定
      • 1.5.1 v-on指令
        • 1.5.1.1 click命令
        • 1.5.1.2 methods属性介绍
      • 1.5.2 事件修饰符
        • 1.5.2.1 stop 阻止冒泡
        • 1.5.2.2 prevent 阻止默认行为
      • 1.5.3 按键修饰符
      • 1.5.4 小案例——计算器
    • 1.6 属性绑定
      • 1.6.1 v-bind属性绑定
      • 1.6.2 属性动态绑定
      • 1.6.3 属性动态绑定扩展
    • 1.7 分支结构语法
      • 1.7.1 分支结构介绍
      • 1.7.2 分支结构介绍(if/else)
      • 1.7.3 v-show命令
    • 1.8 循环遍历
    • 1.9 Vue常用特性
      • 1.9.1 Vue表单操作
        • 1.9.1.1 常见表单元素
        • 1.9.1.2 数据绑定
      • 1.9.2 表单域修饰符
      • 1.9.3 计算属性
        • 1.9.3.1 需求说明
        • 1.9.3.2 计算属性案例
      • 1.9.4 计算属性和方法的区别
    • 1.10 侦听器
      • 1.10.1 监听器作用
      • 1.10.2 配置监听器
      • 1.10.3 监听器案例实现
    • 1.11 过滤器
      • 1.11.1 过滤器作用
      • 1.11.2 过滤器用法
    • 1.12 VUE生命周期
      • 1.12.1 VUE对象周期函数流程图
      • 1.12.2 VUE对象生命周期Demo
    • 1.13 VUE数组操作
      • 1.13.1 文档位置
      • 1.13.2 数组用法介绍
      • 1.13.3 数组使用案例
  • 2 VUE组件化
    • 2.1 组件介绍
    • 2.2 组件注册
      • 2.2.1 组件化入门案例
      • 2.2.2 组件驼峰规则命名
      • 2.2.3 组件模板标签的使用
      • 2.2.4 注意事项
    • 2.3 局部组件注册
    • 2.4 全局组件中引用局部组件——使用不生效
  • 3 Vue前端交互
    • 3.1 Promise概述
    • 3.2 Promise基本用法
    • 3.3 Promise API介绍
    • 3.4 Axios方式
      • 3.4.1 Axios介绍
      • 3.4.2 Axios入门案例
        • 3.4.2.1 编辑页面html
        • 3.4.2.2 编辑后台AxiosController
      • 3.4.3 Axios GET/DELETE调用
        • 注意事项 GET/DELETE语法相同!!!
        • 3.4.3.1 get方式
        • 3.4.3.2 带参数的get请求
        • 3.4.3.3 Get RestFul风格
        • 3.4.3.4 Get params参数方式
      • 3.4.4 Axios post/put 调用
        • 3.4.4.1 对象方式提交数据
        • 3.4.4.2 Form表单数据
        • 3.4.4.3 restFul方式提交数据
      • 3.4.5 Axios 配置信息
      • 3.4.6 Axios 拦截器机制
        • 3.4.6.1 请求拦截器
        • 3.4.6.2 响应拦截器
      • 3.4.7 async-await用法
        • 3.4.7.1 介绍
        • 3.4.7.2 入门案例用法
        • 3.4.7.3 解构赋值操作
      • 3.4.8 VUE实现用户列表展现
        • 3.4.8.1 编辑AxiosUserController
        • 3.4.8.2 获取用户列表数据
        • 3.4.8.3 循环遍历数据
        • 3.4.8.4 修改用户实现数据回显
        • 3.4.8.5 实现用户修改
        • 3.4.8.6 实现用户数据删除
        • 3.4.8.7 最终代码
      • 3.4.9 跨域
        • 3.4.9.1 同源策略
        • 3.4.9.2 跨域问题
        • 3.4.9.3 CORS
        • 3.4.9.4 响应头信息
  • 4 VUE路由
    • 4.1 VUE Router介绍
      • 4.1.1 后端路由
      • 4.1.2 前端路由
    • 4.2 Router 路由入门案例
      • 4.2.1 Router使用步骤
      • 4.2.2 Router 入门案例
    • 4.3 Router 重定向
    • 4.4 Router 嵌套

0 HBuilderX酷黑主题修改注释颜色

  • 安装目录下的dark_defaolts.json,将该文件下的所有#75715E改为#77B767即可

在这里插入图片描述

1 VUE

1.1 VUE介绍

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

渐进式: 构建项目可以由简单到复杂

1.2 Vue优点

  • 体积小 压缩后的文件只有33k
  • 运行效率更高 采用虚拟机DOM,一种可以预先通过javaScript对数据进行计算.把最终的DOM操作计算出来并且优化的技术. 由于这个DOM操作属于预处理操作,并没有真实的操作DOM ,所以叫做虚拟DOM
  • 双向数据绑定 让开发者不再去操作DOM,将更多的经历投入到业务中
  • 生态丰富 市面上有大量的开源项目基于vue 进行开发 成熟稳定

1.3 VUE入门案例

1.3.1 导入JS文件

  • 官网https://cn.vuejs.org/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3.2 VUE入门案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VUE入门案例</title>
</head>
<body>
	<div id="app">
	    <h1>{{hello}}</h1>
	</div>

	<!-- 1.导入vue.js的类库 -->
	<script src="../js/vue-2.7.16.js"></script>
	<!-- 2.编辑VUE js -->
	<script>
	    //新规定:  1.结尾的;号可以省略   2.字符一般使用'单引号'
	    //补充知识:
	    //  var: js中声明变量的修饰符 没有作用域的概念
	    //  const 定义常量的
	    //  let   有作用域的变量声明
	
	    //实例化VUE对象   函数式编程
	    const app = new Vue({
	        //1.定义el元素 要在哪个位置使用vue进行渲染
	        el: "#app",
	        //2.定义数据对象
	        data: {
	            hello: 'VUE入门案例'
	        }
	    })
	</script>
</body>
</html>

1.4 VUE基本用法

1.4.1 v-cloak属性

由于插值表达式在渲染没有完成时,会展现{{xxx}}效果,用户体验不好
可以在渲染没有完成时不给用户展现任何信息

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据显示测试案例</title>
	<!-- 配置样式 -->
	<style>
		/* 渲染没有完成时不展现 */
		[v-cloak]{
			display: none;
		}	
	</style>
</head>
<body>
    <div id="app">
        <h3 v-cloak>{{hello}}</h3>
    </div>

    <script src="../js/vue-2.7.16.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
                hello: 'vue案例'
            }
        })
    </script>
</body>
</html>

1.4.2 v-text指令

直接展现解析数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据显示测试案例</title>
</head>
<body>
    <div id="app">
   		 <!-- 以优化后的效果进行展现 内部兼容了v-cloak -->
        <h3 v-text="msg"></h3>
    </div>

    <script src="../js/vue-2.7.16.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
				msg: '测试v-text指令'
            }
        })
    </script>
</body>
</html>

1.4.3 v-html指令

将html标记语言,以渲染之后的效果进行展现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据显示测试案例</title>
</head>
<body>
    <div id="app">
		<!-- 以html解析之后的效果进行展现 -->
		<h1 v-html="html"></h1>
    </div>

    <script src="../js/vue-2.7.16.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
				html: '<h1>html效果展现</h1>'
            }
        })
    </script>
</body>
</html>

1.4.4 v-pre指令

如果用户就想展现{{name}}数据

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据显示测试案例</title>
</head>
<body>
    <div id="app">
		<!-- v-pre指令 跳过vue的解析过程,直接展现数据 -->
		<h3 v-pre>{{name}}</h3>
    </div>

    <script src="../js/vue-2.7.16.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
            }
        })
    </script>
</body>
</html>

1.4.5 v-once指令

如果数据只需要VUE解析一次之后不需要再次解析,则可以使用该指令

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据显示测试案例</title>
</head>
<body>
    <div id="app">
		<!-- v-once指令 元素只被解析一次 -->
		<h3 v-once>{{once}}</h3>
    </div>

    <script src="../js/vue-2.7.16.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
				once: '测试解析次数'
            }
        })
    </script>
</body>
</html>

1.4.6 v-model指令

如果需要实现页面的数据与属性实现双向数据绑定则使用v-model
一般在输入框中最为常用,一般用来保证数据的一致性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>数据显示测试案例</title>
</head>
<body>
    <div id="app">
		<!-- v-model 测试双向数据绑定 1.服务器将数据给用户展现的 2.用户需要传递数据给服务器 -->
		双向数据绑定:<input name="model" v-model="model" />
    </div>

    <script src="../js/vue-2.7.16.js"></script>
    <script>
        const app = new Vue({
            el: "#app",
            data: {
				model: ' 测试双向数据绑定'
            }
        })
    </script>
</body>
</html>

1.4.7 MVVM思想

  • 字母解释
    • M Model 代表数据
    • V View 代表视图
    • VM (view-model) 视图与数据的控制层
  • 当页面数据发生变化时,则通过dom监听将数据传给model
    • 当model的数据发生变化时,则通过数据绑定 绑定到页面中

在这里插入图片描述

1.5 事件绑定

1.5.1 v-on指令

如果需要对页面元素进行操作(事件)

1.5.1.1 click命令
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>事件绑定的操作</title>
	</head>
	<body>
		<div id="app">
			<!-- 要求实现num数据+1 -->
			{{num}}
			<!-- 添加事件绑定 -->
			<button v-on:click="num++">自增</button>
			<!-- 简化写法 v-on使用@进行替换 -->
			<button @click="num--">自减</button>
		</div>
		
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					num: 100
				}
			})
		</script>
	</body>
</html>
1.5.1.2 methods属性介绍

通过methods属性定义更加复杂的方法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>事件绑定的操作</title>
	</head>
	<body>
		<div id="app">
			{{num}}
			<!-- 如果操作较为复杂,可以通过方法的方式进行操作 -->
			<button @click="addNum">自增</button>
		</div>
		
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					num: 100
				},
				methods:{
					//js中方法称之为函数
					// addNum: function(){}
					addNum(){//简化写法
						//对num+1
						this.num ++
					}
				}
			})
		</script>
	</body>
</html>

1.5.2 事件修饰符

1.5.2.1 stop 阻止冒泡
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>事件绑定的操作</title>
	</head>
	<body>
		<!-- 事件冒泡 由于操作的过程中可能有嵌套的关系,所以会触发冒泡机制
			 如果需要阻止冒泡,通常使用.stop进行修饰
		 -->
		<div id="app" @click="addNum">
			<!-- 要求实现num数据+1 -->
			{{num}}
			<!-- 添加事件绑定 -->
			<button @click.stop="num++">自增</button>
		</div>
		
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					num: 100
				},
				methods:{
					addNum(){
						this.num++
					}
				}
			})
		</script>
	</body>
</html>
1.5.2.2 prevent 阻止默认行为
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>事件绑定的操作</title>
	</head>
	<body>
		<div id="app" @click="addNum">
			<!-- 需求:有时需要通过A标签跳转链接 -->
			<a href="http://www.baidu.com" @click="getMsg">百度</a>
			<!-- 需求:如果阻止默认的行为 则使用.prevent属性 -->
			<a href="http://www.baidu.com" @click.prevent="getMsg">百度</a>
		</div>
		
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
				},
				methods:{
					getMsg(){
						console.log("发起请求")
					}
				}
			})
		</script>
	</body>
</html>

1.5.3 按键修饰符

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>事件绑定的操作</title>
	</head>
	<body>
		<div id="app" @click="addNum">
			<!-- 按键修饰符 通过按特定的键 触发事件 -->
			<input name="username" type="text" @keyup.enter="handler" value="回车触发" />
			<input name="username" type="text" @keyup.space="handler" value="空格触发" />
			<input name="username" type="text" @keyup.delete="handler" value="删除键触发" />
			<input name="username" type="text" @keyup.left="handler" value="<-触发" />
			<input name="username" type="text" @keyup.right="handler" value="->键触发" />
			<input type="text" @click.middle="handler" value="鼠标滚轮触发" />
			<input type="text" @click.left="handler" value="鼠标左键触发" />
			<input type="text" @click.right="handler" value="鼠标右键触发" />
		</div>

		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
				},
				methods: {
					handler(){
						console.log('被触发了')
					}
				}
			})
		</script>
	</body>
</html>

1.5.4 小案例——计算器

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>计算器案例</title>
	</head>
	<body>

		<div id="app">
			<h1>实现计算器功能</h1>
			<div>
				<div>数据A:<input type="text" name="num1" v-model="num1" /></div>
				<div>数据B:<input type="text" name="num2" v-model="num2" /></div>
				<button type="button" @click="count">计算</button>
				<div>结果:<span v-text="result"></span></div>
			</div>
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					num1: '',
					num2: '',
					result: ''
				},
				methods: {
					count() {
						this.result = parseInt(this.num1) + parseInt(this.num2);
						//this.result = eval(this.num1) + eval(this.num2)
					}
				}
			})
		</script>
	</body>
</html>

1.6 属性绑定

1.6.1 v-bind属性绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<!-- 需求:需要为href属性动态绑定数据 -->
			<a href="http://www.baidu.com">百度</a>
			<!-- 属性绑定的语法 -->
			<a v-bind:href="url">百度</a>
			<!-- 简化操作 -->
			<a :href="url">百度</a>
		</div>
		
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					url: 'http://www.baidu.com'
				}
			})
		</script>
	</body>
</html>

1.6.2 属性动态绑定

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>属性绑定</title>
		<!-- 定义style标签 -->
		<style>
			.red{
				background-color: red;
				width: 100px;
				height: 100px;
			}
		</style>
	</head>
	<body>
		<div id="app">
			<!-- class的绑定-->
			<div class="red">class的测试内容</div>
			<!-- 需求:需要动态的绑定样式 -->
			<div v-bind:class="{red: isRed}">class的测试内容</div>
			<div :class="{red: isRed}">class的测试内容</div>
			<!-- 切换样式 -->
			<button @click="isRed=!isRed">切换</button>
		</div>
		
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					// 如果控制样式 则设定boolean类型的值
					isRed: true
				}
			})
		</script>
	</body>
</html>

1.6.3 属性动态绑定扩展

  • 数组方式写法
<div v-bind:class="[redClass,fontSize]">属性样式测试</div>
<button @click="changeCss">切换</button>
</div>
data: {
	redClass: "red",
	fontSize: "fontSize"
},
methods: {
	changeCss() {
		this.redClass = ''
		this.fontSize = ''
	}
}
  • 样式绑定
<div v-bind:style="{border: borderStyle,width: widthStyle,height: heightStyle}">123</div>
data: {
	borderStyle: "1px solid blue",
	widthStyle: "100px",
	heightStyle: "100px"
}
  • 对象封装写法
<div v-bind:style="myStyle">456</div>
data: {
	myStyle : {
		border: '2px solid green',
		width: "20px",
		height: "20px"
	}
}

1.7 分支结构语法

1.7.1 分支结构介绍

  • v-if
    • 如果判断为真 则显示标签数据
  • v-else
    • 如果判断为假 则显示数据
  • v-else-if
    • 判断规则 位于if和else之间的.
  • v-show
    • 展现数据

1.7.2 分支结构介绍(if/else)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>分支结构语法</title>
	</head>
	<body>
		<div id="app">
			<!-- 
			需求:设定课程成绩:score 根据课程的成绩进行评级
			注意事项:v-if/v-else位置应该连续 v-else不可以单独使用
			 -->
			<h3 v-if="score>=90">优秀</h3>
			<h3 v-else-if="score>=80 && score<90">良好</h3>
			<h3 v-else-if="score>=70 && score<80">中等</h3>
			<h3 v-else-if="score>=60 && score<70">及格</h3>
			<h3 v-else>不及格</h3>
		</div>

		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					score: 80
				}
			})
		</script>
	</body>
</html>

1.7.3 v-show命令

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>分支结构语法</title>
	</head>
	<body>
		<div id="app">			
			<!-- v-show指令 h3标签动态的展现 跟一个布尔类型的值-->
			<!-- style="display:none" 如果数据频繁的切换 v-show效率更高 -->
			<h3 v-show="isShow">展现一个变化的数据</h3>
			<!-- 通过按钮切换状态 -->
			<button @click="isShow = !isShow">切换</button>
		</div>

		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					isShow: true
				}
			})
		</script>
	</body>
</html>

1.8 循环遍历

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>循环结构</title>
	</head>
	<body>
		<div id="app">
			<!-- 1.循环数组 注意事项:循环时最好指定key 标识循环数据的位置 -->
			<h3 v-for="item in hobbys" v-text="item" :key="item"></h3>

			<!-- 2.带下标的循环遍历语法 2个参数  参数1:遍历的数据   参数2:下标 -->
			<h3 v-for="(item,index) in hobbys" v-text="item" :key="index"></h3>

			<!-- 3.循环遍历对象 -->
			<div v-for="user in userList" :key="user.id">
				<span v-text="user.id"></span>
				<span v-text="user.name"></span>
			</div>
		</div>

		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					//一般采用数组的形式保存多个数据
					hobbys: ['打游戏', '敲代码', '喝水'],
					userList: [{
						id: 100,
						name: '孙尚香'
					}, {
						id: 200,
						name: '王昭君'
					}, {
						id: 300,
						name: '貂蝉'
					}]
				}
			})
		</script>
	</body>
</html>

1.9 Vue常用特性

1.9.1 Vue表单操作

1.9.1.1 常见表单元素
  • input 文本框
  • textarea 文本域
  • select 下拉框
  • radio 单选框
  • checkbox 多选框
1.9.1.2 数据绑定
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>表单数据提交</title>
	</head>
	<body>
		<div id="app">
			<form action="http://www.baidu.com">
				<div>
					<span>用户名:</span>
					<span>
						<input name="username" type="text" v-model="username" />
					</span>
				</div>

				<div>
					<span>性别:</span>
					<span>
						<!--label相当于合并一个div 需要id-for进行关联  -->
						<input name="gender" type="radio" value="" id="man" v-model="gender" />
						<label for="man"></label>
						<input name="gender" type="radio" value="" id="women" v-model="gender" />
						<label for="women"></label>
					</span>
				</div>

				<div>
					<span>爱好:</span>
					<span>
						<input name="hobbys" type="checkbox" value="敲代码" v-model="hobbys" />敲代码
						<input name="hobbys" type="checkbox" value="打游戏" v-model="hobbys" />打游戏
						<input name="hobbys" type="checkbox" value="喝水" v-model="hobbys" />喝水
					</span>
				</div>

				<div>
					<span>部门:</span>
					<span>
						<!-- 设定下拉框多选 multiple="true" -->
						<select name="dept" v-model="dept" multiple="true">
							<option value="财务部">财务部</option>
							<option value="研发部">研发部</option>
							<option value="测试部">测试部</option>
						</select>
					</span>
				</div>
				<div>
					<span>用户详情</span>
					<textarea name="userInfo" style="width: 200px;height: 50px;" v-model="userInfo"></textarea>
				</div>
				<div>
					<!-- 让默认的行为失效 -->
					<button @click.prevent="submit">提交</button>
				</div>
			</form>
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: "#app",
				data: {
					username: '',
					gender: '男',
					//如果数据项有多项 则使用数组接收
					hobbys: ['敲代码', '喝水'],
					//定义下拉框 如果单个数据使用'' 多个数据使用数组
					//dept: '研发部'
					dept: ['财务部', '研发部'],
					userInfo: ''
				},
				methods: {
					submit() {
						//数据提交
						console.log("用户名:" + this.username)
						console.log("性别:" + this.gender)
						console.log('爱好:' + this.hobbys)
						console.log('部门:' + this.dept)
						console.log('用户详情:' + this.userInfo)
						console.log('封装好数据之后,可以使用ajax方式实现数据提交')
					}
				}
			})
		</script>
	</body>
</html>

1.9.2 表单域修饰符

  • number:将用户输入的内容转户为数值类型.
  • trim:去除左右两边多余的空格.
  • lazy:简化input框调用js的次数 当失去焦点时调用
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>表单修饰符</title>
	</head>
	<body>
		<div id="app">
			<!-- number 将字符转化为数值 -->
			数字1: <input type="text" v-model.number="num1" /><br>
			数字2: <input type="text" v-model.number="num2" /><br>
			<button @click="addNum">加法操作</button> <br>
			总数: {{count}}
			<hr>
			<!-- 去除多余的空格 -->
			数据: <input type="text" v-model.trim="msg" /> <br>
			字符长度 {{msg.length}}
			<hr />
			<!-- lazy 当数据失去焦点时触发事件 -->
			检验用户名: <input type="text" v-model.lazy="username"><br>
			{{username}}
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					num1: '',
					num2: '',
					count: '',
					msg: '',
					username: ''
				},
				methods: {
					addNum() {
						this.count = this.num1 + this.num2
					}
				}
			})
		</script>
	</body>
</html>

1.9.3 计算属性

1.9.3.1 需求说明

有时在vue的JS中需要进行大量的数据计算,但是如果将所有的数据计算都写到HTML标签中,则代码的结构混乱。所以VUE中提供了计算属性的功能computed

1.9.3.2 计算属性案例
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>计算属性</title>
	</head>
	<body>
		<div id="app">
			<!-- 需求: 需要对一个字符串进行反转操作
					用户输入内容 abc 
					要求的输出内容   cba
				思路: 字符串拆分为数组  将数组进行反转  将数组拼接成串				 
				方法说明:
					reverse(): 将数组进行反转
					join("连接符") 将数组拼接为字符串
			 -->
			用户输入: <input type="text" v-model="msg" /> <br>
			常规调用:{{msg.split('').reverse().join('')}}<br>

			<!-- 添加计算属性的名称-->
			计算属性调用: {{reverseMethod}}
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					msg: ''
				},
				//定义计算属性的key
				computed: {
					//指定计算属性的名称 要求有返回值
					reverseMethod() {

						return this.msg.split('').reverse().join('')
					}
				}
			})
		</script>
	</body>
</html>

1.9.4 计算属性和方法的区别

  • 方法调用时每次都会执行.
  • 计算属性调用时有缓存机制
  • 如果数据需要被大量的引用 则使用计算属性更好 效率高

1.10 侦听器

1.10.1 监听器作用

当属性数据发生变化 则通知监听器所绑定的方法

一般多用于执行异步操作

1.10.2 配置监听器

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>监听器用法</title>
	</head>
	<body>
		<div id="app">
			<!-- 需求:用户全名的拼接 -->
			姓氏:<input type="text" name="firstName" v-model.lazy="firstName" />
			名称:<input type="text" name="lastName" v-model.lazy="lastName" />
			全名:{{fullName}}
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					firstName: '',
					lastName: '',
					fullName: ''
				},
				//当数据发生变化时,就会触发监听器中的函数  必须传递数据
				watch: {
					firstName(val) {
						this.fullName = val + this.lastName
					},
					lastName(val) {
						this.fullName = this.firstName + val
					}
				}
			})
		</script>
	</body>
</html>

1.10.3 监听器案例实现

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<!-- 需求:
					要求用户输入username的用户名,之后与服务器进行效验
					如果已经存在给用户提示  如果不存在 则提示用户可以使用
			-->
			<!-- 当用户失去焦点时触发 -->
			用户名:<input type="text" name="username" type="text" v-model.lazy="username">{{msg}}
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					username: '',
					msg: ''
				},
				methods: {
					checkName(username) {
						setTimeout(() => {
							//===严格意义的数据效验 新版本提倡这么写 不光效验数值 还效验类型
							if (username === 'admin') {
								this.msg = '用户名已被使用'
							} else {
								this.msg = '用户名可以使用'
							}
						}, 2000)
					}
				},
				watch: {
					username(val) {
						this.checkName(val)
						this.msg = '数据正在效验'
					}
				}
			})
		</script>
	</body>
</html>

1.11 过滤器

1.11.1 过滤器作用

格式化数据,比如格式化日期,特殊数据格式时使用

1.11.2 过滤器用法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>过滤器的使用</title>
	</head>
	<body>
		<div id="app">
			用户输入的内容:<input name="username" type="text" v-model.lazy="username" /><br>
			{{username | rename}}<br />
			<!-- 过滤器连级 -->
			{{username | rename | addChar}}
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//1.单独定义过滤器
			//参数1:过滤器名称  参数2:过滤器执行的方法
			//注意事项:过滤器需要返回值
			Vue.filter('rename',function(val){
				return val.split('').reverse().join('')
			})
			
			//2.追加哈哈哈字符
			//箭头函数写法 可以省略function关键字,如果只有一个参数则()省略 使用=>进行关联
			Vue.filter('addChar', val => {
				return val + '哈哈哈'
			})
			const app = new Vue({
				el: '#app',
				data: {
					username: ''
				}
			})
		</script>
	</body>
</html>

1.12 VUE生命周期

1.12.1 VUE对象周期函数流程图

在这里插入图片描述

1.12.2 VUE对象生命周期Demo

只要熟练掌握 mounted 就可以了

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>生命周期</title>
	</head>
	<body>
		<div id="app">
			<!-- 
				1.VUE对象的生命周期函数,可以单独的调用
				2.生命周期的函数名称是固定的,不能随意修改.
			 -->
			用户名: <input type="text" v-model="name" />
			<button @click="destroyed">销毁</button>
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					name: ''
				},
				methods: {
					destroyed() {
						//手动销毁VUE对象 vue中的对象API使用$调用
						this.$destroy()
					}
				},
				//在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
				beforeCreate() {
					console.log("初始化之后调用-beforeCreate")
				},
				//在实例创建完成后被立即调用。在这一步,实例已完成以下的配置
				created() {
					console.log("实力化对象完成,并且完成了配置之后调用created")
				},
				//在挂载开始之前被调用:相关的 render 函数首次被调用。
				beforeMount() {
					console.log("数据在备挂载前调用beforeMount")
				},
				//实例被挂载后调用 页面真正的加载完成之后调用
				mounted() {
					console.log("页面加载完成mounted")
				},
				//数据更新时调用,发生在虚拟 DOM 打补丁之前
				beforeUpdate() {
					console.log("数据更新时调用beforeUpdate")
				},
				//由于数据更改之后调用
				updated() {
					console.log("数据修改之后调用updated")
				},
				//实例销毁之前调用。在这一步,实例仍然完全可用。
				beforeDestroy() {
					console.log("VUE对象销毁之前调用beforeDestroy")
				},
				//实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。
				destroyed() {
					console.log("实例销毁后调用destroyed")
				}
			})
		</script>
	</body>
</html>

1.13 VUE数组操作

1.13.1 文档位置

在这里插入图片描述

1.13.2 数组用法介绍

  • push()
    • 在数组末尾追加数据
  • pop()
    • 删除数组最后一个元素
  • shift()
    • 删除数组第一个元素
  • unshift()
    • 在数组开头追加元素
  • splice()
    • 在指定位置替换元素
  • sort()
    • 数组排序,默认是按照字符编码的顺序进行排序 从小到大
  • reverse()
    • 数组反转

1.13.3 数组使用案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>数组案例</title>
	</head>
	<body>
		<div id="app">
			<span v-for="item in array" v-text="item"></span><br>

			数据: <input type="text" v-model="data" />
			<button @click="push">追加</button>
			<button @click="pop">移除最后一个</button>
			<button @click="shift">删除第一个元素</button>
			<button @click="unshift">在开头追加元素</button>
			<button @click="splice">替换元素</button>
			<button @click="sort">排序</button>
			<button @click="reverse">反转</button>
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app',
				data: {
					array: [4, 2, 3, 1, 5],
					data: ''
				},
				methods: {
					push() {
						this.array.push(this.data)
					},
					pop() {
						//移除最后一个数据
						this.array.pop()
					},
					shift() {
						this.array.shift()
					},
					unshift() {
						this.array.unshift(this.data)
					},
					splice() {
						//关于参数说明 参数1:操作数据起始位置 index
						//			  参数2:操作数据的个数
						//			  参数3:要替换的值
						//替换元素     将第一个参数进行替换
						this.array.splice(0,1,this.data)
					},
					sort() {
						this.array.sort()
					},
					reverse() {
						this.array.reverse()
					},
				}
			})
		</script>
	</body>
</html>

2 VUE组件化

2.1 组件介绍

组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。仔细想想,几乎任意类型的应用界面都可以抽象为一个组件树.
使用组件可以将一些重复的内容进行封装.各个组件单独维护.体现了分治的思想(分布式思想)
补充知识: 为了保证组件化 相互之间互不干扰,则应该在组件内部 单独定义html/js/css.
在这里插入图片描述

2.2 组件注册

2.2.1 组件化入门案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>组件</title>
	</head>
	<body>
		<div id="app">
			<!-- 3.调用组件 -->
			<hello></hello>
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//定义全局组件 参数1:定义组件名称 暂时不要使用驼峰规则
			//				参数2:定义组件对象
			Vue.component('hello',{
				//1.组件数据
				//必须有返回值  返回值是一个对象
				data(){
					return{
						msg: 'hello 组件'
					}
				},
				//2.组件结构 html数据
				template: '<h1>{{msg}}</h1>'
			})
			
			// 注意事项:组件的使用必须有Vue对象的渲染
			const app = new  Vue({
				el: '#app'
			})
		</script>
	</body>
</html>

2.2.2 组件驼峰规则命名

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>驼峰命名规则</title>
	</head>
	<body>
		<div id="app">
			<!-- 3.调用组件 -->
			<!-- 注意事项:
					1.如果组件名称使用驼峰规则,则默认的条件下vue渲染数据时都采用字母小写
					hellocomponent 所以导致组件不能匹配
					2.如果需要使用驼峰规则 则使用'-'线连接
					强调:组件的调用时可以添加'-'线-->
			<hello-component></hello-component>
		</div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//定义全局组件 参数1:定义组件名称 暂时不要使用驼峰规则
			//				参数2:定义组件对象
			Vue.component('helloComponent',{
				//1.组件数据
				//必须有返回值  返回值是一个对象
				data(){
					return{
						msg: 'hello 组件'
					}
				},
				//2.组件结构 html数据
				template: '<h1>{{msg}}</h1>'
			})
			
			// 注意事项:组件的使用必须有Vue对象的渲染
			const app = new  Vue({
				el: '#app'
			})
		</script>
	</body>
</html>

2.2.3 组件模板标签的使用

  • ’ ’   ` ` 的使用

在这里插入图片描述

  • 组件template的写法
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>组件模板标签的使用</title>
	</head>
	<body>
		<div id="app">
			<!-- 3.调用组件 -->
			<!-- 注意事项:
					1.如果组件名称使用驼峰规则,则默认的条件下vue渲染数据时都采用字母小写
					hellocomponent 所以导致组件不能匹配
					2.如果需要使用驼峰规则 则使用'-'线连接
					强调:组件的调用时可以添加'-'线-->
			<hello-component></hello-component>
		</div>
		
		<!-- 
			模板标签的用法
			 1.模板标签不要与Vue的div相耦合
			 2.template标签需要添加id进行标识
			 3.template模板标签中 必须有根标签
			 -->
		<template id="helloTem">
			<div>
				<h1>{{msg}}</h1>
			</div>
		</template>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//定义全局组件 参数1:定义组件名称 暂时不要使用驼峰规则
			//				参数2:定义组件对象
			Vue.component('helloComponent',{
				//1.组件数据
				//必须有返回值  返回值是一个对象
				data(){
					return{
						msg: 'hello 组件'
					}
				},
				//2.组件结构 html数据
				// ' ' 当前行有效
				// ` ` 支持多种格式的html
				//template: '<h1>{{msg}}</h1>'
				//组件模板优化
				template: '#helloTem'
			})
			
			// 注意事项:组件的使用必须有Vue对象的渲染
			const app = new  Vue({
				el: '#app'
			})
		</script>
	</body>
</html>

2.2.4 注意事项

  • 组件中的data 是一个函数 data(){return {}}
  • 组件模版的内容必须是一个根元素.
  • 组件如果采用驼峰规则命名,则使用-线进行关联

2.3 局部组件注册

通过components关键字定义局部组件

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

		<template id="hello1">
			<div>
				<h3>{{msg}}</h3>
			</div>
		</template>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//1.定义组件对象
			const hello1 = {
				data() {
					return {
						msg: 'hello1局部组件'
					}
				},
				template: '#hello1'
			}
			/* 局部组件的写法 */
			const app = new Vue({
				el: '#app',
				//vue对象中的组件  组件名称/组件对象
				components: {
					//'hello1' : hello1
					//js简化写法 如果key与value值相同,则可以简化.
					hello1
				}
			})
		</script>
	</body>
</html>

2.4 全局组件中引用局部组件——使用不生效

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>组件注册</title>
	</head>
	<body>
		<div id="app">
			<hello1></hello1>
			<hello2></hello2>
			<hello3></hello3>
		</div>

		<!-- 定义模版代码1 -->
		<template id="hello1">
			<div>
				{{msg}}
			</div>
		</template>
		<!-- 定义模版代码2 -->
		<template id="hello2">
			<div>
				{{msg}}
			</div>
		</template>
		<!-- 定义模版代码3 -->
		<template id="hello3">
			<div>
				{{name}}
				<!-- 在全局组件中引用局部组件 使用不生效 -->
				<!-- <hello1></hello1> -->
			</div>
		</template>

		<!--引入js函数类库  -->
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//定义全局组件
			Vue.component('hello3', {
				data() {
					return {
						name: '定义全局组件'
					}
				},
				template: "#hello3"
			})

			/* 定义局部组件1 */
			let hello1 = {
				data() {
					return {
						msg: '你好Hello1'
					}
				},
				template: "#hello1"
			}
			/* 定义局部组件2 */
			let hello2 = {
				data() {
					return {
						msg: '你好Hello2'
					}
				},
				template: "#hello2"
			}

			const app = new Vue({
				el: "#app",
				data: {

				},
				//只能在当前元素中使用
				components: {
					'hello1': hello1,
					'hello2': hello2
				}
			})
		</script>
	</body>
</html>

3 Vue前端交互

3.1 Promise概述

Promise是一种异步编程的一种解决方案.从语法上将Promise是一个对象.从它身上可以获取异步调用的信息

  • 有效避免回调地狱问题 典型的Ajax嵌套问题 (闭包方式)
  • Promise对象提供了简洁的API 用法简单

3.2 Promise基本用法

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app"></div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			const app = new Vue({
				el: '#app'
			})

			//1.定义promise对象
			//成功调用resolve  失败调用reject
			let promise = new Promise(function(resolve, reject) {
				let flag = true
				if (flag) {
					resolve("业务执行成功")
				} else {
					reject("业务执行失败")
				}
			})
			//通过then获取回调函数
			promise.then(function(result) {
				//从resolve中获取数据
				console.log(result)
			}, function(result) {
				//从reject中获取数据
				console.log(result)
			})
		</script>
	</body>
</html>

3.3 Promise API介绍

  • then 异步调用正确时返回
  • catch 获取异常信息
  • finally 成功与否都会执行的操作
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>promise调用API</title>
	</head>
	<body>
		<div id="app"></div>
		<script src="../js/vue-2.7.16.js"></script>
		<script>
			//1.定义promise对象
			let promise = new Promise(function(resolve, reject) {
				let flag = true
				if (flag) {
					resolve("业务执行成功")
				} else {
					reject("业务执行失败")
				}
			})

			//通过then获取回调函数
			promise.then(function(result) {
					//从resolve中获取数据
					console.log(result)
				})
				.catch(function(data) {
					console.log(data)
				})
				.finally(function() {
					console.log("最终都会执行")
				})
		</script>
	</body>
</html>

3.4 Axios方式

3.4.1 Axios介绍

  • Axios 是一个基于 promise(内部封装了ajax) 的 HTTP 库,可以用在浏览器和 node.js 中
    • 作用: 在内部 简化异步调用
  • 特点:
    • 从浏览器中创建 XMLHttpRequests
    • 从 node.js 创建 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求数据和响应数据
    • 取消请求
    • 自动转换 JSON 数据
    • 客户端支持防御 XSRF

3.4.2 Axios入门案例

3.4.2.1 编辑页面html
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Axios入门案例</title>
	</head>
	<body>
		<h1>Axios Ajax调用</h1>
		<!-- 1.导入js类库 -->
		<script src="../js/axios-1.6.7.js"></script>
		<script>
			//1.发起Get请求
			// 原始参数  1: url地址  参数2:提交参数  参数3:回调函数
			// 知识点: 传统的ajax的操作有"回调地狱问题" '闭包' 
			// 回调地狱问题: 由于业务复杂,导致多重的ajax进行嵌套. 如果中间出现任何问题.则导致整个ajax调用失败.

			//参数 1: url地址  2.提交的参数
			//跨域请求: 浏览器不能正常执行!!!!
			let url = "http://localhost:8090/hello"
			axios.get(url)
				.then(function(result) {
					//获取返回值 promise对象
					console.log(result)
					//如果需要获取服务器的返回值则使用.data属性
					console.log(result.data)
				})
		</script>
	</body>
</html>
3.4.2.2 编辑后台AxiosController
package com.jt.controller;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

//在后端接收前端axios发来的请求
@RestController
@CrossOrigin //允许当前类中的所有方法执行跨域操作!!
public class AxiosController {
    /**
     * Axios入门案例
     * url:http://localhost:8090/hello
     */
    @GetMapping("/hello")
    public String hello() {
        return "Vue的Ajax异步调用";
    }
}

3.4.3 Axios GET/DELETE调用

注意事项 GET/DELETE语法相同!!!
3.4.3.1 get方式
let url = "http://localhost:8090/hello"
axios.get(url)
	.then(function(result) {
		//获取返回值 promise对象
		console.log(result)
		//如果需要获取服务器的返回值则使用.data属性
		console.log(result.data)
	})
/**
* Axios入门案例
* url:http://localhost:8090/hello
*/
@GetMapping("/hello")
public String hello() {
     return "Vue的Ajax异步调用";
}
3.4.3.2 带参数的get请求
//2.带参数的get请求
//url:http://localhost:8090/axios?id=100
axios.get('http://localhost:8090/axios?id=100')
	.then(result=>{
		console.log(result.data)
	})
/**
* 接受get请求的ID参数
* url:http://localhost:8090/axios?id=100
*/
@GetMapping("/axios")
public String getAxios(Integer id) {
    return "动态获取数据" + id;
}
3.4.3.3 Get RestFul风格
//3.RestFul风格
axios.get('http://localhost:8090/axios/100')
	.then(result=>{
		console.log(result.data)
	})
/**
* RestFul接收参数
* url:http://localhost:8090/100
*/
@GetMapping("/axios/{id}")
public String axiosRestFul(@PathVariable Integer id) {
    return "RestFul接受参数" + id;
}
3.4.3.4 Get params参数方式
//4.利用params对象的方式传递参数
axios.get('http://localhost:8090/axiosParams',{
		params: {
			id: 100
		}
	}).then(result=>{
		console.log(result.data)
	})
/**
* 测试params对象传递参数
*/
@GetMapping("/axiosParams")
public String params(Integer id){
    return "params获取参数"+id;
}

在这里插入图片描述
在这里插入图片描述

3.4.4 Axios post/put 调用

3.4.4.1 对象方式提交数据
/**
* Post/Put请求的说明:
* 	如果采用对象的方式进行数据传输,则发起请求时自动的转换为JSON格式进行数据传递
*/
axios.post('http://localhost:8090/addAxios',{
  	  id: 100,
	  name: 'tomcat'
	}).then(result=>{
		console.log(result.data)
	})
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class AxiosPOJO {
    private Integer id;
    private String name;
}
/**
     * 动态接收Post请求 并且接收JSON参数
     * url:/addAxios
     * 语法:
     *      如果前端传递的是一个JSON字符串
     *      则使用注解@RequestBody 将JSON串转换为对象
*/
@PostMapping("/addAxios")
public AxiosPOJO addAxios(@RequestBody AxiosPOJO axiosPOJO){
	return axiosPOJO;
}
3.4.4.2 Form表单数据
/**
 * 通过form表单的方式提交数据
*/
//1.定义form表单对象
let params = new URLSearchParams();
params.append('id',100)
params.append('name','tomcat')
axios.post('http://localhost:8090/addAxiosForm',params)
	.then(result=>{
		console.log(result.data)
	})
/**
* 利用Form表单接收数据
*/
@PostMapping("/addAxiosForm")
public AxiosPOJO addAxiosForm(AxiosPOJO axiosPOJO){
    return axiosPOJO;
}

在这里插入图片描述

3.4.4.3 restFul方式提交数据
//RestFul方式传参
axios.post('http://localhost:8090/addAxiosRestFul/100/tomcat')
	.then(result=>{
		console.log(result.data)
	})
/**
* ResatFul方式
*/
@PostMapping("/addAxiosRestFul/{id}/{name}")
public AxiosPOJO addAxiosRestFul(AxiosPOJO axiosPOJO){
	return axiosPOJO;
}

3.4.5 Axios 配置信息

//配置基本请求路径
axios.defaults.baseURL = "http://localhost:8090/"
//设定请求头信息
//axios.defaults.headers['mytoken'] = 'token-123456'
axios.defaults.headers.mytoken = '112233445566'
//配置基本请求路径
axios.defaults.baseURL = "http://localhost:8090/"
//设定请求头信息
// axios.defaults.headers['mytoken'] = 'token-123456'
axios.defaults.headers.mytoken = '112233445566'
axios.get('hello')
	.then(result=>{
		console.log(result.data)
	})

在这里插入图片描述
在这里插入图片描述

3.4.6 Axios 拦截器机制

在这里插入图片描述

3.4.6.1 请求拦截器
//1.定义请求拦截器
axios.interceptors.request.use(function(config){
	//console.log(config)
	//在请求发出前进行信息设置
	config.headers.mytoken = 'qwerqwerqwer'
	return config
},function(error){
	//报错信息返回
	console.log(error)
})
3.4.6.2 响应拦截器
//2.定义响应拦截器
axios.interceptors.response.use(function(response){
	console.log(response)
	return response
},function(error){
	console.log(error)
})	
axios.get("http://localhost:8090/getJSON")
	.then(function(result){
		//console.log(result.data)
	})

在这里插入图片描述

3.4.7 async-await用法

3.4.7.1 介绍
  • async-await
    • 是ES7 引入的最新的规范 更加简单的进行异步调用
  • async
    • 用来标识方法(函数)
  • await
    • 标识ajax调用
3.4.7.2 入门案例用法
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Async-Await</title>
	</head>
	<body>
		<script src="../js/axios-1.6.7.js"></script>
		<script>
			//配置基本请求路径
			axios.defaults.baseURL = "http://localhost:8090/"

			//原始写法
			function getHello1() {
				axios.get('hello').then(result => {
					console.log(result.data)
				})
			}

			//使用async与await定义方法
			async function getHello2() {
				//返回一个promise对象
				const result = await axios.get('hello')
				//通过data获取数据
				console.log(result.data)
			}
			
			//调用函数
			getHello2()
		</script>
	</body>
</html>
3.4.7.3 解构赋值操作
  • 采用解构赋值的操作让代码更加灵活
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Async-Await</title>
	</head>
	<body>
		<script src="../js/axios-1.6.7.js"></script>
		<script>
			//配置基本请求路径
			axios.defaults.baseURL = "http://localhost:8090/"

			async function getHello3() {
				//data:是对象中的属性
				//解构赋值:将返回的对象的数据 采用指定的对象接收
				//value 表示接收返回值结果
				const {data: value} = await axios.get('hello')
				//通过data获取数据
				console.log(value)
			}
			
			//调用函数
			getHello3()
		</script>
	</body>
</html>

3.4.8 VUE实现用户列表展现

3.4.8.1 编辑AxiosUserController
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//使用VUE的方式 实现用户的CRUD操作
@RestController
@CrossOrigin
public class AxiosUserController {
    @Autowired
    private UserService userService;

    /**
     * 1.查询数据库用户列表数据
     * 2.url:/axiosUser/findAll
     * 3.返回值结果:List<User>
     */
    @GetMapping("/axiosUser/findAll")
    public List <User> findAll(){
        return userService.findAll();
    }
}
@Override
public List<User> findAll() {
	return userMapper.selectList(null);
}

在这里插入图片描述

3.4.8.2 获取用户列表数据
  • 利用mouted方法 初始化数据
  • 利用axios方式获取数据
<!DOCTYPE html>
<head>
	<meta charset="UTF-8">
	<title>用户列表数据</title>
</head>
<body>
	<div id="app">
		用户编号:<input type="text" disabled /><!-- disabled 元素禁用 -->
		用户姓名:<input type="text" /><br />
		用户年龄:<input type="text" />
		用户性别:<input type="text" />
		<button>更新</button>
		<hr />
		<!-- 用户展现的表格 -->
		<table id="userTable" border="1px" align="center" width="800px">
			<tr align="center">
				<td colspan="5">
					<h3>用户列表</h3>
				</td>
			</tr>
			<tr align="center">
				<td>ID</td>
				<td>名称</td>
				<td>年龄</td>
				<td>性别</td>
				<td>操作</td>
			</tr>
			<tr align="center">
				<td>100</td>
				<td>张三</td>
				<td>18</td>
				<td></td>
				<td>
					<button>修改</button>
					<button>删除</button>
				</td>
			</tr>
		</table>
	</div>
	<!-- 1.引入页面JS -->
	<script src="../js/vue-2.7.16.js"></script>
	<script src="../js/axios-1.6.7.js"></script>

	<!-- 2.编辑自己的JS代码 -->
	<script>
		//1.定义默认的axios请求路径
		axios.defaults.baseURL = "http://localhost:8090/"
		
		const app = new Vue({
			el: '#app',
			data: {
				//1.定义用户列表的数据
				userList: [],
			},
			methods: {
				//1.发起get请求
				async getUserList() {
					const {data: result} = await axios.get('/axiosUser/findAll')
					this.userList = result
				}
			},
			mounted() {
				//当前页面渲染成功之后调用
				//调用查询用户的方法
				this.getUserList()
			}
		})
	</script>
</body>
</html>
3.4.8.3 循环遍历数据
<tr align="center" v-for="user in userList" :key="user.id">
	<td>{{user.id}}</td>
	<td>{{user.name}}</td>
	<td>{{user.age}}</td>
	<td>{{user.sex}}</td>
	<td>
		<button>修改</button>
		<button>删除</button>
	</td>
</tr>
<tr align="center" v-for="user in userList">
	<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>修改</button>
		<button>删除</button>
	</td>
</tr>	
3.4.8.4 修改用户实现数据回显

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.8.5 实现用户修改

在这里插入图片描述
在这里插入图片描述

/**
* 1.实现更新操作
* 2.url:/axiosUser/updateUser
* 3.参数: user对象的JSON串
* 4.返回值: 不要求有返回值 void即可
*/
@PutMapping("/axiosUser/updateUser")
public void updateUser(@RequestBody User user){
    userService.updateUser(user);
}
@Override
public void updateUser(User user) {
	userMapper.updateById(user);
}
3.4.8.6 实现用户数据删除

在这里插入图片描述
在这里插入图片描述

/**
* 1.实现删除操作
* 2.url:axiosUser/deleteUser?id=1
* 3.参数: id=1
* 4.返回值: void
*/
@DeleteMapping("/axiosUser/deleteUser")
public void deleteUser(Integer id){
	userService.deleteUserById(id);
}
@Override
public void deleteUserById(Integer id) {
	userMapper.deleteById(id);
}
3.4.8.7 最终代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>用户列表展现案例</title>
	</head>
	<body>
		<div id="app">
			<h1 align="center">用户列表展现案例</h1>
			<table align="center" border="1px" width="800px">
				<tr align="center">
					<td>ID编号</td>
					<td>姓名</td>
					<td>年龄</td>
					<td>性别</td>
					<td>操作</td>
				</tr>
				<tr align="center" v-for="user in userList" :key="user.id">
					<td>{{user.id}}</td>
					<td>{{user.name}}</td>
					<td>{{user.age}}</td>
					<td>{{user.sex}}</td>
					<td>
						<button @click="updateUser(user)">修改</button>
						<button @click="deleteUser(user)">删除</button>
					</td>
				</tr>
			</table>
			<hr />
			<div>
				<h3 align="center">用户修改操作</h3><br>
				<p>
						用户ID号: <input type="text" name="id" v-model="user.id" disabled/>
						用户名称: <input type="text" name="name" v-model="user.name"/>
				</p>
				<p>
					用户年龄: <input type="text" name="age" v-model="user.age"/>
					用户性别: <input type="text" name="sex" v-model="user.sex"/>
				</p>
				<p>
					<button @click="updateUserBtn">修改</button>
				</p>
			</div>
		</div> 
		
		
		<script src="../js/axios.js"></script>
		<script src="../js/vue.js"></script>
		<script>
			//1.定义默认的axios请求路径
			axios.defaults.baseURL = "http://localhost:8090/"
			
			const app = new Vue({
				el: "#app",
				data: {
					//准备用户数据
					userList: [],
					user: {
						id: '',
						name: '',
						age: '',
						sex: ''
					}
				},
				methods: {
					//1.发起get请求
					async getUserList(){
						const {data: result} = await axios.get('/getUserList')
						this.userList = result
					},
					updateUser(user){
						//1.获取页面修改的数据
						this.user = user
					},
					async updateUserBtn(){
						await axios.put('updateUser',this.user)
						//重新加载页面数据
						this.getUserList()
					},
					async deleteUser(user){
						let id = user.id
						await axios.delete('user/'+id)
						//删除之后,重新加载数据
						this.getUserList()
					}
				},
				mounted(){
					this.getUserList()
				}
			})
		</script>
	</body>
</html>
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//使用VUE的方式 实现用户的CRUD操作
@RestController
@CrossOrigin
public class AxiosUserController {
    @Autowired
    private UserService userService;

    /**
     * 1.查询数据库用户列表数据
     * 2.url:/axiosUser/findAll
     * 3.返回值结果:List<User>
     */
    @GetMapping("/axiosUser/findAll")
    public List <User> findAll(){
        return userService.findAll();
    }

    /**
     * 1.实现更新操作
     * 2.url:/axiosUser/updateUser
     * 3.参数: user对象的JSON串
     * 4.返回值: 不要求有返回值 void即可
     */
    @PutMapping("/axiosUser/updateUser")
    public void updateUser(@RequestBody User user){
        userService.updateUser(user);
    }

    /**
     * 1.实现删除操作
     * 2.url:axiosUser/deleteUser?id=1
     * 3.参数: id=1
     * 4.返回值: void
     */
    @DeleteMapping("/axiosUser/deleteUser")
    public void deleteUser(Integer id){
        userService.deleteUserById(id);
    }
}
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService{

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> findAll() {
        return userMapper.selectList(null);
    }

    @Override
    public void updateUser(User user) {
        userMapper.updateById(user);
    }

    @Override
    public void deleteUserById(Integer id) {
        userMapper.deleteById(id);
    }
}

3.4.9 跨域

3.4.9.1 同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

浏览器出于安全性的考虑,要求所有的请求都必须满足同源策略!

要素: 请求协议://域名:端口 必须相同!

3.4.9.2 跨域问题
  • Ajax的请求违反同源策略,ajax的请求就称之为跨域访问

在这里插入图片描述

  • 跨域练习:
    • 页面地址 https://www.jd.com/xxx/xx
    • ajax请求地址 http://www.jd.com/xx/xx
      • 协议不同,是跨域请求
    • 页面地址 http://www.jd.com/xxx/xx
    • ajax请求地址 http://192.168.1.100/xx/xx 备注: IP就是域名的IP
      • 域名不同 是跨域访问
    • 页面地址 http://www.jd.com:80/xxx/xx
    • ajax请求地址 http://www.jd.com:8090/xx/xx
      • 端口不同 是跨域访问
3.4.9.3 CORS

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS的实质就是在服务器端添加允许访问的响应头 CORS是服务端的一种技术.

在这里插入图片描述

3.4.9.4 响应头信息

在这里插入图片描述

  • *号可以换成特定的网址.则只允许该网址访问

在这里插入图片描述
在这里插入图片描述

4 VUE路由

4.1 VUE Router介绍

  • Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:
    • 嵌套的路由/视图表
    • 模块化的、基于组件的路由配置
    • 路由参数、查询、通配符
    • 基于 Vue.js 过渡系统的视图过渡效果
    • 细粒度的导航控制
    • 带有自动激活的 CSS class 的链接
    • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
    • 自定义的滚动条行为

4.1.1 后端路由

在这里插入图片描述

4.1.2 前端路由

前端路由在内部配置了路由表,之后用户发起请求之后,根据路由表的内容直接跳转html页面(组件)
在这里插入图片描述

4.2 Router 路由入门案例

4.2.1 Router使用步骤

  • 引入路由的js库文件
  • 添加路由链接
  • 添加路由的填充位
  • 定义路由组件.
  • 配置路由规则并且创建路由实例
  • 实现路由的挂载(到Vue根实例中)

4.2.2 Router 入门案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>路由规则</title>
	</head>
	<body>
		<div id="app">
			<!-- 2. 添加路由链接
					Vue中默认添加路由规则
					router-link:vue会将标签解析为a标签
					to:vue会解析为href属性
			 -->
			<router-link to="/user">用户</router-link>
			<router-link to="/dept">部门</router-link>
			<!-- 3.定义路由填充位 
				   当用户点击路由时 在该位置展现页面 理解为新的div 
			-->
			<router-view></router-view>
		</div>
		<!-- 1.引入js  -->
		<script src="../js/vue-2.7.16.js"></script>
		<script src="../js/vue-router-3.5.1.js"></script>
		<script>
			/*4.定义组件变量*/
			const user = {
				template: '<h1>我是user组件</h1>'
			}
			const dept = {
				template: '<h1>我是dept组件</h1>'
			}
			/*5.配置路由规则
				属性routes[] 定义路由规则
				path: 定义路径
				component: 定义组件名称
			*/
			const router = new VueRouter({
				//定义规则
				routes: [
					{path: '/user',component: user},
					{path: '/dept',component: dept}
				]
			})
			//6.将路由组件挂载到Vue中
			const app = new Vue({
				el: '#app',
				//挂载路由实例对象   如果名称一致 可以简化
				//router: router
				router
			})
		</script>
	</body>
</html>

4.3 Router 重定向

  • 路由的组件提供了重定向的功能,可以让用户默认跳转指定的组件
    • 当用户访问A地址时,强制跳转访问B 则需要使用路由重定向技术
  • 关键子: redirect

在这里插入图片描述

4.4 Router 嵌套

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>路由嵌套</title>
	</head>
	<body>
		<div id="app">
			<router-link to="/shopping">商场</router-link>
			<router-link to="/zoo">动物园</router-link>
			<router-view></router-view>
		</div>
		
		<!-- 定义商场组件 -->
		<template id="shoppingTem">
			<div>
				<h1>我是商场组件</h1>
				<router-link to="/shopping/shoe">鞋店</router-link>
				<router-link to="/shopping/phone">手机店</router-link>
				<router-view></router-view>
			</div>
		</template>
		<script src="../js/vue-2.7.16.js"></script>
		<script src="../js/vue-router-3.5.1.js"></script>
		<script>
			const shopping = {
				template: '#shoppingTem'
			}
			const zoo = {
				template: '<h1>我是动物园组件</h1>'
			}
			const shoe = {
				template: '<h1>我是鞋店</h1>'
			}
			const phone = {
				template: '<h1>我是手机店</h1>'
			}
			const router = new VueRouter({
				routes: [
					{path: '/shopping',component: shopping,children:[
						{path: '/shopping/shoe',component: shoe},
						{path: '/shopping/phone',component: phone}
					]},
					{path: '/zoo',component: zoo}
				]
			})
			const app = new Vue({
				el: '#app',
				router
			})
		</script>
	</body>
</html>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/414298.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Centos6安装PyTorch要求的更高版本gcc

文章目录 CentOS自带版本安装gcc 4的版本1. 获取devtoolset-8的yum源2. 安装gcc3. 版本检查和切换版本 常见问题1. 找不到包audit*.rpm包2. 找不到libcgroup-0.40.rc1-27.el6_10.x86_64.rpm 的包4. cc: fatal error: Killed signal terminated program cc1plus5. pybind11/pybi…

如何使用Fastapi上传文件?先从请求体数据讲起

文章目录 1、请求体数据2、form表单数据3、小文件上传1.单文件上传2.多文件上传 4、大文件上传1.单文件上传2.多文件上传 1、请求体数据 前面我们讲到&#xff0c;get请求中&#xff0c;我们将请求数据放在url中&#xff0c;其实是非常不安全的&#xff0c;我们更愿意将请求数…

【C语言】linux内核ipoib模块 - ipoib_ib_handle_tx_wc

一、中文注释 这个函数是用来处理 Infiniband 设备在传输完成时的回调。该回调负责释放发送队列中的缓冲区并更新网络设备统计信息。 static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) {// 通过net_device结构体获取私有数据结构struct ipoib_d…

网络安全之内容安全

内容安全 攻击可能只是一个点&#xff0c;防御需要全方面进行 IAE引擎 DFI和DPI技术--- 深度检测技术 DPI --- 深度包检测技术--- 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对 数据包的内容进行识别。&#xff08;应用…

S32 Design Studio PE工具配置TMR

配置步骤 配置内容 生成的配置结构体如下&#xff0c;在Generated_Code路径下的lpTmr.c文件和lpTmr.h文件。 /*! lpTmr1 configuration structure */ const lptmr_config_t lpTmr1_config0 {.workMode LPTMR_WORKMODE_PULSECOUNTER,.dmaRequest false,.interruptEnable tr…

数据抽取平台pydatax介绍--实现和项目使用

数据抽取平台pydatax实现过程中&#xff0c;有2个关键点&#xff1a; 1、是否能在python3中调用执行datax任务&#xff0c;自己测试了一下可以&#xff0c;代码如下&#xff1a; 这个str1就是配置的shell文件 try:result os.popen(str1).read() except Exception as …

git忽略某些文件(夹)更改方法

概述 在项目中,常有需要忽略的文件、文件夹提交到代码仓库中,在此做个笔录。 一、在项目根目录内新建文本文件,并重命名为.gitignore,该文件语法如下 # 以#开始的行,被视为注释. # 忽略掉所有文件名是 a.txt的文件. a.txt # 忽略所有生成的 java文件, *.java # a.j…

数据结构:栈和队列与栈实现队列(C语言版)

目录 前言 1.栈 1.1 栈的概念及结构 1.2 栈的底层数据结构选择 1.2 数据结构设计代码&#xff08;栈的实现&#xff09; 1.3 接口函数实现代码 &#xff08;1&#xff09;初始化栈 &#xff08;2&#xff09;销毁栈 &#xff08;3&#xff09;压栈 &#xff08;4&…

【MQ05】异常消息处理

异常消息处理 上节课我们已经学习到了消息的持久化和确认相关的内容。但是&#xff0c;光有这些还不行&#xff0c;如果我们的消费者出现问题了&#xff0c;无法确认&#xff0c;或者直接报错产生异常了&#xff0c;这些消息要怎么处理呢&#xff1f;直接丢弃&#xff1f;这就是…

ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the ‘ssl‘报错解决

安装labelme出错了 根据爆栈的提示信息&#xff0c;我在cmd运行以下命令之后一切正常了&#xff0c;解决了问题&#xff01; pip install urllib31.26.6参考网址&#xff1a;ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1, currently the ‘ssl’ module is compile…

常见的socket函数封装和多进程和多线程实现服务器并发

常见的socket函数封装和多进程和多线程实现服务器并发 1.常见的socket函数封装2.多进程和多线程实现服务器的并发2.1多进程服务器2.2多线程服务器2.3运行效果 1.常见的socket函数封装 accept函数或者read函数是阻塞函数&#xff0c;会被信号打断&#xff0c;我们不能让它停止&a…

docker容器技术(3)

Docker技术编排 概述&#xff1a; docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题&#xff1f; 如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,…

【XR806开发板试用】socket客户端与虚拟机服务器通信交互测试以及终端交互

XR806 客户端准备工作。 1、连接wifi 2、创建socket连接服务器。 3、创建终端接收数据线程。 wifi_connect.c #include <stdio.h> #include <string.h> #include "wifi_device.h" #include "wifi_hotspot.h" #include "kernel/os/os.h…

桥接模式(Bridge Pattern) C++

上一节&#xff1a;适配器模式&#xff08;Adapter Pattern&#xff09; C 文章目录 0.理论1.组件2.使用场景 1.实践 0.理论 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它的核心思想是将抽象部分与其实现部分分离&#xff0c;使它们可…

区块链智能合约开发

一.区块链的回顾 1.区块链 区块链实质上是一个去中心化、分布式的可进行交易的数据库或账本 特征: 去中心化&#xff1a;简单来说&#xff0c;在网络上一个或多个服务器瘫痪的情况下&#xff0c;应用或服务仍然能够持续地运行&#xff0c;这就是去中心化。服务和应用部署在…

死区过滤器Deadband和DeadZone区别(应用介绍)

死区过滤器的算法和详细介绍专栏也有介绍,这里我们主要对这两个模块的区别和应用场景进行详细介绍 1、死区过滤器 https://rxxw-control.blog.csdn.net/article/details/128521007https://rxxw-control.blog.csdn.net/article/details/128521007 1、Deadband和DeadZone区别…

kafka学习笔记三

目录 第二篇 外部系统集成 第三篇 生产调优手册 第1章 kafka硬件配置选择 第2章 生产者调优 2.1 生产者核心参数配置 2.2 生产者如何提高吞吐量 2.3 数据可靠性 2.4 数据去重 2.5 数据有序 2.6 数据乱序 第3章 Kafka Broker调优 3.1 Broker核心参数配置 3.2 其他 …

k8s service的概念以及创建方法

Service 的功能&#xff1a; Service主要用于提供网络服务&#xff0c;通过Service的定义&#xff0c;能够为客户端应用提供稳定的访问地址&#xff08;域名或IP地址&#xff09;和负载均衡功能&#xff0c;以及屏蔽后端Endpoint的变化&#xff0c;是K8s实现微服务的核心资源。…

【README 小技巧】 展示gitee中开源项目start

【README 小技巧】 展示gitee中开源项目start <a target"_blank" hrefhttps://gitee.com/wujiawei1207537021/wu-framework-parent><img srchttps://gitee.com/wujiawei1207537021/wu-framework-parent/badge/star.svg altGitee star/></a>

使用ffmpeg压缩视频

一、到ffmpeg官网下载文件包&#xff1a; Download FFmpeg 下载后找到 bin 下的3个exe文件&#xff0c;复制到自己本机的某个目录下, 如&#xff1a; 二、使用命令行压缩&#xff1a; ffmpeg -i input.mp4 -c:v libx265 -crf 28 -y output.mp4 这条命令使用 FFmpeg 工具对输…