Vuex的基础使用

引入vuex

安装依赖:npm install vuex --save
src目录下的store文件夹创建index.js

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(vuex);
//不是生产环境debug为true
const debug = process.env.NODE_ENV !== 'production';
//创建vuex实例对象
const store = new Vuex.Store({
	strict: debug,//在不是生产环境下开启严格模式
	state:{
	},
	getters:{
	},
	mutations:{
	},
	actions:{
	}
})
export default store;

再在main.js中引入Vuex

import Vue from 'vue';
import App from './App.vue';
import store from './store';
const vm = new Vue({
	store: store,
	render: h => h(App)
}).$mount('#app')

Vuex的核心属性

state, getters, mutations. actions, modules

State

Vuex中状态都存储state中,改变状态的唯一路径是提交mutation(e.g: this.$store.commit('SET_NUMBER', 10))。

当Vuex中存储的状态是对象数据类型时,需要先使用 JSON.stringify(objName)将对象转换为字符串形式,再进行存储(e.g:
this.$store.commit('createUser', JSON.stringify(user)), 在获取到对象数据类型时,再通过JSON.parse()进行转换。

批量使用Vuex的state状态 -> 使用mapState辅助函数

import {mapState} from 'vuex'
export default{
	computed:{
		...mapState(['price','number'])
	}
}

Getters

主要用于提供给多个组件state的派生状态,getter接收两个参数,一个是state(局部的state),第二个是getter(可以用来访问其他的getter),如果想要访问全局的getter和state,可以使用getter的第三个参数rootState以及第四个参数rootGetters
使用方法如下:

const store = new Vuex.Store({
	state: {
		price: 10,
		number: 10,
		discount: 0.7,
		todos: [
			{id: 1, text: '...', done: true},
			{id: 1, text: '...', done: true},
		]
	},
	getters: {
		total: state => {
			return state.total * state.number;
		},
		discountTotal: (state,getters) => {
			return state.discount * getters.total;
		},
		// 可以通过给getter传值的方式获取特定的state
		getTodoById: (state) => (id) => {
			return state.todos.find(todo=>todo.id === id)
		}
	}
})

可以在组件中通过计算属性computed通过this.$store.getters.total这样来访问这些getters派生的state。

computed: {
	total(){
		return this.$store.getters.total;
	},
	discountTotal(){
		return this.$store.getters.discountTotal;
	}//使用和普通getters相同的方法进行引用
	getTodoById(){
		return this.$store.getters.getTodoById;
	}
}
mounted(){
	// 输出state中todos一个index的done属性
	console.log(this.getTodoById(1).done)//false
}

批量使用Vuex的getters -> 使用mapGetters辅助函数

import {mapGetters} from 'vuex'
export default{
	computeds: {
		...mapGetters(['total','discountTotal'])
		// 如果需要给getters属性取别名
		//...mapGetters({
		//	myTotal: 'total',
		//	myDiscountTotal: 'discount
		//})
	}
}

Mutations

用于改变state中的某个状态,必须是同步函数,只有mutation中的函数能够直接变更某个状态,mutation函数的第一个值是state(局部的state,及模块的state),第二个值是data。

const store = new Vuex.Store({
	state: {
		number: 30,
	},
	mutations: {
		SET_NUMBER(state,data){
			state.number = data;
		}
	}
})

在组件中使用this.$store.commit提交mutation,改变state中的number属性。

this.$store.commit('SET_NUMBER',10)
// 如果在组件中我们会多次提交同一个,可以借助mapMutation辅助函数
import { mapMutations } from 'vuex'
methods: {
	...mapMutations({
		setNumber: 'SET_NUMBER'
	})
}
//然后调用方法也变得更加简洁
this.setNumber(10)

Actions

action与mutation的不同之处:
①action是提交mutation,只能间接地修改state中的属性,而mutation可以直接变更state;
②action可以是异步的(通常是异步的),而mutation只能是同步的;
③action通过this.$store.dispatch(‘ACTION_NAME’,data)进行提交,而mutation通过this.$store.commit(‘MUTATION_NAME’,data)进行提交;
④action第一个参数是context而mutation是state。
action与mutation的相同之处:
dispatch和commit的第二个参数都可以接受外部提交时传递的参数。

actions: {
	SET_NUMBER_A({commit},data){
		return new Promise((resolve,reject)=>{
			setTimeout(()=>{
				commit('SET_NUMBER',10);
				resolve();
			},2000)
		})
	},
	//如果一个异步操作的action需在另一个action结束处理后再操作,试下方法如下
	async actionA({commit}){
		//...
	},
	async actionB({dispatch}){
		await dispatch('actionA')//等待actionA完成
	}
}
//在组件中通过dispatch调用
this.$store.dispatch('SET_NUMBER_A').then(()=>{
	//...
})
//也可以借助mapActions辅助函数
methods:{
	...mapActions({
		setNumberA: 'SET_NUMBER_A',
	})
}
//可以直接使用setNumber进行调用
this.setNumberA().then(()=>{
	//...
})

Modules

如果所有状态集成在一个对象,当状态属性过多时,store对象就会变得非常臃肿,所以将store分割成模块(module)。每个模块拥有独立的state、mutations、actions、getters。

const state = {
	//...
}
const getters = {
	//...
}
const mutations ={
	//...
}
const actions = {
	//...
}
export default{
	state,
	getters,
	mutations,
	actions
}

再在index.js引入模块

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
import moduleA from './module/moduleA';
import moduleB from './module/moduleB';
const store = new Vuex.Store({
	modules:{
		moduleA,
		moduleB,
	}
});
export default store

命名空间

默认情况下,模块内部的action、mutation和getter是注册在全局命名空间,如果多个模块中action、mutation的命名是一样的,那么提交mutation、action时,将会触发所有模块中命名相同的mutation、action。为避免这种情况,在导出模块时,添加namespaced: true属性使其成为带有命名空间的模块。

export default{
	namespaced: true,
	state,
	getters,
	mutations,
	actions
}

如果需要提交在带有命名空间的模块中的mutation或者action,用如下方法:

this.$store.commit('moduleA/mutationA',data)
//将mapState,mapGetters,mapActions和mapMutations绑定到命名空间的模块
//引入createNamespaceHelpers
import { createNamespacedHelpers } from 'vuex';
const { mapState, mapActions } = createNamespacedHelpers('moduleA');
export default {
    computed: {
        // 在 `module/moduleA` 中查找
        ...mapState({
            a: state => state.a,
            b: state => state.b
        })
    },
    methods: {
        // 在 `module/moduleA` 中查找
        ...mapActions([
            'actionA',
            'actionB'
        ])
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值