Vue入门第四天

「爱情、让人受尽委屈。」 2022-09-08 10:25 312阅读 0赞

接口调用方式

  • 原生ajax
  • 基于jQuery的ajax
  • fetch
  • axios

异步

  • JavaScript的执行环境是「单线程」
  • 所谓单线程,是指JS引擎中负责解释和执行JavaScript代码的线程只有一个,也就是一次只能完成一项任务,这个任务执行完后才能执行下一个,它会「阻塞」其他任务。这个任务可称为主线程
  • 异步模式可以一起执行多个任务
  • JS中常见的异步调用

    • 定时任何
    • ajax
    • 事件函数

promise

  • 主要解决异步深层嵌套的问题
  • promise 提供了简洁的API 使得异步操作更加容易

基于Promise发送Ajax请求

  1. <script type="text/javascript"> /* 基于Promise发送Ajax请求 */ function queryData(url) { # 1.1 创建一个Promise实例 var p = new Promise(function(resolve, reject){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState != 4) return; if(xhr.readyState == 4 && xhr.status == 200) { # 1.2 处理正常的情况 resolve(xhr.responseText); }else{ # 1.3 处理异常情况 reject('服务器错误'); } }; xhr.open('get', url); xhr.send(null); }); return p; } # 注意: 这里需要开启一个服务 # then方法中,你也可以直接return数据而不是Promise对象,在后面的then中就可以接收到数据了 queryData('http://localhost:3000/data') .then(function(data){ console.log(data) # 1.4 想要继续链式编程下去 需要 return return queryData('http://localhost:3000/data1'); }) .then(function(data){ console.log(data); return queryData('http://localhost:3000/data2'); }) .then(function(data){ console.log(data) }); </script>

Promise 基本API

实例方法

.then()
  • 得到异步任务正确的结果
.catch()
  • 获取异常信息
.finally()
  • 成功与否都会执行(不是正式标准)

静态方法

.all()
  • Promise.all方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用Promise.resolve转换为一个promise)。它的状态由这三个promise实例决定
.race()
  • Promise.race方法同样接受一个数组作参数。当p1, p2, p3中有一个实例的状态发生改变(变为fulfilledrejected),p的状态就跟着改变。并把第一个改变状态的promise的返回值,传给p的回调函数

  1. <script type="text/javascript"> /* Promise常用API-对象方法 */ // console.dir(Promise) function queryData(url) { return new Promise(function(resolve, reject){ var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function(){ if(xhr.readyState != 4) return; if(xhr.readyState == 4 && xhr.status == 200) { // 处理正常的情况 resolve(xhr.responseText); }else{ // 处理异常情况 reject('服务器错误'); } }; xhr.open('get', url); xhr.send(null); }); } var p1 = queryData('http://localhost:3000/a1'); var p2 = queryData('http://localhost:3000/a2'); var p3 = queryData('http://localhost:3000/a3'); Promise.all([p1,p2,p3]).then(function(result){ // all 中的参数 [p1,p2,p3] 和 返回的结果一 一对应["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"] console.log(result) //["HELLO TOM", "HELLO JERRY", "HELLO SPIKE"] }) Promise.race([p1,p2,p3]).then(function(result){ // 由于p1执行较快,Promise的then()将获得结果'P1'。p2,p3仍在继续执行,但执行结果将被丢弃。 console.log(result) // "HELLO TOM" }) </script>

fetch

  • Fetch API是新的ajax解决方案 Fetch会返回Promise
  • fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象
  • fetch(url, options).then()

fetch API 中的 HTTP 请求

  • fetch(url, options).then()
  • HTTP协议,它给我们提供了很多的方法,如POST,GET,DELETE,UPDATE,PATCH和PUT

    • 默认的是 GET 请求
    • 需要在 options 对象中 指定对应的 method method:请求使用的方法
    • post 和 普通 请求的时候 需要在options 中 设置 请求头 headers 和 body

