Vuex

Posted by CodingWithAlice on October 1, 2021

Vuex

vuex是专为 Vue.js 应用程序开发的 状态管理模式。它采用 集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

主要用于管理vue中的数据,可以兄弟组件互相传值;

1、图文解析

上图的解释:

Vue Components 是我们的 vue 组件组件会触发(dispatch)一些事件或动作(Actions);

② 我们在 组件 中发出的动作,肯定是想获取或者改变数据的,但是在 vuex 中,数据是集中管理的,我们不能直接去更改数据,所以会把这个动作提交(Commit)到 Mutations 中;

③ 然后 Mutations 就去改变(MutateState 中的数据;

④ 当 State 中的数据被改变之后,就会重新渲染(Render)到 Vue Components (组件)中去, Vue Components (组件)展示更新后的数据,完成一个流程。

// 调用数据
this.$store.state.city;

//修改store中的内容
this.$store.dispatch('name',value);

//或者直接使用commit进行修改
this.$store.commit('name',value);

2、核心 - store

Vuex 的核心是 Store(仓库),相当于是一个容器,一个Store实例中包含以下属性的方法:

  • state 定义属性(状态 、数据)
  • getters 用来获取属性【就像计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算;getter 接受 state 作为其第一个参数;】
  • actions 定义方法(动作)【也可以直接修改state,通过提交 mutation 的方式,而非直接改变 this.$store.state.count,是因为我们想要 更明确地追踪到状态的变化
  • commit 提交变化,修改数据的唯一方式就是提交 mutations
  • mutations 定义变化,处理状态(数据)的改变【操作state中的数据store.commit('increment')
  • mapGetters 用来获取属性(数据)
  • mapActions 用来获取方法(动作)state:管理项目的数据(进行数据初始化);

3、mutation和action之间有什么区别?

actions 可以包含任意异步操作,提交的是 mutation,而不是直接变更状态;

mutation是同步的,使用 this.$store.commit('xxx') 来提交mutation;

(下文来自尤大大)

区分 actions 和 mutations 并不是为了解决竞态问题,而是 为了能用 devtools 追踪状态变化

事实上在 vuex 里面 actions 只是一个架构性的概念,并不是必须的,说到底只是一个函数,你在里面想干嘛都可以,只要 最后触发 mutation 就行。异步竞态怎么处理那是用户自己的事情。vuex 真正限制你的只有 <span style=color:red>mutation 必须是同步的</span> 这一点(在 redux 里面就好像 reducer 必须同步返回下一个状态一样)。

同步的意义在于这样每一个 mutation 执行完成后都可以对应到一个新的状态,这样 devtools 就可以打个 snapshot 存下来,然后就可以随便 time-travel 了。

如果你开着 devtool 调用一个异步的 action,你可以清楚地看到它所调用的 mutation 是何时被记录下来的,并且可以立刻查看它们对应的状态。

<div id="app1">8</div>
//store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
    state:{
        count:0
    }
});

new Vue({
    el:'#app1',
    store,
    computed:{
        count(){
            return this.$store.state.count
        }
    }
})

4、vuex的使用

需要在根实例main.js中传入store

import store from './store'
new Vue({
    el: '#app',
    router,
    store,
    components: { App },
    template: '<App/>'
})

写在一个页面上的话,需要判断本地是否已经有这个数据了

1567605439082

在src–store–index.js中声明state、mutations

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
Vue.use(Vuex)

export default new Vuex.Store({
    state,
    mutations
})

然后在src–store–state.js中声明公共使用的数据

let defaultCity = '上海'
try {
    if (localStorage.city) {
        defaultCity = localStorage.city
    }
} catch (e) {}

export default {
    city: defaultCity // 调用的时候,调用city就可以了
}

在src–store–mutations.js中声明改变公共变量的方法

export default {
    changeCity (state, city) { // 调用的时候使用changeCity就可以了
        state.city = city
        try {
            localStorage.city = city
        } catch (e) {}
    }
}

在实际使用的页面中,就可以直接使用了

// 调用数据
this.$store.state.city;

//修改store中的内容
this.$store.dispatch('name',value);

//或者直接使用commit进行修改
this.$store.commit('name',value);