文章目录
vm.$watch
Vue 实例将会在实例化时调用$watch,遍历 watch 对象的每一个属性。
我们也可以利用 vm.$watch 来实现侦听,用法与 watch 选项部分一致,略有不同。以下为使用方法。
- 侦听某个数据的变化
// 1. 三个参数,一参为被侦听的数据;二参为数据改变时执行的回调函数;三参可选,为设置的选项对象
vm.$watch(
"msg",
function () {
// 干了点事儿
},
{
deep: Boolean,
immediate: Boolean,
}
);
// 2. 二个参数,一参为被侦听的数据;二参为选项对象,其中handler属性为必需,是数据改变时执行的回调函数,其他属性可选。
vm.$watch("msg", {
handler() {
// 干了点事儿
},
deep: Boolean,
immediate: Boolean,
});
- 侦听某个对象属性的变化
vm.$watch("obj.name" /**参数和上面一之*/);
- 当监听的数据的在初始不确定,由多个数据得到时,此时可以将第一个参数写成函数类型
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 计算属性
-
两者都可以观察和响应 Vue 实例上的数据的变动。
-
watch 擅长处理的场景是:一个数据影响多个数据。计算属性擅长处理的场景是:多个数据影响一个数据。
-
在侦听器中可以执行异步,但是在计算属性中不可以,例:
使用侦听器:
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 参数说明
参数 | 类型 | 描述 |
---|---|---|
url | String | 请求目标 url |
body | Object, FormData, string | 作为请求体发送的数据 |
headers | Object | 作为请求头部发送的头部对象 |
params | Object | 作为 URL 参数的参数对象 |
method | String | HTTP 方法 (例如 GET,POST,…) |
responseType | String | 设置返回数据的类型 |
timeout | Number | 在请求发送之前修改请求的回调函数 |
credentials | Boolean | 是否需要出示用于跨站点请求的凭据 |
emulateHTTP | Boolean | 是否需要通过设置 X-HTTP-Method-Override 头部并且以传统 POST 方式发送 PUT,PATCH 和 DELETE 请求。 |
emulateJSON | Boolean | 设置请求体的类型为 application/x-www-form-urlencoded |
before | function(request) | 在请求发送之前修改请求的回调函数 |
uploadProgress | function(event) | 用于处理上传进度的回调函数 |
downloadProgress | function(event) | 用于处理下载进度的回调函数 |
响应对象
通过如下属性和方法处理一个请求获取到的响应对象:
属性
属性 | 类型 | 描述 |
---|---|---|
url | String | 响应的 URL 源 |
body | Object, Blob, string | 响应体数据 |
headers | Header | 请求头部对象 |
ok | Boolean | 当 HTTP 响应码为 200 到 299 之间的数值时该值为 true |
status | Number | HTTP 响应码 |
statusText | String | HTTP 响应状态 |
方法
方法 | 描述 |
---|---|
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 错误。