Vuex 核心概念基本使用 及 求和案例

Posted YuLong~W

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vuex 核心概念基本使用 及 求和案例相关的知识,希望对你有一定的参考价值。

Vuex

概念

在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的 共享状态 进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

何时使用:多个组件需要共享数据时

Vuex 实现了一个单向数据流,在全局拥有一个 State 存放数据,当组件要更改 State 中的数据时,必须通过 Mutation 进行,Mutation 同时提供了订阅者模式供外部插件调用获取 State 数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走 Action,但 Action 也是无法直接修改 State 的,还是需要通过 Mutation 来修改 State 的数据。最后,根据 State 的变化,渲染到视图上。

1、状态自管理应用(单向数据流)

  • state: 驱动应用的数据源,数据源就是组件里面的data
  • view: 以声明方式将 state 映射到视图
  • actions: 响应在 view的用户输入导致的状态变化。actions说白了就是多个函数

2、初始化显示: View(组件,也就是模板页面)读取State(状态)

3、更新显示: 更新的起始点为 View,它通过事件触发调用 Actions 里面的某一个函数,然后Actions 去更新 State 的状态数据。State 更新之后,View 的界面也会随之改变

4、多组件共享状态的问题

比如说,当用户登录之后,用户的个人中心页面上有三个组件都需要获取到用户的登录状态(isLogin),这时就有了一个多组件共享状态的概念。

  1. 多个视图依赖于同一状态
  2. 来自不同视图的行为需要变更同一状态
  3. 以前的解决办法
    a. 将数据以及操作数据的行为都定义在父组件
    b. 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递)
  4. vuex 就是用来解决这个问题的

相关对象:


1、state

vuex 管理的状态对象,它是唯一的

const state = 
   xxx: initValue


2、 mutations

包含多个直接更新 state 的方法(回调函数)的对象

谁来触发: action 中的 commit('mutation名称')

只能包含同步的代码, 不能写异步代码

const mutations = 
  yyy (state, data1) 
      // 更新 state 的某个属性
  


3、 actions

包含多个事件回调函数的对象

通过执行 commit()来触发 mutation 的调用,间接更新 state

谁来触发: 组件中: $store.dispatch('action名称', data1) // 'zzz

可以包含异步代码(axios)

const actions =
   zzz (commit, state, data1)
      commit('yyy', data1)
   


4、 getters

包含多个计算属性(get)的对象 (也就是说,getters是用来放state里面的变量的计算属性的)

谁来读取: 组件中: $store.getters.xxx

const getters =
   mmm (state) 
       return ...
   


5、 modules

包含多个 module,一个 module 是一个 store 的配置对象,与一个组件(包含有共享数据)对应


工作流程

流程:View -> Actions -> Mutations -> State -> View

流程详解:

① 在组件(页面)中,通过 dispatch()mapActions() 这个函数分发给actions的函数去处理。

② actions的函数可以与后台交互,也可以通过 commit()提交给mutations去处理。

③ mutations 可以直接与devtool交互与直接更新 state(数据状态)。

④ 如果有计算属性(get函数写在getters里面),则状态通过getters的$store.getters()mapGetters()来更新组件;反之就通过$store.state()或者mapState()的方式来更新组件。

搭建vuex环境

1、创建文件:src/store/index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = 
//准备mutations对象——修改state中的数据
const mutations = 
//准备state对象——保存具体的数据
const state = 

//创建并暴露store
export default new Vuex.Store(
	actions,
	mutations,
	state
)

2、在main.js中创建vm时传入store配置项

......
//引入store
import store from './store'
......

//创建vm
new Vue(
	el:'#app',
	render: h => h(App),
	store
)

基本使用

1、初始化数据、配置actions、配置mutations,操作文件store.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)

const actions = 
    //响应组件中加的动作
	jia(context,value)
		context.commit('JIA',value)
	,


const mutations = 
    //执行加
	JIA(state,value)
		state.sum += value
	


//初始化数据
const state = 
   sum:0


//创建并暴露store
export default new Vuex.Store(
	actions,
	mutations,
	state,
)

2、组件中读取vuex中的数据:$store.state.sum

3、组件中修改vuex中的数据:

  • $store.dispatch('action中的方法名',数据)
  • $store.commit('mutations中的方法名',数据)

备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

求和案例

效果展示:

实现代码:

main.js文件:

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入store
import store from './store'

//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue(
	el:'#app',
	render: h => h(App),
	store,
)

App.vue文件:

<template>
	<div>
		<Count/>
	</div>
</template>

<script>
	import Count from './components/Count'
	export default 
		name:'App',
		components:Count,
	
</script>

components文件夹下Count.vue文件:

<template>
	<div>
		<h1>当前求和为:$store.state.sum</h1>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment">+</button>
		<button @click="decrement">-</button>
		<button @click="incrementOdd">当前求和为奇数再加</button>
		<button @click="incrementWait">等一等再加</button>
	</div>
</template>

<script>
	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		methods: 
			increment()
				this.$store.commit('JIA',this.n)
			,
			decrement()
				this.$store.commit('JIAN',this.n)
			,
			incrementOdd()
				this.$store.dispatch('jiaOdd',this.n)
			,
			incrementWait()
				this.$store.dispatch('jiaWait',this.n)
			,
		,
		mounted() 
			console.log('Count',this)
		,
	
