Vuex理解与使用

1.Vuex是什么

  Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,用于管理页面的数据状态、提供统一数据操作的生态系统。在组件中可以任意获取仓库中的数据。和Vuex类似的还有redux,redux一般在react中使用比较多。

   ----来自官方示例图

 

  1.在组件中,通过dispatch一个Actions->Mutations->State,最后渲染组件

  2.其中在actions可以异步操作。不需要异步操作时,只需要commit一个mutions去修改仓库中的数据,然后组件就会渲染。

  3.并且vuex是响应式的,如果仓库(state)中的数据被更改了,那么页面也会相应的更新

  4.其中vuex规定了。仓库(state)中的数据更改必须通过mutations。不可以直接修改

2.安装

  1.通过src方式引入静态文件

     <script src="/path/to/vue.js"></script>

     <script src="/path/to/vuex.js"></script>

  2.通过npm/yarn安装

     npm install vuex -S

     yarn add vuex

3.注入vuex

  在cli中新建index.js,通过import vuex from 'vuex'引入

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {},
    mutations: {},
    actions: {},
    modules: {}
});
main.js

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';


Vue.config.productionTip = false;

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

4.核心概念

  State:

    1.说明:

      仓库中的数据都保存在这。并且全局只有一个唯一实例,以对象形式存在

    2.基本使用:

      // index.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 1
    },
    mutations: {},
    actions: {},
    modules: {}
});

      组件中: 

<template>
    <div>
        <p>state中的count:{{ $store.state.count }}</p>
    </div>
</template>

<script>
export default {
    created() {
        console.log(this.$store.state.count);
    }
};
</script>

<style scoped lang="scss">
* {
    margin: 0;
    font-size: 20px;
}
</style>

      通过this.$store.state获取仓库所有数据

    3.辅助函数

      mapState返回的是一个对象

        1.引入:在组件中import { mapState } from 'vuex'

        2.使用:mapState和computed    

<template>
    <div>
        <p>state中的count:{{ count }}</p>
        <p>{{ sum }}</p>
    </div>
</template>

<script>
import { mapState } from 'vuex';
export default {
    data() {
        return {
            a: 1,
            b: 2
        };
    },
    created() {
        // console.log(this.$store.state.count);
    },
    computed: mapState({
        // 返回state中的count
        count: state => state.count,

        // 其它计算属性
        sum() {
            return this.a + this.b;
        }
    })
};
</script>

        3.使用扩展运算符...简化

    computed: {
        // 使用字符串数组写法
        ...mapState(['count']),
        // 其它计算属性
        sum() {
            return this.a + this.count;
        }
    }
    computed: {
        // 使用对象写法
        ...mapState({
            countAlias: 'count'
        }),
        // 其它计算属性
        sum() {
            return this.a + this.countAlias;
        }
    }

  Getters:

    1.说明:

      getters就是将state中的数据包装一个在返回,接受第一个参数state,可以访问state中的数据。也可以接受第二个参数其它的getter

    2.基本使用

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        list: [1, 2, 3, 4, 5, 6]
    },
    getters: {
        filterList: state => {
            return state.list.filter(i => i > 3);
        }
    },
    mutations: {},
    actions: {},
    modules: {}
});
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 1,
        list: [1, 2, 3, 4, 5, 6]
    },
    getters: {
        // 使用其他getters
        initData: (state, getters) => {
            return getters.filterList.map(i => i + state.count);
        },
        filterList: state => {
            return state.list.filter(i => i > 3);
        }
    },
    mutations: {},
    actions: {},
    modules: {}
});

      组件中:

<template>
    <div>
        <p>getter中的sum返回值:{{ $store.getters.filterList }}</p>
        <p>使用其他getter:{{ $store.getters.initData }}</p>
    </div>
</template>

<script>
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {
        console.log(this.$store.getters.filterList);
    },
    computed: {}
};
</script>

      通过this.$store.getter获取所有getters

    3.在getter中返回一个函数,实现使用getter时传参

getters: {
        filterList: state => data => {
            return state.list.find(i => i === data);
        }
    },


<template>
    <div>
        <p>getter中的sum返回值:{{ $store.getters.filterList(2) }}</p>
    </div>
</template>

    4.辅助函数:

      mapGetters

        1.引入:import { mapGetters } from 'vuex';

        2.使用:mapGetters和computed

          传递字符串数组

<template>
    <div>
        <p>getter中的sum返回值:{{ filterList(2) }}</p>
    </div>
</template>

<script>
import { mapGetters } from 'vuex';
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {
        console.log(this.$store.getters.filterList);
    },
    computed: {
        ...mapGetters(['filterList'])
    }
};
</script>

          使用对象形式

<template>
    <div>
        <p>getter中的sum返回值:{{ filterListAlias(2) }}</p>
    </div>
</template>

<script>
import { mapGetters } from 'vuex';
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {
        console.log(this.$store.getters.filterList);
    },
    computed: {
        ...mapGetters({
            filterListAlias: 'filterList'
        })
    }
};
</script>

  Mutation 

    1.说明:

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

      在mutation中不可以做异步操作

    2.基本使用

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 1
    },
    getters: {},
    mutations: {
        increment(state) {
            state.count++;
        }
    },
    actions: {},
    modules: {}
});

      组件中:

<template>
    <div>
        <p>state中的count:{{ $store.state.count }}</p>
        <button @click="clickFn">+</button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {},
    methods: {
        clickFn() {
            this.$store.commit('increment');
        }
    }
};
</script>

      通过this.$store.commit('increment');方式修改state中的数据。注意这里的increment解释为mutation的事件类型,并不是函数名称

    a.传参使用,接受第二个参数payload

