入门(四)之Promise、Vuex、axios"/>
Vue入门(四)之Promise、Vuex、axios
一、Promise
有异步操作时,使用Promise对异步操作进行封装
resolve => then
reject => catch
1、Promise的基本使用
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>// resolve ,reject 本身它们又是函数// 链式编程new Promise((resolve, reject) => {setTimeout(() => {resolve() }, 1000)}).then(() => {// 第一次拿到结果的代码console.log('Hello World')return new Promise((resolve, reject) => {//第二次网络请求的代码setTimeout(() => {resolve()},1000)})}).then(() => {// 第二次处理的代码console.log('Hello Vuejs')return new Promise((resolve, reject) => {//第三次网络请求的代码setTimeout(() => {resolve('Hello Wielun')},1000)})}).then((data) => {// 第三次处理的代码console.log(data)})//什么情况使用Promis?// 有异步操作时,使用Promise对异步操作进行封装new Promise((resolve, reject) => {setTimeout(() => {reject('error')}, 1000)}).catch((err) => {console.log(err)})</script>
</body>
</html>
2、另外处理形态
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>new Promise((resolve, reject) => {setTimeout(() => {// resolve('Hello Vue')reject('err')},1000)}).then(data => {console.log(data)}, err => {console.log(err)})</script>
</body>
</html>
3、链式调用简写
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>new Promise((resolve, reject) => {setTimeout(() => {resolve('Wielun')},1000)}).then(res => {console.log(res, '第一层')// 省略掉 new Promisereturn Promise.resolve(res + '111')// reject简写// return Promise.reject('error')// throw 'error'}).then(res => {console.log(res, '第二层')// 省略掉 Promise.resolvereturn res + '222'}).then(res => {console.log(res, '第三层')}).catch(err => {console.log(err)})</script>
</body>
</html>
4、all用法(伪代码)
两次ajax请求都结束在执行then
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>Promise.all([new Promise((resolve, reject) => {$ajax({url: "url1",success: function(data) {resolve(data)}})}),new Promise((resolve, reject) => {$ajax({url: "url2",success: function(data) {resolve(data)}})})]).then(results => {console.log(results[0]); //第一个ajax结果console.log(results[1]) //第二个ajax结果})</script>
</body>
</html>
二、Vuex
专为Vue.js应用程序开发的状态管理模式
1、组件共享(状态管理)
- 用户的登陆状态、用户名称、头像、地理位置信息等等
- 商品的收藏、购物车中的物品等等
2、单界面的状态管理
修改app.vue:
<template><div id="app"><h1>{{message}}</h1><h1>{{counter}}</h1><button @click="counter++">+</button><button @click="counter--">+</button></div>
</template><script>export default {name: 'App',data() {return {message: 'Hello World',counter: 0}}
}
</script><style></style>
3、多界面的状态管理
(1) 安装vuex
npm install vuex --save
(2)修改App.vue
<template><div id="app"><h1>{{message}}</h1><h1>{{$store.state.counter}}</h1><button @click="add">+</button><button @click="sub">+</button><hello-vuex></hello-vuex></div>
</template><script>
import HelloVuex from '@/components/HelloVuex'
export default {name: 'App',components: {HelloVuex},data() {return {message: 'Hello World',// counter: 0}},methods: {add() {this.$storemit('increment')},sub() {this.$storemit('decrement')},}
}
</script><style></style>
(3)修改main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'Vue.config.productionTip = falsenew Vue({render: h => h(App),store,
}).$mount('#app')
(4)修改src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'// 1、安装插件
Vue.use(Vuex)// 2、创建对象
const store = new Vuex.Store({state: {counter: 1000},mutations: {//方法increment(state) {state.counter--},decrement(state) {state.counter--}},getters: {},modules: {}
})// 3、导出
export default store
(5)修改src/components/HelloVuex.vue
<template><div>{{$store.state.counter}}</div>
</template><script>export default {}
</script><style scoped></style>
(6)查看结果
通过google商店安装devtools,可以查看执行过程
4、Getters基本使用
(1)修改App.vue
(2)修改store/index.js
(3)查看结果
5、Getters传参
(1)修改store/index.js
import Vue from 'vue'
import Vuex from 'vuex'// 1、安装插件
Vue.use(Vuex)// 2、创建对象
const store = new Vuex.Store({state: {counter: 1000,stutents: [{id: 1, name: 'wielun1', age:18},{id: 2, name: 'wielun2', age:21},{id: 3, name: 'wielun3', age:19},{id: 4, name: 'wielun4', age:22},]},mutations: {//方法increment(state) {state.counter--},decrement(state) {state.counter--}},getters: {powerCounter(state) {return state.counter * state.counter},more20stu(state) {return state.stutents.filter(s => s.age > 20)},more20stuLength(state, getters) {return getters.more20stu.length},moreAgeStu(state) {// return function(age) {// return state.stutents.filter(s => s.age > age)// }return age => {return state.stutents.filter(s => s.age > age)}}},modules: {}
})// 3、导出
export default store
(2)修改App.vue
<template><div id="app"><h1>{{message}}</h1><h1>{{$store.state.counter}}</h1><button @click="add">+</button><button @click="sub">+</button><h2>平方:{{$store.getters.powerCounter}}</h2><h2>大于20岁:{{$store.getters.more20stu}}</h2><h2>大于20岁个数:{{$store.getters.more20stuLength}}</h2><hello-vuex></hello-vuex></div>
</template><script>
import HelloVuex from '@/components/HelloVuex'
export default {name: 'App',components: {HelloVuex},data() {return {message: 'Hello World',// counter: 0}},methods: {add() {this.$storemit('increment')},sub() {this.$storemit('decrement')},}
}
</script><style></style>
(3)查看结果
6、Mutation传递参数
(1)修改App.vue
<template><div id="app"><h1>{{message}}</h1><h1>{{$store.state.counter}}</h1><button @click="add">+</button><button @click="sub">+</button><button @click="addCount(5)">+5</button><button @click="addStudent">添加学生</button><h2>平方:{{$store.getters.powerCounter}}</h2><h2>大于20岁:{{$store.getters.more20stu}}</h2><h2>大于20岁个数:{{$store.getters.more20stuLength}}</h2><h2>自定义岁数:{{$store.getters.moreAgeStu(18)}}</h2><hello-vuex></hello-vuex></div>
</template><script>
import HelloVuex from '@/components/HelloVuex'
export default {name: 'App',components: {HelloVuex},data() {return {message: 'Hello World',// counter: 0}},methods: {add() {this.$storemit('increment')},sub() {this.$storemit('decrement')},addCount(count) {// 参数被称为载荷(Payload)this.$storemit('incrementCount',count)},addStudent() {const stu = {id: 5, name: 'wielun5', age: 24};this.$storemit('addStudent',stu)}}
}
</script><style></style>
(2)修改store/index.js
import Vue from 'vue'
import Vuex from 'vuex'// 1、安装插件
Vue.use(Vuex)// 2、创建对象
const store = new Vuex.Store({state: {counter: 1000,stutents: [{id: 1, name: 'wielun1', age:18},{id: 2, name: 'wielun2', age:21},{id: 3, name: 'wielun3', age:19},{id: 4, name: 'wielun4', age:22},]},mutations: {//方法increment(state) {state.counter--},decrement(state) {state.counter--},incrementCount(state,count) {state.counter += count},addStudent(state,stu) {state.stutents.push(stu)}},getters: {powerCounter(state) {return state.counter * state.counter},more20stu(state) {return state.stutents.filter(s => s.age > 20)},more20stuLength(state, getters) {return getters.more20stu.length},moreAgeStu(state) {// return function(age) {// return state.stutents.filter(s => s.age > age)// }return age => {return state.stutents.filter(s => s.age > age)}}},modules: {}
})// 3、导出
export default store
(3)查看结果
6、Mutation提交风格
(1)修改App.vue
(2)修改store/index.js
7、Mutation响应式原理
- 提前在store中初始化好所需的属性
- 当给state中的对象添加新属性时:
- 方式一:使用Vue.set(obj, ‘newProp’, ‘123’)
- 方式二:用新对象给就对象重新赋值
state.info['address'] = '洛杉矶' ###非响应式
Vue.set(state.info, 'address', '洛杉矶') ###这样就是响应式
Vue.delete(state.info, 'age')
8、Mutation类型常量
这样不容易写错名字,方便管理
(1)创建store/mutations-types.js
export const INCREMENT = 'increment'
(2)修改App.vue
(3)修改store/index.js
9、Actions使用
(1)修改store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import {INCREMENT} from '@/store/mutations-types'// 1、安装插件
Vue.use(Vuex)// 2、创建对象
const store = new Vuex.Store({state: {counter: 1000,stutents: [{id: 1, name: 'wielun1', age:18},{id: 2, name: 'wielun2', age:21},{id: 3, name: 'wielun3', age:19},{id: 4, name: 'wielun4', age:22},],info: {name: 'wielun1111', age:18}},mutations: {//方法[INCREMENT](state) {state.counter--},decrement(state) {state.counter--},// incrementCount(state,count) {// state.counter += count// },incrementCount(state,payload) {state.counter += payload.count},addStudent(state,stu) {state.stutents.push(stu)},updateInfo(state) {state.info.name = 'wielun'}},actions: {// context: 上下文// aUpdateInfo(context, payload) {// setTimeout(() => {// contextmit('updateInfo');// console.log(payload)// }, 1000) // })// }aUpdateInfo(context, payload) {return new Promise((resolve, reject) => {setTimeout(() => {contextmit('updateInfo');console.log(payload);resolve('hello Vue')},1000)})}},getters: {powerCounter(state) {return state.counter * state.counter},more20stu(state) {return state.stutents.filter(s => s.age > 20)},more20stuLength(state, getters) {return getters.more20stu.length},moreAgeStu(state) {// return function(age) {// return state.stutents.filter(s => s.age > age)// }return age => {return state.stutents.filter(s => s.age > age)}}},modules: {}
})// 3、导出
export default store
(2)修改App.vue
<template><div id="app"><h1>{{message}}</h1><h1>{{$store.state.counter}}</h1><h1>{{$store.state.info}}</h1><button @click="add">+</button><button @click="sub">+</button><button @click="addCount(5)">+5</button><button @click="addStudent">添加学生</button><button @click="updateInfo">更新</button><h2>平方:{{$store.getters.powerCounter}}</h2><h2>大于20岁:{{$store.getters.more20stu}}</h2><h2>大于20岁个数:{{$store.getters.more20stuLength}}</h2><h2>自定义岁数:{{$store.getters.moreAgeStu(18)}}</h2><hello-vuex></hello-vuex></div>
</template><script>
import HelloVuex from '@/components/HelloVuex'
import {INCREMENT} from '@/store/mutations-types'
export default {name: 'App',components: {HelloVuex},data() {return {message: 'Hello World',// counter: 0}},methods: {add() {this.$storemit(INCREMENT)},sub() {this.$storemit('decrement')},addCount(count) {// 参数被称为载荷(Payload)// 1、普通的提交风格// this.$storemit('incrementCount',count)// 2、特殊的提交风格this.$storemit({type: 'incrementCount',count})},addStudent() {const stu = {id: 5, name: 'wielun5', age: 24};this.$storemit('addStudent',stu)},// updateInfo() {// this.$store.dispatch('aUpdateInfo', '我是payload')// }updateInfo() {this.$store.dispatch('aUpdateInfo', '我是payload').then(res => {console.log('里面完成了提交');console.log(res)})}}
}
</script><style></style>
(3)查看结果
10、modules使用
(1)修改store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import {INCREMENT} from '@/store/mutations-types'// 1、安装插件
Vue.use(Vuex)// 2、创建对象
const moduleA = {state: {name: 'wielun'},mutations: {updateName(state, payload) {state.name = payload}},getters: {fullname(state) {return state.name + 'yayaya'},fullname2(state, getters) {return getters.fullname + '1111' },fullname3(state, getters, rootState) {return getters.fullname2 + rootState.counter}},actions: {aUPdateName(context) {setTimeout(() => {contextmit('updateName', 'dreamya')})}},
}
const store = new Vuex.Store({state: {counter: 1000,stutents: [{id: 1, name: 'wielun1', age:18},{id: 2, name: 'wielun2', age:21},{id: 3, name: 'wielun3', age:19},{id: 4, name: 'wielun4', age:22},],info: {name: 'wielun1111', age:18}},mutations: {//方法[INCREMENT](state) {state.counter--},decrement(state) {state.counter--},// incrementCount(state,count) {// state.counter += count// },incrementCount(state,payload) {state.counter += payload.count},addStudent(state,stu) {state.stutents.push(stu)},updateInfo(state) {state.info.name = 'wielun'}},actions: {// context: 上下文// aUpdateInfo(context, payload) {// setTimeout(() => {// contextmit('updateInfo');// console.log(payload)// }, 1000) // })// }aUpdateInfo(context, payload) {return new Promise((resolve, reject) => {setTimeout(() => {contextmit('updateInfo');console.log(payload);resolve('hello Vue')},1000)})}},getters: {powerCounter(state) {return state.counter * state.counter},more20stu(state) {return state.stutents.filter(s => s.age > 20)},more20stuLength(state, getters) {return getters.more20stu.length},moreAgeStu(state) {// return function(age) {// return state.stutents.filter(s => s.age > age)// }return age => {return state.stutents.filter(s => s.age > age)}}},modules: {a: moduleA}
})// 3、导出
export default store
(2)修改App.vue
<template><div id="app"><h1>-----------modules-----------</h1><h1>{{$store.state.a.name}}</h1><button @click="updateName">修改名字</button><h1>{{$store.getters.fullname}}</h1><h1>{{$store.getters.fullname2}}</h1><h1>{{$store.getters.fullname3}}</h1><button @click="asyncupdateName">异步修改名字</button><h1>-----------------------------</h1><h1>{{message}}</h1><h1>{{$store.state.counter}}</h1><h1>{{$store.state.info}}</h1><button @click="add">+</button><button @click="sub">+</button><button @click="addCount(5)">+5</button><button @click="addStudent">添加学生</button><button @click="updateInfo">更新</button><h2>平方:{{$store.getters.powerCounter}}</h2><h2>大于20岁:{{$store.getters.more20stu}}</h2><h2>大于20岁个数:{{$store.getters.more20stuLength}}</h2><h2>自定义岁数:{{$store.getters.moreAgeStu(18)}}</h2><hello-vuex></hello-vuex></div>
</template><script>
import HelloVuex from '@/components/HelloVuex'
import {INCREMENT} from '@/store/mutations-types'
export default {name: 'App',components: {HelloVuex},data() {return {message: 'Hello World',// counter: 0}},methods: {add() {this.$storemit(INCREMENT)},sub() {this.$storemit('decrement')},addCount(count) {// 参数被称为载荷(Payload)// 1、普通的提交风格// this.$storemit('incrementCount',count)// 2、特殊的提交风格this.$storemit({type: 'incrementCount',count})},addStudent() {const stu = {id: 5, name: 'wielun5', age: 24};this.$storemit('addStudent',stu)},// updateInfo() {// this.$store.dispatch('aUpdateInfo', '我是payload')// }updateInfo() {this.$store.dispatch('aUpdateInfo', '我是payload').then(res => {console.log('里面完成了提交');console.log(res)})},updateName() {this.$storemit('updateName','wwwielun')},asyncupdateName() {this.$store.dispatch('aUPdateName')}}
}
</script><style></style>
(3)查看结果
(4)项目结构
三、axios
1、安装
cnpm install axios --save
请求方式:
- axios(config)
- axios.request(config)
- axios.get(url[,config])
- axios.delete(url[,config])
- axios.head(url[,config])
- axios.post(url[,data[,config]])
- axios.put(url[,data[,config]])
- axios.patch(url[,data[,config]])
2、基本使用
(1)修改main.js
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios'Vue.config.productionTip = falsenew Vue({render: h => h(App),
}).$mount('#app')axios({url: 'http://123.207.32.32:8000/home/multidata'
}).then(res => {console.log(res)
})axios({url: 'http://123.207.32.32:8000/home/data',// 专门针对get请求的参数拼接params: {type: 'pop',page: 1}
}).then(res => {console.log(res)
})
(2)查看结果
3、并发请求
(1)修改main.js
// axios.all([axios({
// url: 'http://123.207.32.32:8000/home/multidata'
// }), axios({
// url: 'http://123.207.32.32:8000/home/data',
// params: {
// type: 'sell',
// page: 4
// }
// })]).then(
// result => {
// console.log(result);
// console.log(result[0]);
// console.log(result[1]);
// }
// )
axios.all([axios({url: 'http://123.207.32.32:8000/home/multidata'
}), axios({url: 'http://123.207.32.32:8000/home/data',params: {type: 'sell',page: 4}
})]).then(axios.spread((res1, res2) => {console.log(res1);console.log(res2);})
)
(2)查看结果
4、全局配置
修改main.js:
axios.defaults.baseURL = 'http://123.207.32.32:8000'
axios.defaults.timeout = 5000
axios.all([axios({url: '/home/multidata'
}), axios({url: '/home/data',params: {type: 'sell',page: 4}
})]).then(axios.spread((res1, res2) => {console.log(res1);console.log(res2);})
)
5、创建对应的axios实例
修改main.js:
const instance1 = axios.create({baseURL: 'http://123.207.32.32:8000',timeout: 5000
})instance1({url: '/home/multidata'
}).then(res => {console.log(res)
})instance1({url: '/home/data',params: {type: 'sell',page: 1}
}).then(res => {console.log(res)
})
6、模块封装(方式一)
(1)修改src/network/request.js
import axios from 'axios'export function request(config, success, failure) {// 1、创建axios实例const instance = axios.create({baseURL: 'http://123.207.32.32:8000',timeout: 5000})instance(config).then(res => {success(res)}).catch(err => {failure(err)})
}
(2)修改main.js
import {request} from "./network/request"request({url: '/home/data',
}, res => {console.log(res)
}, )
7、模块封装(方式二)
(1)修改src/network/request.js
// export function request(config) {
// return new Promise((reslove, reject) => {
// // 1、创建axios实例
// const instance = axios.create({
// baseURL: 'http://123.207.32.32:8000',
// timeout: 5000
// })// instance(config).then(res => {
// reslove(res)
// }).catch(err => {
// reject(err)
// })
// })
// }export function request(config) {return new Promise((reslove, reject) => {// 1、创建axios实例const instance = axios.create({baseURL: 'http://123.207.32.32:8000',timeout: 5000})// 本身就是一个Promisereturn instance(config)})
}
(2)修改main.js
import {request} from "./network/request"request({url: '/home/data',
}).then(res => {console.log(res)
}).catch(err => {console.log(err)
})
8、拦截器
(1)修改src/network/request.js
export function request(config) {return new Promise((reslove, reject) => {// 1、创建axios实例const instance = axios.create({baseURL: 'http://123.207.32.32:8000',timeout: 5000})// 2、axios拦截器// 2.1、请求拦截// instance.interceptors.request.use(config => {// console.log(config);// //1、比如config中的一些信息不符合服务器的要求// //2、比如每次发送网络请求时,都希望在界面中显示一个图标// //3、某些网络请求(比如登陆token),必须携带一些特殊信息// return config// }, err => {// console.log(err)// });//2.2响应拦截instance.interceptors.response.use(res => {console.log(res)return res.data}, err => {console.log(res)});// 3、发送真正的网络请求,本身就是一个Promisereturn instance(config)})
}
(2)修改main.js
import {request} from "./network/request"request({url: '/home/data',
}).then(res => {console.log(res)
}).catch(err => {console.log(err)
})
更多推荐
Vue入门(四)之Promise、Vuex、axios
发布评论