Vuex简单入门

一.什么是Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理架构。它借鉴了 Flux 和 Redux的设计思想,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。。状态?理解为在data中的属性需要共享给其他vue组件使用的部分,就叫做状态。简单的说就是data中需要共用的属性。

二.Vuex的组成部分

完整的应用Vuex开发的应用结构应该是这样的:

简单的理解:当vue组件(vue components)发生变化的(比如用户触发点击事情,需要改变vuex状态)——》通过dispatch提交action(这里面会很多的函数,需要dispatch触发这里的事情函数)——》通过 store.commit 方法触发状态变更(mutation的方法)  ——》mutation改变state状态——》state状态改变之后,getter映射渲染vue 组件  

案例GitHub

1.State

State负责存储整个应用的状态数据,一般需要在使用的时候在跟节点注入store对象,后期就可以使用this.$store.state直接获取状态

//store为实例化生成的
import store from './store'

new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

这个store可以理解为一个容器,包含着应用中的state等。实例化生成store的过程是:

const mutations = {...};
const actions = {...};
const state = {...};

Vuex.Store({
  state,
  actions,
  mutation
});

后续在组件中使用的过程中,如果想要获取对应的状态你就可以直接使用this.$store.state获取,当然,也可以利用vuex提供的mapState辅助函数将state映射到计算属性中去(当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组),如

//我是组件
import {mapState} from 'vuex'
export default {
  computed: mapState({
    count: state => state.count
  })
}

2.Mutations

Mutations的中文意思是“变化”,利用它可以更改状态,本质就是用来处理数据的函数,其接收唯一参数值state。store.commit(mutationName)是用来触发一个mutation的方法。需要记住的是,定义的mutation必须是同步函数,否则devtool中的数据将可能出现问题,使状态改变变得难以跟踪。

const mutations = {
  mutationName(state) {
    //在这里改变state中的数据
  }
}
在组件中触发:
//我是一个组件
export default {
  methods: {
    handleClick() {
      this.$store.commit('mutationName')
    }
  }
}
或者使用辅助函数mapMutations直接将触发函数映射到methods上,这样就能在元素事件绑定上直接使用了。如:
import {mapMutations} from 'vuex'
//我是一个组件
export default {
  methods: mapMutations([
    'mutationName'
  ])
}

 Vuex之理解mutation的用法

3.Actions

Actions也可以用于改变状态,不过是通过触发mutation实现的,重要的是可以包含异步操作。其辅助函数是mapActions与mapMutations类似,也是绑定在组件的methods上的。如果选择直接触发的话,使用this.$store.dispatch(actionName)方法。

//定义Actions
const actions = {
  actionName({ commit }) {
    //dosomething
    commit('mutationName')
  }
}
在组件中使用

import {mapActions} from 'vuex'
//我是一个组件
export default {
  methods: mapActions([
    'actionName',
  ])
}

Vuex之理解action的用法

4.Getters

有些状态需要做二次处理,就可以使用getters。通过this.$store.getters.valueName对派生出来的状态进行访问。或者直接使用辅助函数mapGetters将其映射到本地计算属性中去。

const getters = {
  strLength: state => state.aString.length
}
//上面的代码根据aString状态派生出了一个strLength状态
在组件中使用

import {mapGetters} from 'vuex'

//我是一个组件
export default {
  computed: mapGetters([
    'strLength'
  ])
}

Vuex之理解Getters的用法

5.Plugins

插件就是一个钩子函数,在初始化store的时候引入即可。比较常用的是内置的logger插件,用于作为调试使用。

import createLogger from 'vuex/dist/logger'
const store = Vuex.Store({
  ...
  plugins: [createLogger()]
})

三.mapGetters, mapMutations, mapActions, mapState 的使用

1. store 文件下

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import VuexPersist from 'vuex-persist'
import user from './modules/user'
import getters from './getters'

Vue.use(Vuex)

const vuexLocal = new VuexPersist({
	storage: window.sessionStorage //可选,sessionStorage/indexDB/localStorage
});
export default new Vuex.Store({
	state: {
		token:"1833737"
	},
	modules: {
		user
	},
	mutations: {
	},
	actions: {
	},
	getters,
	plugins: [vuexLocal.plugin]
})

 store/getters.js

const getters = {
   name: state => state.user.name
  }
  
  export default getters
  

 store/modules/user.js

 

const user = {
	state: {
		name:"王一涵"
	},

	mutations: {
		SET_NAME: (state, name) => {
			state.name = name
		}
	},

	actions: {
		setName({ commit },data) {
			return new Promise((resolve, reject) => {
				commit('SET_NAME', data)
			})
		},
	}
}

export default user

2. 组件

 

<template>
    <div id="app">
        <button @click="fn">按钮</button>
    </div>
