Vue学习笔记 ③

vm.$watch

Vue 实例将会在实例化时调用$watch,遍历 watch 对象的每一个属性。
我们也可以利用 vm.$watch 来实现侦听,用法与 watch 选项部分一致,略有不同。以下为使用方法。

  1. 侦听某个数据的变化
// 1. 三个参数,一参为被侦听的数据;二参为数据改变时执行的回调函数;三参可选,为设置的选项对象
vm.$watch(
  "msg",
  function () {
    // 干了点事儿
  },
  {
    deep: Boolean,
    immediate: Boolean,
  }
);

// 2. 二个参数,一参为被侦听的数据;二参为选项对象,其中handler属性为必需,是数据改变时执行的回调函数,其他属性可选。
vm.$watch("msg", {
  handler() {
    // 干了点事儿
  },
  deep: Boolean,
  immediate: Boolean,
});
  1. 侦听某个对象属性的变化
vm.$watch("obj.name" /**参数和上面一之*/);
  1. 当监听的数据的在初始不确定,由多个数据得到时,此时可以将第一个参数写成函数类型
vm.$watch(
  function () {
    // 表达式`this.a + this.b`每次得出一个不同的结果时该函数都会被调用
    // 这就像监听一个未被定义的计算属性
    return this.a + this.b;
  } /**参数和上面一致*/
);

侦听器函数执行后,会返回一个取消侦听函数,用来停止触发回调:

const unwatch = vm.$watch("msg", function () {});
unwatch(); // 执行后会取消侦听msg数据

使用 unwatch 时,需要注意的是,在带有 immediate 选项时,不能在第一次回调时取消侦听数据。

const unwatch = vm.$watch('msg', function () {
    // 干了点儿事
    unwatch();  // 此时会报错
  },{
    immediate: true
  }
})

如果仍然希望在回调内部用一个取消侦听的函数,那么可以先检查该函数的可用性:

var unwatch = vm.$watch('msg', function () {
    // 干了点儿事
    if(unwatch) {
      unwatch();
    }
  },{
    immediate: true
  }
})

侦听器 vs 计算属性

  1. 两者都可以观察和响应 Vue 实例上的数据的变动。

  2. watch 擅长处理的场景是:一个数据影响多个数据。计算属性擅长处理的场景是:多个数据影响一个数据。

  3. 在侦听器中可以执行异步,但是在计算属性中不可以,例:

使用侦听器:

var vm = new Vue({
  el: "#app",
  data: {
    question: "",
  },
  watch: {
    question() {
      setTimeout(() => {
        alert(this.question);
      }, 1000);
    },
  },
});

vue-resource

在 Vue 中实现异步加载需要使用到 vue-resource 库,利用该库发送 ajax。

引入 vue-resource

<script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>

要注意的是,vue-resource 依赖于 Vue,所以要先引入 Vue,再引入 vue-resource。

引入 vue-resource 之后,在 Vue 的全局上会挂载一个$http 方法,在 vm.$http 方法上有一系列方法,每个 HTTP 请求类型都有一个对应的方法。

vue-resource 使用了 promise,所以$http 中的方法的返回值是一个 promise。

请求方法

POST 请求

用于提交数据

常用 data 格式:

  • 表单提交:multipart/form-data,比较老的网站会使用表单提交去获取数据,现在基本都不用表单提交,而是使用 ajax,但是现在表单提交仍然存在,有时候需要做图片上传、文件上传。
  • 文件上传:application/json,现在大多数情况下都是用这个格式

使用方法:vm.$http.post(url, [body], [options])

  • url: 必需,请求目标 url
  • body: 非必需,作为请求体发送的数据
  • options:非必需,作为请求体发送的数据
this.$http
  .post("https://developer.duyiedu.com/vue/setUserInfo", {
    name: this.name,
    mail: this.mail,
  })
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    console.log(error);
  });

GET 请求

获取数据

使用方法:vm.$http.get(url, [options])

this.$http
  .get("https://developer.duyiedu.com/vue/getUserInfo")
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    console.log(error);
  });

在 get 请求时传参:

this.$http.get('https://developer.duyiedu.com/vue/getUserInfo'{
  params: {
    id: 'xxx'
  }
})
  .then(res => {
    console.log(res);
  })
  .catch(error => {
    console.log(error);
  })

PUT 请求

更新数据,将所有的数据全都推送到后端
使用方法:vm.$http.put(url, [body], [config])

PATCH 请求

更新数据,只将修改的数据全都推送到后端
使用方法:vm.$http.patch(url, [body], [config])

DELETE 请求

删除数据
使用方法:vm.$http.delete(url, [config])

HEAD 请求

请求头部信息
使用方法:vm.$http.head(url, [config])

JSONP 请求

除了 jsonp 以外,以上 6 种的 API 名称是标准的 HTTP 方法。


使用方法:vm.$http.jsonp(url, [options]);

this.$http.jsonp("https://developer.duyiedu.com/vue/jsonp").then((res) => {
  this.msg = res.bodyText;
});

this.$http
  .jsonp("https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su", {
    params: {
      wd: "nn",
    },
    jsonp: "cd", //jsonp默认是callback,百度缩写成了cb,所以需要指定下
  })
  .then((res) => {
    console.log(res);
  });

options 参数说明