fetchAPI 中 响应格式

  • 用fetch来获取数据,如果响应正常返回,我们首先看到的是一个response对象,其中包括返回的一堆原始字节,这些字节需要在收到后,需要我们通过调用方法将其转换为相应格式的数据,比如JSONBLOB或者TEXT等等

    / Fetch响应结果的数据格式 /

    1. fetch('http://localhost:3000/json').then(function(data){
    2. // return data.json(); // 将获取到的数据使用 json 转换对象
    3. return data.text(); // // 将获取到的数据 转换成字符串
    4. }).then(function(data){
    5. // console.log(data.uname)
    6. // console.log(typeof data)
    7. var obj = JSON.parse(data);
    8. console.log(obj.uname,obj.age,obj.gender)
    9. })

axios

  • 基于promise用于浏览器和node.js的http客户端
  • 支持浏览器和node.js
  • 支持promise
  • 能拦截请求和响应
  • 自动转换JSON数据
  • 能转换请求和响应数据

axios基础用法

  • get和 delete请求传递参数

    • 通过传统的url 以 ? 的形式传递参数
    • restful 形式传递参数
    • 通过params 形式传递参数
  • post 和 put 请求传递参数

    • 通过选项传递参数
    • 通过 URLSearchParams 传递参数

    1. 发送get 请求

    1. axios.get('http://localhost:3000/adata').then(function(ret){
    2. # 拿到 ret 是一个对象 所有的对象都存在 ret 的data 属性里面
    3. // 注意data属性是固定的用法,用于获取后台的实际数据
    4. // console.log(ret.data)
    5. console.log(ret)
    6. })
    7. # 2. get 请求传递参数
    8. # 2.1 通过传统的url 以 ? 的形式传递参数
    9. axios.get('http://localhost:3000/axios?id=123').then(function(ret){
    10. console.log(ret.data)
    11. })
    12. # 2.2 restful 形式传递参数
    13. axios.get('http://localhost:3000/axios/123').then(function(ret){
    14. console.log(ret.data)
    15. })
    16. # 2.3 通过params 形式传递参数
    17. axios.get('http://localhost:3000/axios', {
    18. params: {
    19. id: 789
    20. }
    21. }).then(function(ret){
    22. console.log(ret.data)
    23. })
    24. #3 axios delete 请求传参 传参的形式和 get 请求一样
    25. axios.delete('http://localhost:3000/axios', {
    26. params: {
    27. id: 111
    28. }
    29. }).then(function(ret){
    30. console.log(ret.data)
    31. })
    32. # 4 axios 的 post 请求
    33. # 4.1 通过选项传递参数
    34. axios.post('http://localhost:3000/axios', {
    35. uname: 'lisi',
    36. pwd: 123
    37. }).then(function(ret){
    38. console.log(ret.data)
    39. })
    40. # 4.2 通过 URLSearchParams 传递参数
    41. var params = new URLSearchParams();
    42. params.append('uname', 'zhangsan');
    43. params.append('pwd', '111');
    44. axios.post('http://localhost:3000/axios', params).then(function(ret){
    45. console.log(ret.data)
    46. })
    47. #5 axios put 请求传参 和 post 请求一样
    48. axios.put('http://localhost:3000/axios/123', {
    49. uname: 'lisi',
    50. pwd: 123
    51. }).then(function(ret){
    52. console.log(ret.data)
    53. })

axios 全局配置

  1. # 配置公共的请求头
  2. axios.defaults.baseURL = 'https://api.example.com';
  3. # 配置 超时时间
  4. axios.defaults.timeout = 2500;
  5. # 配置公共的请求头
  6. axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
  7. # 配置公共的 post 的 Content-Type
  8. axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