</template>
<script>
import { mapGetters, mapMutations, mapActions, mapState } from "vuex";
export default {
    name: "App",
    components: {
    },
    data() {
        return {
            
        };
    },
    created() {},
    mounted() {
        console.log("开始:", this.$store.getters.name);
    },
    computed: {
        // ...mapGetters(["name"]),
        ...mapState({
            token: "token",
            name:state=> state.user.name,// 指定modules里的
        }),
    },
    created: function () {},
    methods: {
        // ...mapMutations(["SET_NAME"]),
        ...mapActions(["setName"]),
        fn() {
            console.log("token:", this.token);
            // this.SET_NAME("张翰");// mapMutations的方法

            this.setName("迪丽热巴");// mapActions的方法

            console.log("点击", this.name);//mapState mapGetters 访问
        },
    },
};
</script>
<style lang="scss">

</style>

四.demo

1.简单触发mutation

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

// 引入actions, mutations, getters
import mutations from "./mutations.js"
//state:是容器
const state = {
	count:10,
	name:"jack"
}
export default new Vuex.Store({
	state,
	mutations
})

index.vue

<template>
	<div>
		<h1>Vuex小demo</h1>
		<div>测试1:Count is {{count}}</div>
		<div>用户名:{{name}}</div>
		<button @click="add">+</button>  
        <button @click="dec">-</button> 
         <button @click="updata">改变用户名</button>  
	</div>
</template>
<script>
export default {
	computed:{  
        count(){  
        	//通过 store.state 来获取状态对象  
            return this.$store.state.count;
        },
        name(){
        	return this.$store.state.name;
        } 
    }, 
	methods: {
		add(){
			 //通过 store.commit 方法触发状态变更(mutation的方法)   
            this.$store.commit('increment');  
		},
		dec(){
 			this.$store.commit('decrement');
		},
		updata(){
			//传参数
			this.$store.commit('updataName','修小龙'); 
		}

	}
}
</script>

mutations.js模块

/*
*mutations:状态改变操作方法。是vuex修改state的唯一推荐方法,
*/
export default {
 //对state进行操作
	increment:(state) =>{
		return state.count ++;
	},
	decrement:(state) =>{
		return state.count--;
	},
	updataName:(state,userName) =>{
		state.name = userName;
	}
} 

从上面可以简单案例一般组件改变的事件 直接触发mutation方法 进行修改state。

2.加上action

store.js:引入action.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

// 引入actions, mutations, getters
import actions from "./actions.js"
import mutations from "./mutations.js"

//state:是容器
const state = {
	count:10,
	name:"jack"
}

export default new Vuex.Store({
	state,
	actions,
	mutations
})

在index.vue:改变add方法

add(){
			 //通过 store.dispatch方法触发状态变更(action创建函数的方法)   
           this.$store.dispatch('incrementAction');
		},

action.js

//action 模块
/*action:操作行为处理模块。负责处理vue 组件接受到所有交互行为。包含同步/异步操作,支持多个同名方法,按照注册的顺序依次触发。
向后台api请求的操作就在这个模块中进行,包括触发其他action以及提交mutation的操作。该模块提供了,promise的封装,以支持action的链式触发

*通过commit提交
commit:状态改变提交方法。对mutetion进行提交,是唯一能执行mutation的方法

*dispatch:操作行触发方法,是唯一能执行action的方法
*action不能直接操作state
*/

export default {
	incrementAction:(context) =>{
		context.commit('increment');
	}
}

效果也是跟上面一样。加上action后,组件改变事情 触发action函数(通过dispatch触发action),action函数里面触发mutation(还是用commit来触发)

action简单的操作是可以不用,具体情况具体分析。

3.加上getters(辅助性,在基层上进行延伸的操作)

store.js

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)


// 引入actions, mutations, getters
import actions from "./actions.js"
import mutations from "./mutations.js"
import getters from "./getters.js"

//state:是容器
const state = {
	count:10,
	name:"jack"
}

export default new Vuex.Store({
	state,
	actions,
  	getters,
	mutations
})	count:10,
	name:"jack"
}

export default new Vuex.Store({
	state,
	actions,
  	getters,
	mutations
})

index.vue

<template>
	<div>
		<h1>Vuex小demo</h1>
		<div>测试1:Count is {{count}}</div>
		<div>用户名:{{name}}</div>
		<div>通过getters改变用户名:{{userName}}</div><button @click="add">+</button>  
        <button @click="dec">-</button> 
         <button @click="updata">改变用户名</button>  
	</div>
</template>
<script>
export default {
	computed:{  
        count(){  
        	//通过 store.state 来获取状态对象  
            return this.$store.state.count;
        },
        name(){
        	return this.$store.state.name;
        },
        userName(){
        	return this.$store.getters.userName;
        }
    }, 
	methods: {
		add(){
			 //通过 store.dispatch方法触发状态变更(action创建函数的方法)   
           this.$store.dispatch('incrementAction');
		},
		dec(){
 			this.$store.commit('decrement');
		},
		updata(){
			//传参数
			this.$store.commit('updataName','修小龙'); 
		}

	}
}
</script>

getters.js

//getters 模块
/*
*getters:state对象读取方法。图中没有单独列出该模块,应该被包含在render中,组件通过该方法this.$store.getters.userName 直接读取全局state对象
而不需要去触发mutation函数

*/
export default {
	userName:(state) =>{
		return state.name + ',Hello';
	}
}

在之前的基层store中name上加上Hello,getters跟其他都没有关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值