vuex 的使用详解
一、vuex 概述
(一)组件之间共享数据的方式
但是这三种方案,只适合小范围的数据共享,如果我们需要频繁的大范围的进行组件之间的数据共享,那么我们就适合使用 vuex
(二)vuex 是什么
主要实现数据共享
状态值的就是 vuex 中所要共享的全局数据
vuex 就是实现组件之间共享数据的方案
(三)使用 vuex 的好处
(四)什么样的数据适合存储到 vuex 中
二、vuex 的基本使用
先使用 vue ui 图形界面来创建项目
store下的 index.js
入口文件 main.js
三、计时器(项目结构)
使用定时器案例来学习vuex的具体使用
Addition.vue
<template>
<div>
<p>当前的count值为: </p>
<button>+1</button>
</div>
</template>
<script>
export default {
data(){
return{};
}
}
</script>
Subtraction.vue
<template>
<div>
<p>当前的count值为: </p>
<button>-1</button>
</div>
</template>
<script>
export default {
data(){
return{};
}
}
</script>
App.vue
<template>
<div id="app">
<Addition/>
<p>------------------------------</p>
<Subtraction/>
</div>
</template>
<script>
import Addition from './components/Addition.vue'
import Subtraction from './components/Subtraction.vue'
export default {
name: 'app',
components: {
Addition,
Subtraction
}
}
</script>
四、vuex 的核心概念
五、State
1. 组件访问State 中数据的方式一
如下:
Addition.vue
<div>
<p>当前的count值为:{{$store.state.count}} </p>
<button>+1</button>
</div>
2. 组件访问 State 中数据的方式二
导入后需要在 export 中定义一计算属性computed
然后在计算属性中调用 导入的mapState函数,函数里面放入一个数组,数组中存放的是你需要映射,或者需要使用全局的哪个数据,那么就把数据名称放到里面,之后需要在前面放上三个点... 代表着展开运算符,全局里面的数据,映射为我当前组件的一个计算属性,可以认为当前的 count 就是计算属性的一个值
六、Mutation
需求: 在 Addition组件中,点击 +1 让count 值不断的 +1
<template>
<div>
<p>当前的count值为:{{$store.state.count}} </p>
<button @click="add">+1</button>
</div>
</template>
<script>
export default {
data(){
return{};
},
methods:{
add(){
this.$store.state.count++
}
}
}
</script>
这种方式虽然实现了我们的需求,但是,是错误的,因为在vuex 中,不允许直接去修改组件全局的数据,这种代码完全是不合法的
(一)Mutation的作用
如果是通过 this.$store.state.count++ 去写代码,如果项目越写越大,最终state里面的count 发生了变化,如果此时,你想要去查看谁修改了其中的数据,会很麻烦,不方便维护,如果使用 mutation里面的函数来修改 state 中的函数的话,如果发现 state中的数据有问题,可直接通过 mutation发现问题
(二)触发 Mutation 函数的第一种方式
1. Mutation 传递一个参数
store下的 index.js
Addition.vue
2. Mutation 传递两个参数
栗子:
效果:
(三)触发 Mutation 的第二种方式
栗子:
store下的 index.js
Subtraction.vue
同样,Mutation 中可以传递参数
Subtraction.vue
index.js
效果:
七、Action
需求:点击按钮+1,等待1秒后再让count值加1
虽然页面中的效果展示正确了,但是实际上 state中的 count 还是 0,没有发生变化
所以我们知道 在 mutation 函数中,不要执行异步的操作
那么,如果我们就想要在 vuex 中执行异步操作呢???
栗子:
store下的 index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0
},
mutations: {
//加一
jiayi(state){
state.count++
//加N
jiaN (state,step){
state.count+=step
},
//减一
jianyi(state){
state.count--
},
//减去N
jianN(state,step){
state.count-=step
}
},
actions: {
//实现异步加一
addAsync(context){
//context 相当于 new 出来的 vuex.store实例对象
setTimeout(()=>{
context.commit('jiayi')
//actions中不能直接去修改 state中的数据
//如果想要修改必须通过context.commit()去触发mutation中的某个方法才行
},1000)
}
},
modules: {
}
})
Addition.vue
<template>
<div>
<p>当前的count值为:{{$store.state.count}} </p>
<button @click="add">+1</button>
<button @click="addN">+N</button>
<button @click="addAy">+1 Async</button>
</div>
</template>
<script>
export default {
data(){
return{};
},
methods:{
add(){
this.$store.commit('jiayi')
},
addN(){
this.$store.commit('jiaN',4)
},
addAy(){
this.$store.dispatch('addAsync')
}
}
}
</script>
效果:
总结:
1.如果想要修改 state中的数据,只有 mutations才有权力
2.但是mutation里面执行异步操作的话,页面能正常显示,但是实际state中的数据并没有改变
3.所以需要使用 actions 里面去执行异步操作,但是actions实际是在mutation的基础上去实现异步操作更改数据,它本身是不能更改state中的数据的
4.actions中的参数context相当于 new 出来的 store实例对象
(一) 触发actions 异步任务时携带参数
(二)触发Actions 异步任务的第二种方式
栗子:
Subtraction.vue
<template>
<div>
<p>当前的count值为:{{count}} </p>
<button @click="sub">-1</button>
<button @click="subN">-N</button>
<button @click="subAy">-Async</button>
</div>
</template>
<script>
//1.导入 mapState
import {mapState} from 'vuex'
//a.导入 mapMutations
import {mapMutations} from 'vuex'
//导入 mapActions
import {mapActions} from 'vuex'
export default {
data(){
return{};
},
//2.定义一个计算属性
computed:{
...mapState(['count'])
},
methods:{
//b.定义 mapMutations 方法
...mapMutations(['jianyi','jianN']),
...mapActions(['jianAsync']),
sub(){
this.jianyi()
},
subN(){
this.jianN(3)
},
subAy(){
this.jianAsync()
}
}
}
</script>
或者直接把 button 的click函数等于 mapActions 的函数名
<!-- <button @click="subAy">-Async</button> -->
<button @click="jianAsync">-Async</button>
八、Getter
(一)使用 Getter的第一种方式
栗子:
store下面的 index.js
Addition.vue
(二) 使用 Getter的第二种方式
Subtraction.vue
<!-- <p>当前的count值为:{{count}} </p> -->
<p>{{getNum}}</p>
//导入 mapGetters
import {mapGetters} from 'vuex'
computed:{
...mapState(['count']),
...mapGetters(['getNum'])
},