前言
此文章比较适合初学者,如有什么不准确的地方欢迎大佬指正!
Vuex是什么?
官方概念:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex文档地址
Vuex官方地址
换句话说:就是帮助我们储存多个组件共享的数据,方便存取我们和修改,将数据或者状态进行集中式管理。
如何使用Vuex?
目前我们还没有引入vuex,我们需要先下载vuex,并且引入它
-
首先全局安装Vuex
npm install vuex --save
-
安装成功后就可以新建项目啦(当然现有的项目也可以)
-
在项目src目录新建store文件,在store文件夹内新建index.js文件
-
打开index.js导入Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
-
创建一个vuex实例并抛出
const store = new Vuex.Store({})
export default store
-
最后我们在main.js中导入并全局注册
import store from './store/index'
new Vue({
store,
render: h => h(App),
}).$mount('#app'
Vuex几大核心属性
大概的框架我们已经搭载完毕 现在我们来了解一下Vuex的几大核心属性吧~
Vuex有五个核心属性:
1.state
2.mutation
3.action
4.getters
5.moudle
我们来分别说一下每个属性吧~
-
state:唯一的数据源与vue实例中我们熟悉的data遵从一样的规则 获取state定义的值 $store.state.key名
-
mutation:在vuex中更改store中的状态唯一的方法就是提交mutation,这非常类似于时间 使用$store.commit(‘方法名’)触发。
-
action:action类似于mutation 但值得注意的是 action是提交mutation 并不是直接变更状态,而且action可以包含任意的异步操作。
-
getters:可以认为是 store 的计算属性,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值。
-
module 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。为了解决以上问题,Vuex 允许我们将 store 分割成模块module。
小Demo初探Vuex
属性了解之后 我们通过一个小案例一起来初探一下vuex吧~ 在此之前我们已经搭建了一个大概的框架,现在我们开始尽情的玩耍Vuex吧
-
首先我们回到index.js 在我们创建的属性中添加一个state属性,并定义一个数据
const store = new Vuex.Store({
state:{
count:0
},
})
-
接下来我们回到任意一个.vue文件中使用 $store.state.count获取在vuex定义的数据
<template>
<div id="app">
<h1>{{ $store.state.count }}</h1>
</div>
</template>
-
这时我们运行页面 就会看到神奇的一幕 在页面中就会看到我们定义的数据。
获取state中数据的第二种打开方式
-
首先从Vuex中按需导入mapState辅助函数
import { mapState,mapMutations } from 'vuex'
-
在computed属性中声明要获取的state数据
computed: {
...mapState(["count"])
},
-
在视图中进行插值表达式绑定,运行结果和上图一致。
<template>
<div id="app">
<h1>{{count }}</h1>
</div>
</template>
mutation修改数据
到这里我们回想一下 首先安装vuex 创建store实例并抛出去 在main.js引入 并使用 $store.state.key 名在页面中使用了数据 那么我们要如何修改数据呢? 前面说过 更改 store 中的状态的唯一方法就是提交 mutation 那么我们来尝试一下吧。
-
在我们的刚刚.vue文件中新增两个按钮:
<template>
<div id="">
<button>+</button>
<h1>{{ $store.state.count }}</h1>
<button>-</button>
</div>
</template>
-
回到store文件夹下的index.js 在刚刚创建的实例中加入mutation属性 该方法接收两个参数,默认接收state为第一个参数,另一个为自定义参数 我们在mutation中定义两个方法:
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
},
});
-
定义完成回到.vue文件 如何使用mutation呢,其实就和我们自定义事件非常相似 还记得如何触发mutation吗 使用$store.commit(‘方法名’)
<template>
<div id="">
<button [@click](/user/click)="increment()">+</button>
<h1>{{ $store.state.count }}</h1>
<button [@click](/user/click)="decrement()">-</button>
</div>
</template>
methods: {
increment() {
this.$store.commit("increment");
},
decrement() {
this.$store.commit("decrement");
},
},
此时我们来浏览器看一下,我们点击按钮会发现数据变化了!成功触发了mutation~
Mutation 参数传递
前面说过每个mutation都会默认接收state作为第一个参数,除此之外还可以接收我们动态传递过去的参数,以刚才的例子为例,现在我们点击按钮式传递一个参数,让state动态增加或减少我们所传递过去的参数。
-
同样在页面中新增两个按钮
<template>
<div id="app">
<button [@click](/user/click)="add()">+</button>
<button>+N</button>
{{ count }}
<button>-N</button>
<button [@click](/user/click)="reduce()">-</button>
</div>
</template>
-
回到store文件夹下的index.js mutations 写入方法,方法中第一个参数是我们的state,第二个参数就是接收我们传递过去的参数的。
incrementN(state,step) {
state.count+=step;
},
decrementN(state,step) {
state.count-=step;
},
-
定义完成回到.vue文件 触发定义的mutation,此时运行页面点击+N或-N就会增加或减少我们所传递的参数值。
<template>
<div id="app">
<button [@click](/user/click)="add()">+</button>
<button [@click](/user/click)="addN()">+N</button>
{{ count }}
<button [@click](/user/click)="reduceN()">-N</button>
<button [@click](/user/click)="reduce()">-</button>
</div>
</template>
methods: {
//点击按钮count+1
add() {
this.$store.commit("increment");
},
//点击按钮count-1
reduce() {
this.$store.commit("decrement");
},
//点击按钮传递参数count+n
addN() {
this.$store.commit("incrementN", 3);
},
//点击按钮传递参数count-n
reduceN() {
this.$store.commit("decrementN", 3);
},
},
Mutation 的第二种使用方式
-
从vuex中导入mapMutations 辅助函数
import { mapState,mapMutations } from 'vuex'
-
在methods方法中声明我们要用到的mutation,就可以直接调用啦~
methods: {
...mapMutations(["increment", "incrementN", 'decrement','decrementN']),
//点击按钮count+1
add() {
this.increment()
},
//点击按钮count-1
reduce() {
this.decrement()
},
//点击按钮传递参数count+n
addN() {
this.incrementN(3)
},
//点击按钮传递参数count-n
reduceN() {
this.decrementN(3)
},
},
Action的核心概念
我们刚刚实现了计数器的自增自减,假如现在有一个新的需求,我希望点击按钮修时等待一秒在修改数据,应该怎么做呢?
那么就要介绍一个vuex的另一个核心概念 action 因为mutation不支持异步操作,我们大可以通过action来实现异步。
-
同样在.vue文件中定义按钮
<template>
<div id="app">
<button>异步+N</button>
{{ count }}
<button>异步-N</button>
</div>
</template>
-
回到store文件夹下的index.js,在 store 实例中新增 actions,并写入方法,action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此我们可以调用 context.commit 提交一个 mutation
actions:{
incrementNAsync(context,step){
setTimeout(() => {
context.commit('incrementN',step)
},1000)
},
decrementNAsync(context,step){
setTimeout(() => {
context.commit('decrementN',step)
},1000)
}
}
-
定义完成回到.vue文件使用 $store.dispatch 来触发,此时点击按钮就会发现数据会在一秒之后更改。
<template>
<div id="app">
<button [@click](/user/click)="addNAsync()">异步+N</button>
{{ count }}
<button [@click](/user/click)="reduceAsync()">异步-N</button>
</div>
</template>
methods: {
addNAsync(){
this.$store.dispatch('incrementNAsync',3)
},
reduceNAsync(){
this.$store.dispatch('decrementNAsync',3)
}
},
action的第二种使用方式
-
从vuex中导入mapActions函数
import {mapActions} from "vuex";
-
在methods方法中声明我们要用到的action,就可以直接调用
<template>
<div id="app">
<button [@click](/user/click)="addNAsync()">异步+N</button>
{{ count }}
<button [@click](/user/click)="reduceNAsync()">异步-N</button>
</div>
</template>
methods: {
...mapActions(["incrementNAsync", "decrementNAsync"]),
addNAsync() {
this.incrementNAsync(3);
},
reduceNAsync() {
this.decrementNAsync(3);
},
},
这种方式下也可以直接调用mapActions声明的方法,不用在methods从新定义方法, 同样mutaiton也支持此种方式。
<button [@click](/user/click)="incrementNAsync(3)">异步+N</button>
<button [@click](/user/click)="'decrementNAsync'(3)">异步+N</button>
...mapActions(['incrementNAsync', 'decrementNAsync']),
getter核心属性
getter用于对store中的数据进行加工处理,不会修改原数据,类似于 computed 属性 当 store 数据发生变化, getter 也会相应发生变化
-
在store文件夹下的index.js中新增getters,定义一个新的函数
getters:{
showMsg(){
return '我是getters'
}
}
-
回到.vue文件中使用插值表达式的方式
<p>{{ $store.getters.showMsg}}</p>
getter第二种使用方式
-
从vuex中导入mapGetters函数
从vuex中导入mapGetters函数
-
在computed中声明要用到的getters
...mapGetters(['showMsg']),
-
在页面中直接引入
<p>{{showMsg}}</p>
## 写在最后
这是我在掘金发表的第一篇文章,修修改改好几次,还在持续优化中,如果有哪啦不准确的地方,欢迎指正,最后希望可以得到你手里的小心心~
<p style="line-height: 20px; color: #ccc">
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作者: 太可爱了啊
原文链接:<a href='https://juejin.im/post/6854573222051430413'>https://juejin.im/post/6854573222051430413</a>
</p>