美文网首页
探究VueX

探究VueX

作者: _既白_ | 来源:发表于2018-09-20 18:41 被阅读52次

    VueX

    Vuex 核心概念

    状态管理模式,集中式存储管理Vuex其实就是一个针对Vue项目设计的状态机,相当于把需要共享的变量存储在状态机中(store),然后将这个状态机挂在根组件中(绑在vue实例上)使用。

    State

    state是状态在机中状态的集合,相当于对象的属性集合,用来存储状态态。

    Getter

    getter属于派生状态,是store中的计算属性。getter的返回值会根据它的依赖被缓存起来,并且只用当它的依赖的state值发生改变才会被重新计算。

    state :{
            name:'VueX的使用:',
            count:0
    
        },
    getters:{
            splicing:state => {//这里的state对应着上面这个state
                return state.module_one.name + state.module_one.count;
            }
        },
    

    Actions

    Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。异步操作mutation

    const store = new Vuex.Store({
      state: {
        count: 0
      },
      mutations: {
        increment (state) {
          state.count++
        }
      },
      actions: {
        increment (context) {
          context.commit('increment')
        }
      }
    })
    

    Mutation

    更改 Vuexstore 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

    
    state :{
    
            name:'VueX的使用:',
            count:0
    
        },
    
    mutations:{
            increase(state){//这里的state对应着上面这个state
                state.module_one.count++;
                //你还可以在这里执行其他的操作改变state
            },
    
            reduce(state){
                state.module_one.count--;
            }
        },
    

    你不能直接调用一个 mutation handler。这个选项更像是事件注册:“当触发一个类型为 incrementmutation 时,调用此函数。”要唤醒一个 mutation handler,你需要以相应的 type调用 store.commit 方法:

    this.$store.commit('increment');
    
    

    Module

    由于使用单一store,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 statemutationactiongetter、甚至是嵌套子模块——从上至下进行同样方式的分割

    const moduleA = {
      state: { ... },
      mutations: { ... },
      actions: { ... },
      getters: { ... }
    }
    
    const moduleB = {
      state: { ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        a: moduleA,
        b: moduleB
      }
    })
    
    store.state.a // -> moduleA 的状态
    store.state.b // -> moduleB 的状态
    

    Vuex的应用

    业务简单的项目

    使用

    <template>
        <div>
            <div @click="clickAction('increase')">increase</div>
            <div @click ="clickAction('reduce')">increase</div>
            <label>{{conunt}}</label>
            <label>{{splicingString}}</label>
        </div>
    </template>
    
    <script>
        export default {
    
            data () {
    
                return {
    
                    conunt:'',
                    splicingString:''
                }
            },
            
        }
        
        methods:{
           clickAction (flag) {
    
             if (flag == 'increase') {
    //            this.$store.commit('increase');
                  this.$store.dispatch('changeAsyn');
               }else {
                  this.$store.commit('reduce');
               }
               this.conunt =  this.$store.state.count;
               this.splicingString = this.$store.getters.splicing;
    
            }
    
         }
    
    </script>
    
    

    index.js (简单的项目)

    store目录中创建index.js文件,在此文件中创建状态机

    import Vue from 'vue'
    import vuex from 'vuex'
    import module_one from './module-one'
    Vue.use(vuex);
    
    
    export default new vuex.Store({
    
        state :{
            name:'VueX的使用:',
            count:0
    
        },
    
        mutations:{
            increase(state){//这里的state对应着上面这个state
                state.module_one.count++;
                //你还可以在这里执行其他的操作改变state
            },
    
            reduce(state){
                state.module_one.count--;
            }
        },
    
        getters:{
            splicing:state => {//这里的state对应着上面这个state
                return state.module_one.name + state.module_one.count;
            }
        },
    
        actions:{
    
            changeAsyn(context) {
                setTimeout(() => {
                    context.commit('increase');
                }, 1000);
            }
    
        }
    
    
    })
    

    业务复杂的项目

    目录结构(官方推荐)

    ├── index.html
    ├── main.js
    ├── components
    └── store
        ├── index.js          # 我们组装模块并导出 store 的地方
        ├── state.js          # 跟级别的 state
        ├── getters.js        # 跟级别的 getter
        ├── mutation-types.js # 根级别的mutations名称(官方推荐mutions方法名使用大写)
        ├── mutations.js      # 根级别的 mutation
        ├── actions.js        # 根级别的 action
        └── modules
            ├── m1.js         # 模块1
            └── m2.js         # 模块2
    

    store.js

    const state = {
        name:'Hello VueX',
        count:0
    };
    export default state;
    

    getters.js

    export default {
        name:state => state.name;
        count:state => state.count;
        splicing:state => {
            return state.name + state.count;
       }
    }
    
    or
    
    export const name = (state) => {
        return state.name;
    }
    
    export const count = (state) => {
        return state. count
    }
    
    export const splicing = (state) => {
        return `My name is ${state.name}, I am ${state.count}.`;
    }
    
    

    mutation-type.js

    我们会将所有mutations的函数名放在这个文件里):
    
    export const SET_NAME = 'SET_NAME';
    export const SET_COUNT = 'SET_COUNT';
    

    mutations.js

    import * as types from './mutation-type.js';
    
    export default {
        [types.SET_NAME](state, name) {
            state.name = name;
        },
        [types.SET_COUNT](state, count) {
            state.count = count;
        }
    };
    
    外部使用:
    

    actions.js

    // 异步操作多个commit
    import * as types from './mutation-type.js';
    export default {
        nameAsyn({commit}, {age, name}) {
            commit(types.SET_NAME, name);
            commit(types.SET_COUNT, age);
        }
    };
    
    
    

    modules--m1.js

    
    export default {
        state: {},
        getters: {},
        mutations: {},
        actions: {}
    };
    
    

    index.js示例(组装vuex):

    import vue from 'vue';
    import vuex from 'vuex';
    import state from './state.js';
    import * as getters from './getters.js';
    import mutations from './mutations.js';
    import actions from './actions.js';
    import m1 from './modules/m1.js';
    import m2 from './modules/m2.js';
    import createLogger from 'vuex/dist/logger'; // 修改日志
    
    vue.use(vuex);
    
    const debug = process.env.NODE_ENV !== 'production'; // 开发环境中为true,否则为false
    
    export default new vuex.Store({
        state,
        getters,
        mutations,
        actions,
        modules: {
            m1,
            m2
        },
        plugins: debug ? [createLogger()] : [] // 开发环境下显示vuex的状态修改
    });
    
    

    store 挂载到main.js中的vue实例上

    
    import store from './store/index.js';
    
    new Vue({
      el: '#app',
      store,
      render: h => h(App)
    });
    
    or 
    
    import store from './store/index'
    App.vue 文件
    export default {
      name: 'app',
        store,//使用store
      components: {
        HelloWorld
      }
    }
    

    mapGetters、mapActions、mapMutations

    很多时候 , $store.state.dialog.name$store.dispatch('nameAsyn') 这种写法又长又臭 , 很不方便 , 我们没使用 vuex 的时候 , 获取一个状态只需要 this.name , 执行一个方法只需要 this. setName 就行了 , 使用 vuex 使写法变复杂了 ?

    使用 mapState、mapGetters、mapActions 就是为了简化:$store.state.name$store.dispatch('nameAsyn') $store.commit('SET_NAME')this.$store.getters.name变成更加简单的方式:如访问 this.name ,this.splicing,this.setName,this.nameAsyn

    
    import {mapGetters, mapMutations, mapActions} from 'vuex';
    
    /* 只写组件中的script部分 */
    export default {
        computed: {
            ...mapGetters([
                name,
                age,
                splicing
            ]),
            
            ...mapState([
                    'name'
            ])
        },
        methods: {
            ...mapMutations({
                setName: 'SET_NAME',
                setAge: 'SET_AGE'
            }),
            ...mapActions([
                nameAsyn
            ])
        }
    };
    

    参考链接

    Vue 官网文档
    理解vuex -- vue的状态管理模式
    前端框架Vue(4)——vuex 状态管理
    vuex最简单、最详细的入门文档

    相关文章

      网友评论

          本文标题:探究VueX

          本文链接:https://www.haomeiwen.com/subject/ibxwnftx.html