axios 拦截器

  • 请求拦截器

    • 请求拦截器的作用是在请求发送前进行一些操作

      • 例如在每个请求体里加上token,统一做了处理如果以后要改也非常容易
  • 响应拦截器

    • 响应拦截器的作用是在接收到响应后进行一些操作

      • 例如在服务器返回登录状态失效,需要重新登录的时候,跳转到登录页

    1. 请求拦截器

    1. axios.interceptors.request.use(function(config) {
    2. console.log(config.url)
    3. # 1.1 任何请求都会经过这一步 在发送请求之前做些什么
    4. config.headers.mytoken = 'nihao';
    5. # 1.2 这里一定要return 否则配置不成功
    6. return config;
    7. }, function(err){
    8. #1.3 对请求错误做点什么
    9. console.log(err)
    10. })
    11. #2. 响应拦截器
    12. axios.interceptors.response.use(function(res) {
    13. #2.1 在接收响应做些什么
    14. var data = res.data;
    15. return data;
    16. }, function(err){
    17. #2.2 对响应错误做点什么
    18. console.log(err)
    19. })

async 和 await

  • async作为一个关键字放到函数前面

    • 任何一个async函数都会隐式返回一个promise
  • await关键字只能在使用async定义的函数中使用

    • ​ await后面可以直接跟一个 Promise实例对象
    • ​ await函数不能单独使用
  • async/await 让异步代码看起来、表现起来更像同步代码

    1. async 基础用法

    1. # 1.1 async作为一个关键字放到函数前面
    2. async function queryData() {
    3. # 1.2 await关键字只能在使用async定义的函数中使用 await后面可以直接跟一个 Promise实例对象
    4. var ret = await new Promise(function(resolve, reject){
    5. setTimeout(function(){
    6. resolve('nihao')
    7. },1000);
    8. })
    9. // console.log(ret.data)
    10. return ret;
    11. }
    12. # 1.3 任何一个async函数都会隐式返回一个promise 我们可以使用then 进行链式编程
    13. queryData().then(function(data){
    14. console.log(data)
    15. })
    16. #2. async 函数处理多个异步函数
    17. axios.defaults.baseURL = 'http://localhost:3000';
    18. async function queryData() {
    19. # 2.1 添加await之后 当前的await 返回结果之后才会执行后面的代码
    20. var info = await axios.get('async1');
    21. #2.2 让异步代码看起来、表现起来更像同步代码
    22. var ret = await axios.get('async2?info=' + info.data);
    23. return ret.data;
    24. }
    25. queryData().then(function(data){
    26. console.log(data)
    27. })

图书列表案例

1. 基于接口案例-获取图书列表

  • 导入axios 用来发送ajax
  • 把获取到的数据渲染到页面上

    1. <div class="grid">
    2. <table>
    3. <thead>
    4. <tr>
    5. <th>编号</th>
    6. <th>名称</th>
    7. <th>时间</th>
    8. <th>操作</th>
    9. </tr>
    10. </thead>
    11. <tbody>
    12. <!-- 5. 把books 中的数据渲染到页面上 -->
    13. <tr :key='item.id' v-for='item in books'>
    14. <td>{

    {item.id}}

    1. <td>{

    {item.name}}

    1. <td>{

    {item.date }}

    1. <td>
    2. <a href="">修改</a>
    3. <span>|</span>
    4. <a href="">删除</a>
    5. </td>
    6. </tr>
    7. </tbody>
    8. </table>
    9. </div>
    10. </div>
    11. <script type="text/javascript" src="js/vue.js"></script>
    12. 1. 导入axios
    13. <script type="text/javascript" src="js/axios.js"></script>
    14. <script type="text/javascript"> /* 图书管理-添加图书 */ # 2 配置公共的url地址 简化后面的调用方式 axios.defaults.baseURL = 'http://localhost:3000/'; axios.interceptors.response.use(function(res) { return res.data; }, function(error) { console.log(error) }); var vm = new Vue({ el: '#app', data: { flag: false, submitFlag: false, id: '', name: '', books: [] }, methods: { # 3 定义一个方法 用来发送 ajax # 3.1 使用 async 让异步的代码 以同步的形式书写 queryData: async function() { // 调用后台接口获取图书列表数据 // var ret = await axios.get('books'); // this.books = ret.data; # 3.2 发送ajax请求 把拿到的数据放在books 里面 this.books = await axios.get('books'); } }, mounted: function() { # 4 mounted 里面 DOM已经加载完毕 在这里调用函数 this.queryData(); } }); </script>

