天天看点

十三.Vue.js 状态管理Vuex

Vuex是一个状态管理的插件,管理过程包含了state(数据源)、view(state绑定到视图)、actions(view改变同步改变数据源)三个状态,页面刷新的时候vuex里的数据会重新初始化,导致数据丢失,页面会重新加载vue实例,vuex里面的数据就会被重新赋值,解决办法:将vuex中的数据直接保存到浏览器缓存中(sessionStorage、localStorage、cookie),界面刷新前把数据存sessionStorage或再次请求远程数据,使之动态更新vuex数据,App.vue中添加以下代码

// App.vue 
//===========================下面是解决刷新页面丢失vuex数据
  created() {
    //在页面加载时读取sessionStorage里的状态信息
    if (sessionStorage.getItem('store')) {
      this.$store.replaceState(Object.assign({}, this.$store.state,         JSON.parse(sessionStorage.getItem('store'))));
    }

    //在页面刷新时将vuex里的信息保存到sessionStorage里
    window.addEventListener('beforeunload', () => {
      sessionStorage.setItem('store', JSON.stringify(this.$store.state));
    });
  }
           

应用场景:(购物车的数据共享,登入注册)

  • 多个视图依赖于同一状态
  • 来自不同视图的行为需要变更同一状态
  • 可以思考到涉及

    sessionStorage

    cookies

    之类的里面或涉及到非父子关系的组件,例如兄弟关系、祖孙关系,甚至更远的关系组件之间的联系

Vuex使用:

  • 安装:cnpm install vuex --save
  • 引入:import Vuex from 'vuex'           Vue.use(Vuex)
  • 创建:  new Vuex.Store({})
  • 使用:挂载到new Vue()上,new Vue({store })

new Vuex.Store 配置

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const store = new Vuex.Store({
    state: {
        todos: [
          { id: 1, text: '...', done: true },
          { id: 2, text: '...', done: false }
        ]
    },
    getters: {
        doneTodos: state => {
            return state.todos.filter(todo => todo.done)
        }
    },
    mutations: {
        todosAdd(state,obj) {
          // 变更状态
          state.todos.push(obj)
        }
    },
    actions: {
        todosAddM(context,obj){ // context属性:state、rootState、commit、dispatch、getters、rootGetters
            context.commit('todosAdd',obj)
        }
    },
    modules: {
        a: moduleA, // moduleA配置和根模块的选项一样,store.state.a // -> moduleA 的状态
        b: moduleB
    }
})

export default store;
           
  • store、modules:存储数据 
  • getters:计算属性,可以理解为跟computed一样,访问 store.getters.doneTodos
  • mutations:通过里面方法改变state里面的数据,通过 store.commit('todosAdd',{id: 3,text:'''}) 调用,同步处理
  • actions:不能直接修改state,通过触发mutations来修改,可操作异步、多个同步处理,通过 store.dispatch('todosAddM',{id: 3,text:'''})调用

Store读取

  • 可以直接 

    created

     时从中读取 

    $store.state

     值,通过 

    commit()

     来修改值
  • mapState、mapGetters、mapActions、mapMutations:当一个组件需要获取多个状态时使用,import { mapState } from 'vuex'
    <template>
      <div id="example">
        {{count}}
      </div>
    </template>
    <script>
    import { mapState } from 'vuex'
    export default {
      data () {
        return {
          str: '国籍',
          dataCount: this.$store.state.count
        }
      },
      computed: mapState({
        count: 'count', // 第一种写法
        from: function (state) { // 用普通函数this指向vue实例,要注意
          return this.str + ':' + state.from
        }
      }),
      methods: {
        increment () {
          this.$store.commit('increment')
        },
        decrement () {
          this.$store.commit('decrement')
        }
      },
      created () {
        // 写个定时器,发现computed依旧保持了只要内部有相关属性发生改变不管是当前实例data中的改变,还是vuex中的值改变都会触发dom和值更新
        setTimeout(() => {
          this.str = '国家'
        }, 1000)
      }
    }
    </script>