一、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 Promise
return Promise.resolve(res + '111')
// reject简写
// return Promise.reject('error')
// throw 'error'
}).then(res => {
console.log(res, '第二层')
// 省略掉 Promise.resolve
return 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.$store.commit('increment')
},
sub() {
this.$store.commit('decrement')
},
}
}
</script>
<style>
</style>
(3)修改main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new 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.$store.commit('increment')
},
sub() {
this.$store.commit('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.$store.commit('increment')
},
sub() {
this.$store.commit('decrement')
},
addCount(count) {
// 参数被称为载荷(Payload)
this.$store.commit('incrementCount',count)
},
addStudent() {
const stu = {id: 5, name: 'wielun5', age: 24};
this.$store.commit('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(() => {
// context.commit('updateInfo');
// console.log(payload)
// }, 1000)
// })
// }
aUpdateInfo(context, payload) {
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit('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.$store.commit(INCREMENT)
},
sub() {
this.$store.commit('decrement')
},
addCount(count) {
// 参数被称为载荷(Payload)
// 1、普通的提交风格
// this.$store.commit('incrementCount',count)
// 2、特殊的提交风格
this.$store.commit({
type: 'incrementCount',
count
})
},
addStudent() {
const stu = {id: 5, name: 'wielun5', age: 24};
this.$store.commit('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(() => {
context.commit('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(() => {
// context.commit('updateInfo');
// console.log(payload)
// }, 1000)
// })
// }
aUpdateInfo(context, payload) {
return new Promise((resolve, reject) => {
setTimeout(() => {
context.commit('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.$store.commit(INCREMENT)
},
sub() {
this.$store.commit('decrement')
},
addCount(count) {
// 参数被称为载荷(Payload)
// 1、普通的提交风格
// this.$store.commit('incrementCount',count)
// 2、特殊的提交风格
this.$store.commit({
type: 'incrementCount',
count
})
},
addStudent() {
const stu = {id: 5, name: 'wielun5', age: 24};
this.$store.commit('addStudent',stu)
},
// updateInfo() {
// this.$store.dispatch('aUpdateInfo', '我是payload')
// }
updateInfo() {
this.$store.dispatch('aUpdateInfo', '我是payload')
.then(res => {
console.log('里面完成了提交');
console.log(res)
})
},
updateName() {
this.$store.commit('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 = false
new 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
})
// 本身就是一个Promise
return 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、发送真正的网络请求,本身就是一个Promise
return instance(config)
})
}
(2)修改main.js
import {request} from "./network/request"
request({
url: '/home/data',
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})