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),这时就有了一个多组件共享状态的概念。
- 多个视图依赖于同一状态
- 来自不同视图的行为需要变更同一状态
- 以前的解决办法
a. 将数据以及操作数据的行为都定义在父组件
b. 将数据以及操作数据的行为传递给需要的各个子组件(有可能需要多级传递) - 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
name:''
,
computedVuex概述及核心概念