# Vue基础
# 前后端交互
# json-server基本使用
目的:模拟后台接口。
问题:前端需要依赖后台接口才能获取数据,但是我们前端开发的时候,后台一定写好了接口吗?
模拟接口:使用json-server这个基于nodejs的命令行工具,模拟后台接口,让前端可以继续进行开发。
npm i json-server -g --registry=https://registry.npm.taobao.org
- 准备db.json文件
{
"books": [
{"id":1,"bookname":"西游记","createTime":"2010-10-10 10:10:10"}
]
}
- 进入db.json文件所在目录,启动server服务
json-server db.json
- 如果json-server服务启动了,我们通过 http://localhost:3000/books访问数组数据。
# 通过postman测试接口
目的:了解接口规则。
我们使用json-server启动的接口符合Restful接口定义的规则。
- url路径中一般使用名词的复数
- 请求的参数使用 /123 这种风格传递,而不使用 ?id=123这种风格
- 严格区分请求方式
| 路径 | 请求方式 | 具体对应操作 |
|---|---|---|
| /books | GET | 获取图书数组数据 |
| /books/1 | GET | 获取当前图书数据 |
| /books | POST | 添加图书(请求体传参) |
| /books/1 | DELETE | 删除图书 |
| /books/1 | PUT | 修改图书(请求体传参) 完整修改:没有提交的数据修改为空 |
| /books/1 | PATCH | 修改图书(请求体传参) 局部修改:没有提交的数据不做修改 |
# axios基本用法
# 基本介绍
前端调用接口
- 原始ajax
- 基于jQuery的封装的ajax方法 $.ajax/$.get/$.post
- axios (opens new window) 是一个js库,专门用于调用接口
axios的核心特性
- 可以从浏览器端发送ajax请求
- 可以从node.js环境发送请求
- 支持 Promise API
- 支持请求和响应拦截器
- 可以转换请求和响应的数据
- 支持请求的取消
- 自动转换json格式数据
- 可以更加安全的发送请求
# 基本用法
- axios发送get请求
- ret这个数据被axios包裹了一层属性data
// 基于axios发送请求
axios.get('http://localhost:3000/books').then(function (ret) {
// ret这个数据被axios包裹了一层属性data
console.log(ret.data)
})
- axios发送post请求
// 参数一表示请求地址,参数二表示请求提交的参数
axios.post('http://localhost:3000/books', {
bookname: '三国演义',
createTime: '2010-10-10 10:10:12'
}).then(ret => {
console.log(ret)
})
- 基于通用的axios方法发送请求
// // 基于axios函数发送get请求
// axios({
// method: 'get',
// url: 'http://localhost:3000/books'
// }).then(ret => {
// console.log(ret)
// })
// ----------------------------
const btn = document.getElementById('btn')
btn.onclick = function () {
// 基于axios函数发送post请求
axios({
method: 'post',
data: {
bookname: '智能时代',
createTime: '2010-10-10 10:10:22'
},
url: 'http://localhost:3000/books'
}).then(ret => {
console.log(ret)
})
}
- 设置请求的基准路径
// 配置axios的基准路径(这样统一配置后,再发送请求时可以省略这部分)
axios.defaults.baseURL = 'http://localhost:3000/'
axios.get('books').then(ret => {
if (ret.data) {
this.books = ret.data
}
})
# 图书案例案例-接口版
# 图书列表功能
目标:实现图书列表渲染功能(调用接口实现)
- 页面打开时自动触发接口调用
- 接口获取数据成功后,更新data中的列表数据
// 配置axios的基准路径(这样统一配置后,再发送请求时可以省略这部分)
axios.defaults.baseURL = 'http://localhost:3000/'
methods: {
// 调用接口获取图书列表数据
loadBookList () {
axios.get('books').then(ret => {
if (ret.data) {
this.books = ret.data
}
})
}
},
mounted () {
// 页面渲染完成后触发
this.loadBookList()
}
- 图书列表动态填充
<tr v-for='item in books' :key='item.id'>
<td>{{item.id}}</td>
<td>{{item.bookname}}</td>
<td>{{item.createTime}}</td>
<td>删除|修改</td>
</tr>
# 删除图书
目标:实现图书删除功能
1、绑定删除事件并传递id
2、调用接口进行删除
3、删除成功后刷新列表
// 实现图书删除
handleDelete (id) {
// 删除操作一般需要确认
if (confirm('确认要删除吗')) {
axios.delete('books/' + id).then(ret => {
if (ret.status === 200) {
// 删除成功,重新渲染列表
this.loadBookList()
}
})
}
},
# 添加图书
目标:实现添加图书功能
- 绑定按钮事件
- 获取表单数据
- 调用接口添加图书
- 根据返回的状态刷新列表
- 清空表单
// 实现添加图书
handleSubmit () {
if (!this.bookname) {
// 没有输入内容
alert('请输入图书名称')
return
}
// 调用接口添加图书
const book = {
bookname: this.bookname,
createTime: new Date()
}
axios.post('books', book).then(ret => {
if (ret.status === 201) {
// 添加图书成功,刷新列表,清空表单
this.loadBookList()
this.bookname = ''
}
})
},
# 搜索图书
目标:掌握vue侦听器功能
侦听器应用场景:在需要监听某项数据的变化然后去,做异步操作或开销较大操作(逻辑非常复杂)。
补充:凡是以后需要监听数据的变化而去做一些事情,就可以使用侦听器。
- 基本用法
new Vue({
data: {
msg: 'hi vuejs'
},
// 侦听器
watch: {
// key 是就是你想监听数据的 字段名称
// value 是函数,当数据变化的时候执行该函数
msg: function(newMsg,oldMsg) {
// newMsg 改变后的值
// oldMsg 改变前的值
// 做你自己的业务逻辑(官方建议:异步|复杂操作)
}
}
})
- 基于侦听器实现搜索功能
<input v-model='keyword' type="text" class="form-control" style="width:200px;display: inline-block;" placeholder="请输入搜索关键字">
data: {
// 品牌列表
list: [],
// 品牌名称
bookname: '',
// 搜索关键字
keyword: ''
},
watch: {
keyword (kw) {
// 当输入关键字时,调用接口查询匹配的结果
// json-server规定模糊匹配规则是在属性名称后添加 _like
// axios.get('books?bookname_like=' + kw).then(ret => {
// if (ret.status === 200) {
// this.books = ret.data
// }
// })
// ------------------------------------
axios.get('books', {
// get传递参数另一种方式:通过params属性传递参数
params: {
bookname_like: kw
}
}).then(ret => {
if (ret.status === 200) {
// 数据变化,页面自动更新(数据的响应式)
this.books = ret.data
}
})
}
},
# 搜索功能添加函数防抖
目标:限制接口调用的频率
执行流程:连续输入两个字符之间的时间间隔如果小于1s,那么不会触发接口调用
函数防抖:超过连续触发条件(输入一个字符)的时间间隔(一秒),才会触发一次任务(调用一次接口)
watch: {
keyword (kw) {
// 当输入关键字时,调用接口查询匹配的结果
// json-server规定模糊匹配规则是在属性名称后添加 _like
// axios.get('books?bookname_like=' + kw).then(ret => {
// if (ret.status === 200) {
// this.books = ret.data
// }
// })
// ------------------------------------
// 1、keyword方法触发一次证明输入了一个字符
// 2、如果连续两次输入字符的时间间隔小于一秒,那么会销毁上一个任务,再产生一个新的任务,并一直重复这个过程
// 3、直到停止输入后,时间超过了1秒后,最后一次任务才会执行
// 函数防抖:超过连续触发条件(输入一个字符)的时间间隔(一秒),才会触发一次任务(调用一次接口)
clearTimeout(this.timer)
this.timer = setTimeout(() => {
axios.get('books', {
// get传递参数另一种方式:通过params属性传递参数
params: {
bookname_like: kw
}
}).then(ret => {
if (ret.status === 200) {
// 数据变化,页面自动更新(数据的响应式)
this.books = ret.data
}
})
}, 1000)
}
},
# 添加接口的加载提示功能
目标:掌握状态位的控制逻辑
data: {
isLoading: true,
}
<tr v-show='isLoading'>
<td colspan="4" style='text-align: center;'>正在加载...</td>
</tr>
// 调用接口获取图书列表数据
loadBookList () {
// 显示加载状态
this.loading = true
axios.get('books').then(ret => {
if (ret.data) {
this.books = ret.data
// 加载完成数据后,隐藏状态
this.loading = false
}
})
}