定义:
mutations: {
        increment(state, payload) {
            state.count += payload;
        }
    },

组件使用:
methods: {
        clickFn() {
            this.$store.commit('increment', '我是参数');
        }
    }

    b.提交方式,一般使用对象形式提交

    methods: {
        clickFn() {
            this.$store.commit({
                type: 'increment',
                data: '我是参数1',
                data2: '我是参数2'
            });
        }
    }


    mutations: {
        increment(state, payload) {
            state.count = state.count + payload.data + payload.data2;
        }
    },

    c.使用常量代替mutation类型事件

       1.新建mutation-types.js文件

          export const SOME_MUTATION = 'someMutation';

       2.引入定义的类型,并使用     

import Vue from 'vue';
import Vuex from 'vuex';
import { SOME_MUTATION } from './mutationTypes';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 1
    },
    getters: {},
    mutations: {
        [SOME_MUTATION](state, payload) {
            state.count += payload.data;
        }
    },
    actions: {},
    modules: {}
});

       3.在组件中使用

<template>
    <div>
        <p>state中的count:{{ $store.state.count }}</p>
        <button @click="clickFn">+</button>
    </div>
</template>

<script>
import { SOME_MUTATION } from '../../store/mutationTypes';
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {},
    methods: {
        clickFn() {
            this.$store.commit(SOME_MUTATION, {
                data: 1
            });
        }
    }
};
</script>

    3.辅助函数

      mapMutations 

        1.引入:import { mapMutations } from 'vuex';

        2.使用:mapMutations和methods

           使用类型时,使用对象形式,将SOME_MUTATION映射为add

    mutations: {
        [SOME_MUTATION](state, payload) {
            state.count += payload.data;
        }
    },

    methods: {
        ...mapMutations({
            add: SOME_MUTATION
        }),
        clickFn() {
            this.add({ data: 2 });
        }
    }

          或者直接使用同名  

<template>
    <div>
        <p>state中的count:{{ $store.state.count }}</p>
        <button @click="add">+</button>
    </div>
</template>

<script>
import { mapMutations } from 'vuex';
import { SOME_MUTATION } from '../../store/mutationTypes';
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {},
    methods: {
        ...mapMutations({ SOME_MUTATION }),
        add() {
            this.SOME_MUTATION({ data: 1 });
        }
    }
};
</script>

          不使用类型时

    mutations: {
        add(state, payload) {
            state.count += payload.data;
        }
    },

    methods: {
        ...mapMutations(['add']),
        clickFn() {
            this.add({ data: 2 });
        }
    }

  Action

    1.说明:

      action类似于mutation,但是action提交的是mutation,而不是直接修改state,也就是通过action提交mutation,然后commit修改state,action可以异步操作

      Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,通过context 访问context.state,context.commit,context.getters,context.dispatch等。

      通过dispatch方法触发

    2.基本使用

export default new Vuex.Store({
    state: {
        count: 1
    },
    getters: {},
    mutations: {
        add(state) {
            state.count += 1;
        }
    },
    actions: {
        increment(context) {
            context.commit('add');
        }
    },
    modules: {}
});

    组件中  

<template>
    <div>
        <p>state中的count:{{ $store.state.count }}</p>
        <button @click="add">+</button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            a: 1
        };
    },
    created() {},
    methods: {
        add() {
            this.$store.dispatch('increment');
        }
    }
};
</script>

    通常会使用解构来简化代码

    actions: {
        increment({ commit, state, getters }) {
            commit('add');
        }
    },

    传递参数

    methods: {
        add() {
            this.$store.dispatch('increment', {
                data: 21
            });
            this.$store.dispatch({
                type: 'increment',
                data: 21
            });
        }
    }

export default new Vuex.Store({
    state: {
        count: 1
    },
    getters: {},
    mutations: {
        add(state, payload) {
            state.count += payload.data;
        }
    },
    actions: {
        increment({ commit, state, getters }, payload) {
            commit('add', payload);
        }
    },
    modules: {}
});

    辅助函数

      mapActions 

        1.引入:import { mapActions } from 'vuex';

        2.使用:mapActions和methods

    methods: {
        // ...mapActions(['increment']),
        ...mapActions({
            incrementAlias: 'increment'
        }),
        add() {
            this.incrementAlias({ data: 1 });
        }
    }

  Module

    略

面试题记录:

  1.vuex是什么

    vuex是一个数据仓库,以对象的形式存在,通过state获取获取数据,状态管理库

  2.有哪几种属性

    state、getter、mutation、action、module

  3.属性作用

    state:数据仓库

    getter:从数据仓库派生出来的一些数据,可以复用

    mutation:修改state,同步

    action:装饰器,异步操作,包裹mutation

    module:模块化vuex

  4.什么时候可以用vuex

    在组件传值,数据复用时,可以用到,虽然父子组件传值,可以使用props/emit等,但是兄弟组件之间,或者多层组件之间传值会变得很麻烦,所以可以使用vuex管理,并且vuex是响应式的

  5.ajax请求放在action还是methods

    如果ajax请求的数据,多个组件都需要用的话,那就放在actions,如果只是组件单独使用,就放在methohs,避免数据混乱。

            

 

posted @ 2021-03-01 10:35  半糖也甜吖  阅读(437)  评论(0编辑  收藏  举报