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,避免数据混乱。