2 添加图书

  • 获取用户输入的数据 发送到后台
  • 渲染最新的数据到页面上

    methods: {

    1. handle: async function(){
    2. if(this.flag) {
    3. // 编辑图书
    4. // 就是根据当前的ID去更新数组中对应的数据
    5. this.books.some((item) => {
    6. if(item.id == this.id) {
    7. item.name = this.name;
    8. // 完成更新操作之后,需要终止循环
    9. return true;
    10. }
    11. });
    12. this.flag = false;
    13. }else{
    14. # 1.1 在前面封装好的 handle 方法中 发送ajax请求
    15. # 1.2 使用async 和 await 简化操作 需要在 function 前面添加 async
    16. var ret = await axios.post('books', {
    17. name: this.name
    18. })
    19. # 1.3 根据后台返回的状态码判断是否加载数据
    20. if(ret.status == 200) {
    21. # 1.4 调用 queryData 这个方法 渲染最新的数据
    22. this.queryData();
    23. }
    24. }
    25. // 清空表单
    26. this.id = '';
    27. this.name = '';
    28. },

    }

3 验证图书名称是否存在

  • 添加图书之前发送请求验证图示是否已经存在
  • 如果不存在 往后台里面添加图书名称

    • 图书存在与否只需要修改submitFlag的值即可

    watch: {

    1. name: async function(val) {
    2. // 验证图书名称是否已经存在
    3. // var flag = this.books.some(function(item){
    4. // return item.name == val;
    5. // });
    6. var ret = await axios.get('/books/book/' + this.name);
    7. if(ret.status == 1) {
    8. // 图书名称存在
    9. this.submitFlag = true;
    10. }else{
    11. // 图书名称不存在
    12. this.submitFlag = false;
    13. }
    14. }

    },

4. 编辑图书

  • 根据当前书的id 查询需要编辑的书籍
  • 需要根据状态位判断是添加还是编辑

    methods: {

    1. handle: async function(){
    2. if(this.flag) {
    3. #4.3 编辑图书 把用户输入的信息提交到后台
    4. var ret = await axios.put('books/' + this.id, {
    5. name: this.name
    6. });
    7. if(ret.status == 200){
    8. #4.4 完成添加后 重新加载列表数据
    9. this.queryData();
    10. }
    11. this.flag = false;
    12. }else{
    13. // 添加图书
    14. var ret = await axios.post('books', {
    15. name: this.name
    16. })
    17. if(ret.status == 200) {
    18. // 重新加载列表数据
    19. this.queryData();
    20. }
    21. }
    22. // 清空表单
    23. this.id = '';
    24. this.name = '';
    25. },
    26. toEdit: async function(id){
    27. #4.1 flag状态位用于区分编辑和添加操作
    28. this.flag = true;
    29. #4.2 根据id查询出对应的图书信息 页面中可以加载出来最新的信息
    30. # 调用接口发送ajax 请求
    31. var ret = await axios.get('books/' + id);
    32. this.id = ret.id;
    33. this.name = ret.name;
    34. },

5 删除图书

  • 把需要删除的id书籍 通过参数的形式传递到后台

    deleteBook: async function(id){

    1. // 删除图书
    2. var ret = await axios.delete('books/' + id);
    3. if(ret.status == 200) {
    4. // 重新加载列表数据
    5. this.queryData();
    6. }

    }

Vue其他文章
Vue入门第一天
Vue入门第二天
Vue入门第三天
Vue入门第四天
Vue入门第五天
Vue组件间的通信

发表评论

表情:
评论列表 (有 0 条评论,312人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Vue门第

    1.路由的概念 路由的本质就是一种对应关系,比如说我们在url地址中输入我们要访问的url地址之后,浏览器要去请求这个url地址对应的资源。 那么url地址和真实的资