Vuex

Vuex是一个专门为vue.js应用程序开发的状态管理模式,用于集中式存储和管理应用的所有软件的状态

比如我们需要保存的用户登陆信息,购物车信息,或多个页面共享的信息等;

 

什么是单项数据流?

单向数据流”理念的简单示意:

 

State将数据映射到View,View中的Actions事件改变State数据源

 

单项数据流有一些弊端,当我们多个组件共享一个状态时,我们每个组件都需要去操作这个数据,这样会使得代码非常臃肿。

因此,Vuex将组件的共享状态抽离出来,以一个全局单例模式来进行管理。

 

Vuex基础

 

 

 基本使用

1.首先,需要将vuex安装,因为是运行时依赖,所以:

npm install vuex --save

 

2.使用vue.use将它注册

vue.use(vuex)
 
3.创建store实例,vuex使用单一状态树,每个应用中都包含一个store实例
const store = new vuex.Store()
 
4.将store导出,并挂载到vue实例上
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
 

详细

五个基本属性:

const store = new vuex.Store({
    state,                             
    getters,
    mutations,
    actions,
    modules:{
        a:moduleA
    }
})

1.state

const state = {
    count : [],
    name:'我是'
}

 
//state中存储着我们需要共享的数据源,我们可以通过 $store.state.name 拿到state中的name值
 
2.getter
 
getter是计算属性,比如当我们需要对一个数组进行过滤时,我们可以使用它:
 
filterArr:state=>{
        return state.count.filter(s=>{
            return s>2
        })
}
 
//这边会传一个state进来,指向当前模块的state
 
然后我们可以直接使用这个函数
 <h1>{{$store.getters.filterArr}}</h1>
 
那么,如果我们需要传一个值给getters中的函数呢?
我们可以直接返回一个函数:
filterArrFn:state=>{
        return item=>{
            return state.count.filter(s=>{
                    return s>item
            })
        }
    }
 
 
<h1>{{$store.getters.filterArrFn(1)}}</h1>
 

 

 

3.mutations

当我们需要改变state源数据中的值时,我们可以在mutations中实现,视图层通过commit来提交事件类型:

this.$store.commit("addOb",ob);  //addOb是我们在mutations中定义的事件类型,ob是我们要传入的参数,可以是一个对象。
 
addOb(state,ob){        //第一个参数还是默认传入的当前模块的state,第二个参数用于接收传入的值
        state.count.push(ob);
    }
 

 

//注意,在mutations中推荐写同步操作,如果在其中写异步操作,虽可以实现,但是devtools工具监测不到。

//所以对于异步操作,我们在actions中处理,然后commit给mutations

 

4.actions

actions用于处理异步操作,然后commit提交给mutations:

addCount(context){
        //console.log(context)
        setTimeout(() => {
            context.commit("sss")
        }, 1000);
  }

这里使用计时器模拟异步操作,actions中定义的事件类型,默认会传入一个context参数,代表当前模块的上下文,在context中,我们可以拿到store中的属性

那么,可以拿到store中的属性,是不是可以直接更改state中的源数据,不使用commit提交呢?

 

测试的结果:

可以改变数据,但是devtools检测不到,所以说,任何需要改变state元数据的操作,都需要通过mutation。

 

addCount事件定义好了之后,可以通过dispatch来提交:

<button @click="dispatch">action</button>
dispatch(){
      this.$store.dispatch("addCount")
    }

 

5.modules

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

//定义了一个module模块

export default {
    state:{
        name:"我是张三"
    },
    mutations : {
        show(state){
            console.log( state.name);
            state.name = '我是李四'
            console.log( state.name);
        }
    },
    
}
 
//然后在modules中引入
import moduleA from "./modules/moduleA"
const store = new vuex.Store({
    state,
    getters,
    mutations,
    actions,
    modules:{
        a:moduleA
    }
})
 
使用方法:
<h1>{{$store.state.a.name}}</h1>
使用commit,dispatch提交事件类型时不需要加前缀,和正常提交一样使用:
this.$store.commit("show");
所以,不要定义重复的事件名
 
那当事件名重复时,再提交会出现什么?
测试后发现:两个重复的事件都会执行!
 
 
posted @ 2019-12-15 16:30  淡薄幽清  阅读(38)  评论(0)    收藏  举报