参数类型描述
urlString请求目标 url
bodyObject, FormData, string作为请求体发送的数据
headersObject作为请求头部发送的头部对象
paramsObject作为 URL 参数的参数对象
methodStringHTTP 方法 (例如 GET,POST,…)
responseTypeString设置返回数据的类型
timeoutNumber在请求发送之前修改请求的回调函数
credentialsBoolean是否需要出示用于跨站点请求的凭据
emulateHTTPBoolean是否需要通过设置 X-HTTP-Method-Override 头部并且以传统 POST 方式发送 PUT,PATCH 和 DELETE 请求。
emulateJSONBoolean设置请求体的类型为 application/x-www-form-urlencoded
beforefunction(request)在请求发送之前修改请求的回调函数
uploadProgressfunction(event)用于处理上传进度的回调函数
downloadProgressfunction(event)用于处理下载进度的回调函数

响应对象

通过如下属性和方法处理一个请求获取到的响应对象:

属性

属性类型描述
urlString响应的 URL 源
bodyObject, Blob, string响应体数据
headersHeader请求头部对象
okBoolean当 HTTP 响应码为 200 到 299 之间的数值时该值为 true
statusNumberHTTP 响应码
statusTextStringHTTP 响应状态

方法

方法描述
text()以字符串方式返回响应体
json()以格式化后的 json 对象方式返回响应体
blob()以二进制 Blob 对象方式返回响应体

以 json()为例:

this.$http
  .get("https://developer.duyiedu.com/vue/getUserInfo")
  .then((res) => {
    return res.json();
  })
  .then((res) => {
    console.log(res);
  });

最后的话

很不幸,Vue 官方已不再维护这个库了,so…哈哈哈,我们再学点其他的 ୧[ * ಡ ▽ ಡ * ]୨

Axios

Axios 是一个基于 promise 的 HTTP 库

浏览器支持情况:Chrome、Firefox、Safari、Opera、Edge、IE8+

引入

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

API

  • axios(config)
  • axios(url, [config])

config 配置对象

最常用的配置:

axios({
  method: "get", // post、get、put....
  baseURL: "", // 请求的域名,基本地址
  url: "", // 请求的路径
  params: {}, // 会将请求参数拼接在url上
  data: {}, // 会将请求参数放在请求体中
  headers: {}, // 设置请求头,例如设置token等
  timeout: 1000, // 设置请求超时时长,单位:ms
});

方法别名

为方便起见,为所有支持的请求方法提供了别名。

  • axios.request(config)
  • axios.get(url, [config])
  • axios.post(url, [data], [config]])
  • axios.delete(url, [config])
  • axios.head(url, [config])
  • axios.put(url, [data], [config])
  • axios.patch(url, [data], [config]])
  • axios.options(url, [config])

配置默认值

可以指定将被用在各个请求的配置默认值

全局配置

axios.defaults.baseURL = "https://developer.duyiedu.com/vue";
axios.defaults.timeout = 1000;

在实际项目中,很少用全局配置。

实例配置

可以使用自定义配置新建一个 axios 实例

const instance = axios.create({
  baseURL: "https://developer.duyiedu.com/vue",
  timeout: 1000,
});

instance.get("/getUserInfo").then((res) => {
  // ...
});

请求配置

const instance = axios.create();
instance.get("/getUserInfo", {
  timeout: 5000,
});

配置的优先顺序

全局 < 实例 < 请求

并发

同时进行多个请求,并统一处理返回值

  • axios.all(iterable)
  • axios.spread(callback)
axios.all([axios.get("/a"), axios.get("/b")]).then(
  axios.spread((aRes, bRes) => {
    console.log(aRes, bRes);
  })
);

拦截器

interceptors,在发起请求之前做一些处理,或者在响应回来之后做一些处理。

请求拦截器

axios.interceptors.request.use((config) => {
  // 在发送请求之前做些什么
  return config;
});

响应拦截器

axios.interceptors.response.use((response) => {
  // 对响应数据做点什么
  return response;
});

移除拦截器

const myInterceptor = axios.interceptors.request.use((config) => {});
axios.interceptors.request.eject(myInterceptor);

为 axios 实例添加拦截器

const instance = axios.create();
instance.interceptors.request.use((config) => {});

取消请求

用于取消正在进行的 http 请求

const cancelToken = axios.CancelToken;
const source = CancelToken.source();

axios
  .get("/getUserInfo", {
    cancelToken: source.token,
  })
  .then((res) => {
    console.log(res);
  })
  .catch((error) => {
    if (axios.isCancel(error)) {
      // 取消请求
      console.log(error.message);
    } else {
      // 处理错误
    }
  });

// 取消请求 参数 可选
source.cancel("取消请求");

错误处理

在请求错误时进行的处理
request / response 是 error 的上下文,标志着请求发送 / 得到响应
在错误中,如果响应有值,则说明是响应时出现了错误。
如果响应没值,则说明是请求时出现了错误。
在错误中,如果请求无值,则说明是请求未发送出去,如取消请求。

axios.get("/user/12345").catch(function (error) {
  // 错误可能是请求错误,也可能是响应错误
  if (error.response) {
    // 响应错误
  } else if (error.request) {
    // 请求错误
  } else {
    console.log("Error", error.message);
  }
  console.log(error.config);
});

在实际开发过程中,一般在拦截器中统一添加错误处理
请求拦截器中的错误,会当请求未成功发出时执行,但是要注意的是:取消请求后,请求拦截器的错误函数也不会执行,因为取消请求不会抛出异常,axios 对其进行了单独的处理。
在更多的情况下,我们会在响应拦截器中处理错误。

const instance = axios.create({});
instance.interceptors.request(
  (config) => {},
  (error) => {
    return Promise.reject(error);
  }
);

instance.interceptors.response(
  (response) => {},
  (error) => {
    return Promise.reject(error);
  }
);

axios 预检

当 axios 的请求为非简单请求时,浏览器会进行预检,及发送 OPTIONS 请求。请求到服务器,询问是否允许跨域。如果响应中允许预检中请求的跨域行为,则浏览器会进行真正的请求。否则会报 405 错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值