【 异步查询工具 axios 】

异步查询数据,自然是通过ajax查询,大家首先想起的肯定是jQuery。但jQuery与MVVM的思想不吻合,而且ajax只是jQuery的一小部分。因此不可能为了发起ajax请求而去引用这么大的一个库。

官网:https://www.kancloud.cn/yunye/axios/234845

1、axios 入门

Vue 官方推荐的 ajax 请求框架叫做:axios,看下demo:

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

axios 的 Get 请求语法:

axios.get("/item/category/list?pid=0") // 请求路径和请求参数拼接
    .then(function(resp){
    	// 成功回调函数
	})
    .catch(function(){
    	// 失败回调函数
	})
// 参数较多时,可以通过params来传递参数
axios.get("/item/category/list", {
        params:{
            pid:0
        }
	})
    .then(function(resp){})// 成功时的回调
    .catch(function(error){})// 失败时的回调

axios 的 POST 请求语法:

比如新增一个用户

axios.post("/user",{
    	name:"Jack",
    	age:21
	})
    .then(function(resp){})
    .catch(function(error){})
  • 注意,POST 请求传参,不需要像 GET 请求那样定义一个对象,在对象的 params 参数中传参。post() 方法的第二个参数对象,就是将来要传递的参数

PUT 和 DELETE 请求与 POST 请求类似

2、axios 的全局配置

而在我们的项目中,已经引入了 axios,并且进行了简单的封装,在 src 下的 http.js 中:

在这里插入图片描述

http.js 中对 axios 进行了一些默认配置:

import Vue from 'vue'
import axios from 'axios'
import config from './config'

// config中定义的基础路径是:http://api.leyou.com/api
axios.defaults.baseURL = config.api; // 设置axios的基础请求路径
axios.defaults.timeout = 2000; // 设置axios的请求时间

// axios.interceptors.request.use(function (config) {
//   // console.log(config);
//   return config;
// })

axios.loadData = async function (url) {
  const resp = await axios.get(url);
  return resp.data;
}

Vue.prototype.$http = axios; // 将 axios 赋值给 Vue 原型的 $http 属性,这样所有 vue 实例都可使用该对象
  • http.js 中导入了 config 的配置,还记得吗?
    在这里插入图片描述

  • http.js 对 axios 进行了全局配置:baseURL=config.api,即http://api.leyou.com/api。因此以后所有用 axios 发起的请求,都会以这个地址作为前缀。

  • 通过Vue.property.$http = axios,将axios赋值给了 Vue原型中的$http。这样以后所有的 Vue 实例都可以访问到 $http,也就是访问到了 axios 了。

3、测试一下:

我们在组件MyBrand.vuegetDataFromServer方法,通过$http发起get请求,测试查询品牌的接口,看是否能获取到数据:
在这里插入图片描述

网络监视:
在这里插入图片描述

控制台结果:

在这里插入图片描述

可以看到,在请求成功的返回结果 response 中,有一个 data 属性,里面就是真正的响应数据。

响应结果中与我们设计的一致,包含3个内容:

  • total:总条数,目前是165
  • items:当前页数据
  • totalPage:总页数,我们没有返回

4、异步加载品牌数据

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

在这里插入图片描述

5、完成分页和过滤

分页

现在我们实现了页面加载时的第一次查询,你会发现你点击分页或搜索不会发起新的请求,怎么办?

虽然点击分页,不会发起请求,但是通过浏览器工具查看,会发现 pagination 对象的属性一直在变化:

在这里插入图片描述

我们可以利用 Vue 的监视功能:watch,当 pagination 发生改变时,会调用我们的回调函数,我们在回调函数中进行数据的查询即可!

具体实现:
在这里插入图片描述

在这里插入图片描述

成功实现分页功能:

在这里插入图片描述

过滤

分页实现了,过滤也很好实现了。过滤字段对应的是search属性,我们只要监视这个属性即可:

在这里插入图片描述

查看网络请求:

在这里插入图片描述

页面结果:

在这里插入图片描述

6、完整代码

<template>
  <v-card>
    <v-card-title>
      <v-btn color="primary" @click="addBrand">新增品牌</v-btn>
      <!--搜索框,与search属性关联-->
      <v-spacer/>
      <v-text-field label="输入关键字搜索" v-model.lazy="search" append-icon="search" hide-details/>
    </v-card-title>
    <v-divider/>
    <v-data-table
      :headers="headers"
      :items="brands"
      :search="search"
      :pagination.sync="pagination"
      :total-items="totalBrands"
      :loading="loading"
      class="elevation-1"
    >
      <template slot="items" slot-scope="props">
        <td>{{ props.item.id }}</td>
        <td class="text-xs-center">{{ props.item.name }}</td>
        <td class="text-xs-center"><img :src="props.item.image"></td>
        <td class="text-xs-center">{{ props.item.letter }}</td>
        <td class="justify-center layout">
          <v-btn color="info">编辑</v-btn>
          <v-btn color="warning">删除</v-btn>
        </td>
      </template>
    </v-data-table>
  </v-card>
</template>

<script>
  import MyBrandForm from './MyBrandForm'
  export default {
    name: "my-brand",
    data() {
      return {
        search: '', // 搜索过滤字段
        totalBrands: 0, // 总条数
        brands: [], // 当前页品牌数据
        loading: true, // 是否在加载中
        pagination: {}, // 分页信息
        headers: [
          {text: 'id', align: 'center', value: 'id'},
          {text: '名称', align: 'center', sortable: false, value: 'name'},
          {text: 'LOGO', align: 'center', sortable: false, value: 'image'},
          {text: '首字母', align: 'center', value: 'letter', sortable: true,},
          {text: '操作', align: 'center', value: 'id', sortable: false}
        ]
      }
    },
    mounted() { // 渲染后执行
      // 查询数据
      this.getDataFromServer();
    },
    watch: {
      pagination: { // 监视pagination属性的变化
        deep: true, // deep为true,会监视pagination的属性及属性中的对象属性变化
        handler() {
          // 变化后的回调函数,这里我们再次调用getDataFromServer即可
          this.getDataFromServer();
        }
      },
      search: { // 监视搜索字段
        handler() {
          this.getDataFromServer();
        }
      }
    },
    methods: {
      getDataFromServer() { // 从服务的加载数的方法。
        // 发起请求
        this.$http.get("/item/brand/page", {
          params: {
            key: this.search, // 搜索条件
            page: this.pagination.page,// 当前页
            rows: this.pagination.rowsPerPage,// 每页大小
            sortBy: this.pagination.sortBy,// 排序字段
            desc: this.pagination.descending// 是否降序
          }
        }).then(resp => { // 这里使用箭头函数
          this.brands = resp.data.items;
          this.totalBrands = resp.data.total;
          // 完成赋值后,把加载状态赋值为false
          this.loading = false;
        })
      }
    }
  }
</script>

<style scoped>

</style>

猜你喜欢

转载自blog.csdn.net/weixin_42112635/article/details/88377992
今日推荐