欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【Vue】状态管理

程序员文章站 2022-03-26 21:01:23
页面应用需要Vuex管理全局/模块的状态,大型单页面组件如果靠事件(events)/属性(props)通讯传值会把各个组件耦合在一起。因此需要Vuex管理属性之间都状态 ......
  页面应用需要vuex管理全局/模块的状态,大型单页面组件如果靠事件(events)/属性(props)通讯传值会把各个组件耦合在一起。因
此需要vuex统一管理,当然如是小型单页面应用,引用vuex反而会增加复杂度。因此需要衡量引用vuex增加的收益是否大于成本。
 

快速入门

 

1. 安装vuex库

cnpm install -s vuex

 

2. 创建vuex.store

import vue from 'vue'
import vuex from 'vuex'

vue.use(vuex);

const store = new vuex.store({
    //组件数据源,单一的state属性
    state: {
        clickcount: 0
    },
    //相当于属性,封装获取state
    getters: {
        getclickcount: state => {
            return state.clickcount;
        }
    },
    //封装引起状态变化的方法
    mutations: {
        increment(state) {
            state.clickcount++;
        }
    },
    //类似于 mutation,不同在于actions支持异步,不是直接变更状态,而是提交到mutation
    actions: {
        increment(context) {
            context.commit('increment')
        },
        async incrementasync({ commit }) {
            return new promise((resolve, reject) => {
                settimeout(() => {
                    try {
                        commit('increment');
                        resolve(new date().gettime() + '  成功执行');
                    } catch (e) {
                        reject(e);
                    }
                }, 1000)
            });
        }
    }
});
export default store;

 

3. vue实例加入store

new vue({
    router: router,
    store: store,
    render: h => h(app),
}).$mount('#app')

 

4. 组件获取store值

<script>
import { mapgetters } from "vuex";

export default {
  computed: mapgetters({ count: ["getclickcount"] }),
};
</script>

 

5. 组件触发更新

<script>
export default {
  data() {
    return { times: 0 };
  },
  methods: {
    increment() {
      this.times++;
      //分发到action
      this.$store.dispatch("incrementasync");
      //提交到mutations
      this.$store.commit("increment");
    },
  },
};
</script>

 

解析

vuex 是什么?


   

  vuex 是一个专为 vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。vuex 也集成到 vue 的官方调试工具devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。

 

state - 数据源


 

vuex 使用单一状态树——是的,用一个对象就包含了全部的应用层级状态。

vue通过store选项,调用vue.use(vuex)注入到每一个子组件中(类似路由)

组件获取state

computed: {
    count () {
      return this.$store.state.count
 }
}

 

或者使用辅助函数mapstate

computed: mapstate({
    // 箭头函数可使代码更简练
    count: state => state.count
})

 

getter - 数据封装读取(类似属性)


 

getter 接受 state 作为其第一个参数

getters: {
    donetodos: state => {
      return state.todos.filter(todo => todo.done)
    },
    gettodobyid: (state) => (id) => {
      return state.todos.find(todo => todo.id === id)
    }
  }

 

通过属性访问

store.getters.donetodos

 

通过方法访问

store.getters.gettodobyid(2)

getters 也提供了一个辅助函数方便访问(mapgetters )

 

mutation - 进行状态更改的地方


 

定义mutation

mutations: {
  increment (state, n) {
    state.count += n
  }
}

 

组件触发变更

store.commit('increment', 1)

 

mutations也提供辅助函数(mapmutations)

import { mapmutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapmutations([
      'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

      // `mapmutations` 也支持载荷:
      'incrementby' // 将 `this.incrementby(amount)` 映射为 `this.$store.commit('incrementby', amount)`
    ]),
    ...mapmutations({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

注意事项

  • mutation 必须是同步函数
  • 最好提前在你的 store 中初始化好所有所需属性。
  • 需要在对象上添加新属性时使用 vue.set 或 替换旧对象

 

action - 对mutation封装


 

 

action 类似于 mutation,不同在于:

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

定义action

actions: {
  increment ({ commit }) {
    commit('increment')
  }
}

 

组件分发action

store.dispatch('increment')

 

支持异步方式分发

actions: {
        async incrementasync({ commit }) {
            return new promise((resolve, reject) => {
                settimeout(() => {
                    try {
                        commit('increment');
                        resolve(new date().gettime() + '  成功执行');
                    } catch (e) {
                        reject(e);
                    }
                }, 1000)
            });
        }
    }

 

组件调用异步分发

this.$store.dispatch("incrementasync").then(
        (data) => {
          console.log(data);
        },
        (err) => {
          console.log(err);
        }
      );

 

参考文章