vuex

411 阅读4分钟

1.什么是vuex?

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

2.为什么需要vuex

当应用较简单时,组件之间的通信以及交互不会很多,组件间通信即可解决数据共享的问题。但是当应用足够复杂,多个组件共享一个状态的时候,组件通信会十分繁琐混乱并且不易管理。此时把组件的共享状态抽取出来,以一个全局单例模式管理,在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为,这样就可以实现状态的高效管理,并且代码更容易维护

3.store

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。 Vuex Store是响应式的,当Vue组件从store中读取状态(state选项)时,若store中的状态发生更新时,他会及时的响应给其他的组件(类似双向数据绑定) 而且不能直接改变store的状态,改变状态的唯一方法就是,显式地提交更改commit(mutations选项)

vuex 的dispatch和commit提交mutation的区别

当你的操作行为中含有异步操作,比如向后台发送请求获取数据,就需要使用action的dispatch去完成了,其他使用commit即可。 这里不通过直接修改store.state的值,而是通过提交mutation去变更,主要是为了使得整个数据的变更可以追踪。

4.state:用来存放组件之间共享的数据。

他跟组件的data选项类似,只不过data选项是用来存放组件的私有数据。 读取状态:
computed: { totalPrice (){ return this.$store.state.totalPrice; } }, 或者采用辅助函数mapstate, computed: { ...mapState([ 'totalPrice' ]), }, 因为Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中

//vuex store
import store from './store/';

const appAdmin = new Vue({
    el    : '#app',
    data() {
        return {};
    },
    router,
    store,
    render: h => h(App)
})

getters:有时候,我们需要对state的数据进行筛选,过滤。这些操作都是在组件的计算属性进行的。如果多个组件需要用到筛选后的数据,那我们就必须到处重复写该计算属性函数;或者将其提取到一个公共的工具函数中,并将公共函数多处导入 - 两者都不太理想。如果把数据筛选完再传到计算属性里就不用那么麻烦了,getters就是干这个的,你可以把getters看成是store的计算属性。getters将store的state中的值重新计算后供整个应用使用.getters下的函数接收接收state作为第一个参数。那么,组件是如何获取经过getters过滤的数据呢?

过滤的数据会存放到$store.getters对象中。具体看一个例子:

module.exports = {
    getUserinfo(state) {
        return state.userinfo;
    },

    getToken(state) {
        return state.userinfo && state.userinfo.token ? state.userinfo.token : '';
    },

    getRemumber(state){
        return state.remumber;
    }
};

5.Mutation

每一个mutation都会有一个事件的type和callback,当我们store.commit(‘plus’)一个事件后,vuex会根据它的type(plus),然后调用相应的callback执行增加的操作,然后去变更仓库中的状态。

Mutation 必须是同步函数 这个是mutation中最重要的一点,如果你在mutation中有异步的回调,那么追踪记录就不可能了,这样就破坏了vuex的初衷。

6.Action

action就是异步提交mutation。Action 通过 store.dispatch 方法触发, action也是支持嵌套的,是因为store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise。

this.$store.dispatch('update_userinfo');
import * as types from './mutations_types';
module.exports = {
    update_userinfo: ({commit}, {userinfo}) => {
        return new Promise((resolve, reject) => {
            commit(types.UPDATE_USERINFO, {
                userinfo
            });
            resolve()
        });
    },

    remove_userinfo: ({commit}) => {
        return new Promise((resolve, reject) => {
            commit(types.REMOVE_USERINFO);
            try {
                resolve()
            }catch(e){
                console.log(e);
            }

        });
    },

通过状态集中管理驱动组件的变化,也就是集中的存储管理应用的所有组件的数据以及状态等。

在项目中应用:

安装npm install vuex --save-dev

import Vuex from 'vuex';
Vue.use(Vuex);

    Vue.use(Vuex);//在创建Vue实例之前
   var myStore =  new Vuex.Store({
        state:{
            //存放组件之间共享的数据
            name:"jjk"
        },
         mutations:{
             //显式的更改state里的数据
         },
         getters:{
             //获取数据的方法
         },
         actions:{
             //
         }
    });
    new Vue({
        el:"#app",
        data:{
            name:"dk"
        },
        store:myStore,
        mounted:function(){
            console.log(this)//控制台
        }
    })

需要注意的问题:

由于vue是单页面应用,我们在项目的入口文件main.js注册使用vuex来管理全局变量。但是当我们刷新页面时,全局变量就会初始化,导致拿不到我们想要的值。为了解决这个问题,我们在将全局需要用到的vuex的状态(例如用户登录的信息)存放在localstorage里,即可解决。将store对象的构造函数重写,将this.stroe指向local storage,然后设置set和get方法分别存取local storage 的内容。