Promise
Promise是异步编程的一种解决方案。
最常见的异步场景就是网络请求了。
语法:
new Promise((resolve,reject)=>(
)).then(()=>{
}).catch(()=>{
})
异步操作之后会有三种状态:
- pending:等待状态,比如正在进行网络请求,或者定时器没有到时间
- fulfill:满足状态,当主动回调了resolve时,就处于该状态,并且会回调.then( )
- reject:拒绝状态,当主动回调了reject时,就处于该状态,并且会回调.catch( )
Promise的all方法
当程序中同时发送多个网络请求,只能当多个网络请求的结果都接收成功时才正在处理好结果,该怎么办?
Promise中有个all方法,可以同时处理多个异步操作。 Promise.all([]) 中间是个数组
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result1')
}, 1000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result2')
}, 3000)
}),
]).then(result => {
console.log(result);
})

Vuex
vuex是一个专门为Vue.js应用程序开发的状态管理模式。
状态管理是什么? 简单的来看就是多个组件之间共享变量全部存储在一个对象里面,然后将这个对象放在顶层的Vue实例中,让其他组件可以使用,那么多个组件就共享这个对象中的所有变量属性了。
并且该状态管理是响应式的。
但是什么状态需要在多个组件间共享呢?
- 比如用户的登录状态、用户名称、头像、地理位置信息等等
- 比如商品的收藏、购物车中的物品等等
state属性
在多页面中使用vuex,使用脚手架创建带有vuex插件的文件夹 在主文件夹下有个store文件夹,有个main.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter:1000
},
mutations: {
},
actions: {
},
modules: {
}
})
在App.vue文件中使用conuter
<template>
<div id="app">
<h2>{{$store.state.counter}}</h2>
</div>
</template>

