• 03基于 Vue2.x 的 Vuex3.x .


    前言

    本文是基于 Vue2.x 的 Vuex3.x 版。如果是 Vue3.x 则对应 Vuex4.x

    注意安装命令如下:

    npm i vuex@3
    
    • 1

    简单示例

    main.js 注入

    import store from './store'
    new Vue({
      el: '#app',
      store
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5

    src/store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
     
    Vue.use(Vuex)
     
    export default new Vuex.Store({
      state: {
        // 是否显示
        visible: true
      },
      mutations: {// 同步操作,可修改
        setVisible (state, value) {
            state.visible = value
        },
      },
      getters: {// 可以认为是 store 的计算属性
        getVisible(state) {
          return state.visible;
        }
      },
      actions: {// 异步操作,不可修改,交给mutations 
        setVisibleAction ({commit},payload) {
          commit("setVisible",payload)
        },
      },
      modules: {
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    计算属性中使用

    computed: {
    	close: {
    		set (value) {
    			/ 两种方式,1. commits是同步;2. dispatch 是异步
    			// return this.$store.commit('setVisible', value)
    			return this.$store.dispatch('setVisibleAction', value)
    		},
    		get () {
                // 两种方式,1. getter;2. state
    			// return this.$store.getters.getVisible
    			return this.$store.state.visible
    		},
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    核心概念

    mapState 辅助函数帮助我们生成计算属性

    mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性;

    mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store);

    mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store);

    State

    Vuex 使用单一状态树,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态。有如下四种常用方式:

    方式一

    函数

    computed: {
    	count() {
    		return this.$store.state.count;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    方式二

    get 函数

    computed: {
    	count: {
    		get() {
    			return this.$store.state.count;
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    方式三

    mapState 对象方式。注意在 .vue 文件中要 import

    import { mapState } from 'vuex'
    
    • 1
    computed: mapState({
    	count: state => state.count
    })
    
    • 1
    • 2
    • 3
    方式四

    mapState 数组方式。注意在 .vue 文件中要 import

    import { mapState } from 'vuex'
    
    • 1
    computed: {
    	// mapState 对象方式
    	...mapState({
    		count: state => state.count
    	})
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    Getters

    此处就不举例说明了,详见官网说明。官网有如下解释,请仔细阅读理解:

    Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

    使用 $store.getters 对象

    this.$store.getters.getVisible
    
    • 1

    Mutation

    • 改变 store 的状态,唯一的方法是提交 mutation。且mutation 必须是同步函数

    • 建议第二个参数是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读;

    • 建议 使用常量替代 Mutation 事件类型

    定义
    export default new Vuex.Store({
      state: {
        // 是否显示
        visible: true
      },
      mutations: {// 同步操作,可修改
        setVisible (state, value) {
            state.visible = value
        },
      }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    调用
    this.$store.commit('setVisible', false)
    
    • 1

    Actions

    store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise:

    actions: {
      actionA ({ commit }) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            commit('someMutation')
            resolve()
          }, 1000)
        })
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    store.dispatch('actionA').then(() => {
      // ...
    })
    
    • 1
    • 2
    • 3

    Modules

    模块具有更高的封装度和复用性。通过添加 namespaced: true 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。
    目录结构如下:

    └── src
        └── store
            ├── modules(可有多个js)
            │   ├── user.js
            │   └── info.js
            ├── getters.js
            └── index.js
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    modules/user.js

    // 状态
    const state =  {
        token: getToken(),
        name: getUser()
    }
    
    // 同步设置
    const mutations = {
        // token
        SET_TOKEN: (state, token) => {
            state.token = token;
        },
        // name
        SET_NAME: (state, name) => {
            state.name = name;
        }
    }
    
    // 异步设置
    const actions = {
        // 登录
        login({ commit }, userInfo) {
            const { form, axios } = userInfo;
            return new Promise((resolve, reject) => {
                let url = '/v1/auth/login';
                axios.post(url, form).then((resp) => {
                    if (resp.succ) {
                        commit('SET_TOKEN', resp.token);//设置token
                        commit('SET_NAME', resp.user);//设置用户名
                        resolve();
                    } else {
                        reject(resp)
                    }
                });
            })
        },
        // 登出
        logout({ commit, state }) {
            // TODO
        }
    }
    
    export default {
        namespaced: true,
        state,
        mutations,
        actions
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    getters.js

    const getters = {
        // TODO 
    }
    export default getters
    
    • 1
    • 2
    • 3
    • 4

    index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import getters from './getters'
    
    Vue.use(Vuex)
    
    const modulesFiles = require.context('./modules', true, /\.js$/)
    const modules = modulesFiles.keys().reduce((modules, modulePath) => {
        const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
        const value = modulesFiles(modulePath)
        modules[moduleName] = value.default
        return modules
    }, {})
    
    const store = new Vuex.Store({
        modules,
        getters
    })
    
    export default store
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    main.js中引入,代码 3、6 行。

    import Vue from 'vue'
    import App from './App.vue'
    import store from './store'
    
    new Vue({
      store,
      render: h => h(App)
    }).$mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    Qt应用开发(基础篇)——列表视图 QListView
    论,韭菜的自我修养
    (附源码)ssm客户信息管理系统 毕业设计 281609
    java计算机毕业设计失物招领系统源程序+mysql+系统+lw文档+远程调试
    学生成绩管理系统(C语言课设 )
    救济金发放(The Dole Queue, UVa 133)rust解法
    基于STM32和ESP8266的WIFI信号检测仪
    基于matlab的长短期神经网络lstm的股票预测
    数据与视图的完美契合:Vue响应式的交织魅力
    Python random 模块
  • 原文地址:https://blog.csdn.net/sinat_31213021/article/details/126787437