• [译]Managing Vue.js State with Vuex


    原文

    准备

    安装

    Vuex, 是Vue官方出的package, 它不是Vue内置的。需要另外安装。

    npm install vuex --save
    

    然后,需要在应用启动文件启用Vuex

    main.js

    import Vue from 'vue';
    import Vuex from 'vues';
    import App from 'App.vue';
    
    Vue.use(Vuex);
    
    new Vue({
        el: '#app',
        render: h => h(app)
    });
    

    创建一个Store

    store.js

    export const store = new Vuex.store({
        state: {
            safelyStoredNumber: 0
        }
    });
    

    为了使用这个store你必须在你所有要使用其的component里面import这个store。 或者你可以将它注入到跟Vue实例中,这样应用的其他组件都可以使用这个store了。

    main.js

    import Vue from 'vue';
    import Vuex from 'vuex';
    import App from 'App.vue';
    import { store } from './store.js';
    
    Vue.use(Vuex);
    
    new Vue({
        store, 
        el: '#app',
        render: h => h (App)
    });
    

    访问State

    下载创建getter来从store中读取数据。

    使用Getters

    在store中getter是一个简单的函数,它接收一个state对象返回它的一个值。在component中,可以通过this.$store.getters.property做为一个计算属性(不是函数)来获取。如果getter需要接受一个参数,可以返货一个接受参数的函数。

    store.js

    export const store = new Vuex.store({
        state: {
            safelyStoredNumber: 0
        },
        getters: {
            safelyStoredNumber: state => state.safelyStoredNumber,
            storedNumberMatches(state) {
                return matchNumber => {
                    return state.safelyStoredNumber === matcheNumber;
                }
            }
            // 简写
            storedNumberMatches: state => matchedNumber => state.safelyStoreNumber === matcheNumber
        }
    });
    

    在components最简单的访问getters的方法是通过Vuex的mapGetters方法。它让你可以在component中直接使用safelyStoreNumber而不是this.$store.getters.safelyStoreNumber

    App.vue

    <template>
        <p>The safely stored number: {{safelyStoredNumber}}</p>
    </template>
    
    <script>
        import { mapGetters } from 'vuex'
        
        export default {
            computed: {
                ...mapGetters([
                    'safelyStoredNumber'
                ])
            }
        }
    </script>
    

    修改state

    Synchronous Mutations

    调用mutation的函数来修改state。mutation接受一个当前的state和一个可选的payload。payload可以是任何对象。mutation必须是同步的,并且不应该返回任何值。使用this.$store.commit('mutationName', payload)来调用mutation。

    store.js

    export const store = new Vuex.Store({
        state: {
            safelyStoredNumber: 0
        },
        ...
        mutations: {
            incrementStoredNumber(state) {
                state.safelyStoredNumber++;
            },
            setStoredNumber(state, newNumber) {
                state.saftlyStoredNumber = newNumber;
            }
        }
    });
    

    和getters一样,Vuex有一个使用mutation的简便方法,那就是mapMutations方法。

    App.vue

    <template>
        <p>The safely stored number: {{safelyStoredNumber}}</p>
    </template>
    
    <script>
        import { mapMutations } from 'vuex'
    
        export default {
            ...
            methods: {
                ...mapMutations([
                    'incrementStoredNumber',
                    'setStoredNumber'
                ])
            }
        }
    </script>
    

    异步Actions

    在一些复杂的应用中,你可能需要执行一些异步方法来修改state。Vues使用actions来处理这个。action接受一个state context,使得在action里面可以访问getter和commit mutations。
    action最好(非必需)是返回一个Promise指明完成状态。使用ES2017的async/await,可以轻松的检出async action。在component中通过this.$store.dispatch('actionName', payload).then(response => {})使用action。

    在action中通过context.commit('mutationName', payload)修改state。

    store.js

    import myRemoteService from './my-remote-service.js'
    
    export const store = new Vuex.store({
        state: {
            safelyStoredNumber: 0
        },
        ...
        actions: {
            async setNumberToRemoteValue(context) {
                // commit 'setStoredNuymber' mutation
                context.commit('setStoredNumber', await myRemoteService.getRemoteValue());
                return Promise.resolve();
            },
        }
    });
    

    和getters一样,Vuex有一个使用action的简便方法,那就是mapActions方法。

    App.vue

    <template>
        <p> The safely stored number: {{safelyStoredNumber}}</p>
    </template>
    
    <script>
        import { mapActions } from 'vuex'
        export default {
            ...
            methods: {
                ...mapActions([
                    'setNumberToRemoteValue',
                ])
            }
        }
    </script>
    

    模块化

    随着actions,mutations, getters越来越多你需要按照模块来分割它们。Vuex提供了Modules来实现这个。

    my-store-module.js

    export const myModule = {
        // This makes your getters, mutations, and actions accessed by, eg: 'myModule/myModularizedNumber' instead of mounting getters, mutations, and actions to the root namespace.
        namespaced: true,
        state: {
            myModularizedNumber: 0
        },
        getters: {
            myModularizedNumber: state => state.myModularizedNumber
        },
        mutations: {
            setModularizedNumber(state, newNumber) {
                state.myModularizedNumber = newNumber
            }
        }
    }
    

    store.js

    import { myModule } from  './my-store-module.js';
    
    export const store = new Vuex.store({
        modules: {
            myModule
        },
        state: {
            safelyStoredNumber: 0
        },
        ...
    });
    

    mapGetters, mapMutations, mapActions可以接受第一个参数来标明module的命名空间。

    ...mapGetters([
        'myModule/nestedModule/subNestedModule/exampleGetter',
        'myModule/nestedModule/subNestedModule/anotherGetter',
    ])
    

    可以使用上面的代码来替代上面的代码:

    ...mapGetters('myModule/testedModule/subNestedModule', [
        'exampleGetter',
        'anotherGetter'
    ])
    
  • 相关阅读:
    机器学习规则:ML工程最佳实践----rules_of_ml section 2【翻译】
    机器学习规则:ML工程最佳实践----rule_of_ml section 3【翻译】
    知识图谱技术分享会----有关知识图谱构建的部分关键技术简介及思考
    【e2Open】
    【2B】企业供应链管理软件
    【交互】复杂逻辑配置的一个不错的方法(神策数据)
    【视觉】交易数据展示
    【视觉】数据平台
    【设计复盘】APP设计复盘
    【设计规范】腾讯课堂
  • 原文地址:https://www.cnblogs.com/irocker/p/intro-to-vuex.html
Copyright © 2020-2023  润新知