</script>

<style lang="css">
	button
		margin-left: 5px;
	
</style>

store文件夹下index.js文件:

//该文件用于创建Vuex中最为核心的store
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions——用于响应组件中的动作
const actions = 
	/* jia(context,value)
		console.log('actions中的jia被调用了')
		context.commit('JIA',value)
	,
	jian(context,value)
		console.log('actions中的jian被调用了')
		context.commit('JIAN',value)
	, */
	jiaOdd(context,value)
		console.log('actions中的jiaOdd被调用了')
		if(context.state.sum % 2)
			context.commit('JIA',value)
		
	,
	jiaWait(context,value)
		console.log('actions中的jiaWait被调用了')
		setTimeout(()=>
			context.commit('JIA',value)
		,500)
	

//准备mutations——用于操作数据(state)
const mutations = 
	JIA(state,value)
		console.log('mutations中的JIA被调用了')
		state.sum += value
	,
	JIAN(state,value)
		console.log('mutations中的JIAN被调用了')
		state.sum -= value
	

//准备state——用于存储数据
const state = 
	sum:0 //当前的和


//创建并暴露store
export default new Vuex.Store(
	actions,
	mutations,
	state,
)

getters的使用

概念:当state中的数据需要经过加工后再使用时,可以使用getters加工。

1、在store.js中追加getters配置:

......

const getters = 
	bigSum(state)
		return state.sum * 10
	


//创建并暴露store
export default new Vuex.Store(
	......
	getters
)

2、组件中读取数据:$store.getters.bigSum

四个map方法的使用

1、mapState方法:用于帮助我们映射state中的数据为计算属性

computed: 
    //借助mapState生成计算属性:sum、school、subject(对象写法)
     ...mapState(sum:'sum',school:'school',subject:'subject'),
         
    //借助mapState生成计算属性:sum、school、subject(数组写法)
    ...mapState(['sum','school','subject']),
,

2、mapGetters方法:用于帮助我们映射getters中的数据为计算属性

computed: 
    //借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters(bigSum:'bigSum'),

    //借助mapGetters生成计算属性:bigSum(数组写法)
    ...mapGetters(['bigSum'])
,

3、mapActions方法:用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

methods:
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions(incrementOdd:'jiaOdd',incrementWait:'jiaWait')

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])

4、mapMutations方法:用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

methods:
    //靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations(increment:'JIA',decrement:'JIAN'),
    
    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['JIA','JIAN']),

备注:mapActions与mapMutations使用时,若需要 传递参数 需要:在模板中绑定事件时传递好参数,否则参数是事件对象。

多组件共享数据案例

实现效果:

实现代码:

App.vue文件:

<template>
	<div>
		<Count/>
		<hr>
		<Person/>
	</div>
</template>

<script>
	import Count from './components/Count'
	import Person from './components/Person'

	export default 
		name:'App',
		components:Count,Person,
	
</script>

components文件夹下Count.vue文件:

<template>
	<div>
		<h1>当前求和为:sum</h1>
		<h3>当前求和放大10倍为:bigSum</h3>
		<h3>我在school,学习subject</h3>
		<h3 style="color:red">Person组件的总人数是:personList.length</h3>
		<select v-model.number="n">
			<option value="1">1</option>
			<option value="2">2</option>
			<option value="3">3</option>
		</select>
		<button @click="increment(n)">+</button>
		<button @click="decrement(n)">-</button>
		<button @click="incrementOdd(n)">当前求和为奇数再加</button>
		<button @click="incrementWait(n)">等一等再加</button>
	</div>
</template>

<script>
	import mapState,mapGetters,mapMutations,mapActions from 'vuex'
	export default 
		name:'Count',
		data() 
			return 
				n:1, //用户选择的数字
			
		,
		computed:
			//借助mapState生成计算属性,从state中读取数据。(数组写法)
			...mapState(['sum','school','subject','personList']),
			//借助mapGetters生成计算属性,从getters中读取数据。(数组写法)
			...mapGetters(['bigSum'])
		,
		methods: 
			//借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法)
			...mapMutations(increment:'JIA',decrement:'JIAN'),
			//借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法)
			...mapActions(incrementOdd:'jiaOdd',incrementWait:'jiaWait')
		,
	
</script>

<style lang="css">
	button
		margin-left: 5px;
	
</style>

components文件夹下Person.vue文件:

<template>
	<div>
		<h1>人员列表</h1>
		<h3 style="color:red">Count组件求和为:sum</h3>
		<input type="text" placeholder="请输入名字" v-model="name">
		<button @click="add">添加</button>
		<ul>
			<li v-for="p in personList" :key="p.id">p.name</li>
		</ul>
	</div>
</template>

<script>
	import nanoid from 'nanoid'
	export default 
		name:'Person',
		data() 
			return 
				nameVuex概述及核心概念

Vuex概述及核心概念

Vuex概述及核心概念

Vue全家桶之Vuex

Redux 知识点 及 使用案例

简述Vuex(重要)