03基于 Vue2.x 的 Vuex3.x .

前言

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

注意安装命令如下:

npm i vuex@3

简单示例

main.js 注入

import store from './store'
new Vue({
  el: '#app',
  store
})

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: {
  }
})

计算属性中使用

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
		},
	}
}

核心概念

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

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

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

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

State

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

方式一

函数

computed: {
	count() {
		return this.$store.state.count;
	}
}
方式二

get 函数

computed: {
	count: {
		get() {
			return this.$store.state.count;
		}
	}
}
方式三

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

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

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

import { mapState } from 'vuex'
computed: {
	// mapState 对象方式
	...mapState({
		count: state => state.count
	})
}

Getters

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

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

使用 $store.getters 对象

this.$store.getters.getVisible

Mutation

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

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

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

定义
export default new Vuex.Store({
  state: {
    // 是否显示
    visible: true
  },
  mutations: {// 同步操作,可修改
    setVisible (state, value) {
        state.visible = value
    },
  }
})
调用
this.$store.commit('setVisible', false)

Actions

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

actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}
store.dispatch('actionA').then(() => {
  // ...
})

Modules

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

└── src
    └── store
        ├── modules(可有多个js)
        │   ├── user.js
        │   └── info.js
        ├── getters.js
        └── index.js

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
}

getters.js

const getters = {
    // TODO 
}
export default getters

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

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')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值