zoukankan      html  css  js  c++  java
  • 【Vue】状态管理

      页面应用需要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);
            }
          );

    参考文章

  • 相关阅读:
    那些创业的艰辛整理
    一个成功的研发团队应具备的9大属性
    如何将 Linux 系统转移至 LVM 卷
    如何在 Linux 上永久挂载一个 Windows 共享
    怎样在 Chromebook 上安装 Linux 系统?
    1087 有多少不同的值 (20 分)C语言
    1052 卖个萌 (20 分)C语言
    1064 朋友数 (20 分)C语言
    1045 快速排序 (25 分)C语言
    1048 数字加密 (20 分)C语言
  • 原文地址:https://www.cnblogs.com/WilsonPan/p/12773090.html
Copyright © 2011-2022 走看看