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