mutations属性
此时想要修改App.vue文件中的conuter值,应该如何修改?
方法一:直接通过设置点击事件,修改$store.state.counter的值
<template>
<div id="app">
<h2>{{$store.state.counter}}</h2>
<button @click="$store.state.counter++}">+</button>
<button @click="$store.state.counter--}">-</button>
</div>
</template>
这种方法可以进行修改值,但是该方法是官方不推荐的
- 如果有多个页面同时用到该状态,如果其中一个页面对其进行修改,并且出错了,此时就无法查明到究竟是哪个页面进行了修改
- 数据的修改无法做到响应式,如果对数据进行修改,页面的数据修改,并不会影响到真实存在于后台的数据,无法同步。
方法二:mutations属性
在index.js文件夹中,将mutation属性中加入两个属性
new Vuex.Store({
state: {
counter:1000
},
mutations: {
add(state){
state.counter++
},
sub(state){
state.counter--
}
}
在App.vue中设置两个点击事件方法
//App.vue
<template>
<div id="app">
<h2>{{$store.state.counter}}</h2>
<button @click="addcounter">+</button>
<button @click="subounter">-</button>
</div>
</template>
<script>
export default {
name: "App",
methods:{
addcounter(){
this.$store.commit('add')
},
subounter(){
this.$store.commit('sub')
}
}
};
</script>
这就是官方推荐的方法。
同时在浏览器安装一个devtools插件,可以对整个点击过程进行调试。

这就是使用vuex最简单的方式了
现在,对上述的步骤进行小节
- 提取出一个公共的store对象,用于保存在多个组件中共享的状态
- 将store对象放置在new Vue对象中,这样可以保证在所有的组件中都可以使用到
- 在其他组件中使用store对象中保存的状态即可
(通过this.$store.state属性的方法来访问状态,通过this. $store.commit(‘mutation中的方法’)属性的方法来修改状态)
Getters基本使用
getters可以用来处理一些state中的数据
现在有这样的需求,state中有对象,取出Fmvp大于0的对象并展示出来
new Vuex.Store({
state: {
people:[
{id:1,name:'张岳',age:36,fmvp:4},
{id:2,name:"张三",age:30,fmvp:0},
{id:3,name:"李四",age:38,fmvp:2},
{id:4,name:"王八",age:20,fmvp:0},
],
}
此时就在getters属性中加入筛选函数:
getters:{
hasFmvps(state){
return state.people.filter(p => p.fmvp>0)
},
hasFmvpsLength(state,getters){
return getters.hasFmvps.length
}
其中filter(( )=>{ }) ,会遍历数组,然后将符合条件的数组放入到新的数组中
在App.vue中:
<template>
<div id="app">
<h2>拥有Fmvp的人</h2>
<h3>{{$store.getters.hasFmvps}}</h3>
<h3>{{$store.getters.hasFmvpsLength}}</h3>
</div>
</template>

Mutation属性
Vuex的store状态的唯一更新方式:提交Mutation
Mutation主要包括两部分:
- 字符串的时间类型(type)
- 一个回调函数(handler),该回调函数的第一个参数就是state
在通过mutation更新数据的时候,有可能会希望携带一些额外的参数
- 这种参数被称为是mutation的载荷(payload)
在上述的conunter案例中,加入一个+5,+10的按钮
//App.vue
<template>
<div id="app">
<h2>{{$store.state.counter}}</h2>
<button @click="addcounter">+</button>
<button @click="subounter">-</button>
<button @click="addcount(5)">+5</button>
<button @click="addcount(10)">+10</button>
</template>
<script>
export default {
name: "App",
methods:{
addcounter(){
this.$store.commit('add')
},
subounter(){
this.$store.commit('sub')
},
addcount(count){
this.$store.commit('addcount',count)
},
}
};
</script>
mutations: {
add(state){
state.counter++
},
sub(state){
state.counter--
},
addcount(state,count){
state.counter += count
}
},
Action属性
通常情况下,Vuex要求Mutation中的方法必须是同步方法,主要的原因是当使用devtool时,devtools可以捕捉mutation的快照,但是如果是异步操作,那么devtools将不能很好的追踪这个操作是什么时候被完成的
例如:
export default new Vuex.Store({
state: {
counter:1000,
},
mutations: {
add(state){
setTimeout(()=>{
state.counter++
},1000)
}
})

所以当有异步操作时,就不要再使用mutation,而有时候必须要使用一些异步操作,该怎么办?
Action类似于Mutation,但是是用来代替Mutation进行异步操作的。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
counter:1000,
},
mutations: {
add(state){
state.counter++
},
},
actions: {
action_add(context){
setTimeout(()=>{
context.commit("add")
},1000)}
},
})
在App.vue进行修改
methods:{
addcounter(){
this.$store.dispatch("action_add")
},

Modules属性
Modules是模块的意思,为什么在Vuex中使用模块呢?
- Vue使用单一状态树(也就是一个项目中只有一个store),那么也意味着很多状态都会交给Vuex来管理
- 当应用变得非常复杂时,store对象就有可能变得相当臃肿
为了解决这个问题,Vuex允许将store分割成(Module),而每个模块拥有自己的state、mutations、action、getters等
const modulesA = {
state:{...},
mutations:{...},
actions:{...},
getters:{...},
}
const modulesB = {
state:{...},
mutations:{...},
actions:{...},
getters:{...},
}
const modules = {
state:{...},
mutations:{...},
actions:{...},
getters:{...},
modules:{
a:modulesA,
b:modulesB
}
}
如何在其他页面使用?
在modulesA中设置一个name属性
const modulesA = {
state:{
name:"张三"
},
mutations:{...},
actions:{...},
getters:{...},
}
在App.vue中使用
<h1>{{$store.state.a.name}}</h1>
修改modulesA中的name为李四
const modulesA = {
state:{
name : "张三"
},
mutations:{
updatename(state){
state.name="李四"
}
}
}
//App.vue
<h1>{{$store.state.a.name}}</h1>
<button @click="updatea">修改名字</button>
methods:{
updatea(){
this.$store.commit("updatename")
}
}
|