Vuex详解

Vuex介绍
Vuex是一个专为Vue,js应用程序开发的集中式状态管理架构。它把我们项目中所用到的组件对其状态进行集中式的存储于管理,并以相应的规则保证状态得以按照我们想要的效果发生变化。
简单的来说,Vuex就是vue为了方便数据的操作而建立的一个“前端数据库”。我们都知道Vue中组件间本身是不共享作用域的,B组件想要拿到A组件中的数据,需要用到emit等特殊的语句去实现通信。随着项目的变大,组件之间的通信也就越来越难以维护。这时,如果有一个全局变量store,用来存共享的数据state,然后把A组件想要共享的数据挂到B组件上。这样B组件通过state就可以拿到这个数据了。这样一来,由store去统一管理数据,则数据的传递就更加清晰明了,易于维护。当然,B组件确实拿到了A组件中的数据,但是这个数据不是一成不变的。A要操作这个数据,我们就需要在这个数据改变的时候通知一下B,B也跟着变就好了。Vuex其实就是帮我们来做这件事的,帮我们集中存储管理数据。

Vuex核心
通过上面的了解,想必大家也能感觉到Vuex最重要的就是存储应用中大部分状态state的库,这个库就是store。

Vuex和单纯的全局对象的区别
1.Vuex的状态存储是响应式的,当Vue组件从store中读取状态的时候,若store中的状态发生变化,那么相应的组件也会随之改变;
2.store中的状态是不能直接改变的,改变它的唯一方法就是显示地提交(commit) mutation。

说了这么多,大家已经等不及想要去实践一下了吧,下面让我们写一个小demo,感受一下Vuex的作用。

Vuex使用
1.用Vue-cli自行搭建Vue项目;
2.引入Vuex
脚本安装:npm install vuex –save-dev
在src目录下新建vuex文件夹,里面创建store,js,引入vue和vuex,并进行使用

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

3.在main.js中进行引用

  import store from './vuex/store'
  new Vue({
      el: '#app',
      router,
      store,
      components: { App },
      template: '<App/>'
    })

4.在store.js中创建变量,创建执行的方法

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {//共享值
        count:1 
}
const mutations = {
    increment:state => state.count++,       
    decrement:state => state.count--
}
export default new Vuex.Store({//一个容器,包含应用中的大部分状态
    state,//数据库
    mutations//中间量,把数据存入数据库的API,用来操作数据修改state   
}); 

5.在你创建的vue中引入vuex获取操作数据

<template>
    <div>
        <h2>{{msg}}</h2>
        <p>{{$store.state.count}}</p>
        <button @click="increment">+</button>
        <button @click="decrement">-</button>
    </div>
</template>
<script>
    import store from '@/vuex/store';
    import {mapState,mapMutations} from 'vuex'; 
    export default {
        data(){
            return{
                msg:'大家好'
            }
        },
        store,
        methods:mapMutations([//模板获取Vuex里面mutations中的方法,以代替$store.commit()的繁琐写法
            'increment','decrement'
        ])
    }
</script>
<style>

</style>

完成上述的步骤就可以实现组件从vuex中拿数据,以及操作数据了。由此可知,对于一个store容器来说,state和mutation是必不可少的。当然vuex还为我们提供了更加方便的拿取数据和操作数据的方法getters和actions。
6.getters取值
getters是一个纯函数,接收参数state,可以对state进行相关处理,然后返回我们想要取的值。如下:
在store.js里面添加getters

const getters = {
    add:state => state.count += 10
}
export default new Vuex.Store({
    state,//数据库
    mutations,//必须在store里面,它是个中间量,修改数据方法的集合,把数据存入数据库的API,用来修改state  
    getters//从数据库里取数据的API,是一个“纯函数”,就是不会对原数据造成影响的函数
});

在vue文件中引入mapGetters获取add方法

import {mapState,mapMutations,mapGetters} from 'vuex';
computed:{
    ...mapGetters([
        'add'
    ])
}

将获取到的值添加到template模板中

扫描二维码关注公众号,回复: 3170622 查看本文章
<p>{{add}}</p>

这时,你会发现p中的值在每次变化的时候,会先加10,这就是getters先对获取的值进行了处理然后再返回。
你会发现mapGetters写在了computed里面,虽然getter我们写的是函数,但是我们应该把它当成计算属性来用。
7.action操作数据
在store.js里面添加update的actions用于更新数据,与此同时需要在mutations中增加upDate用于存储更新的数据。

const mutations = {
    increment:state => state.count++,       
    decrement:state => state.count--,
    upDate:state => state.count = 2
}
const actions = {
    update:({commit}) => commit('upDate')
}

当然,还是需要把actions放入到store中

export default new Vuex.Store({
    state,//数据库
    getters,//从数据库里取数据的API,是一个“纯函数”,就是不会对原数据造成影响的函数
    actions,//对数据进行处理,处理完再存储到数据库中
    mutations//必须在store里面,它是个中间量,修改数据方法的集合,把数据存入数据库的API,用来修改state   
}); 

在vue文件中引入mapActions获取update方法

import {mapState,mapMutations,mapGetters,mapActions} from 'vuex';
methods:{
    ...mapMutations([
        'increment','decrement','upDate'
    ]),
    ...mapActions([
        'update'
    ])
}

template模板中添加更新按钮

<button @click="update">更新</button>

这时,你就会发现,点击更新按钮,值会先改为我们赋的值然后再进行其他操作。当然,看到这儿,你可能会好奇action和mutation起到的作用是一样的,使用action显得多此一举。其实不然,action与mutation的区别在于action是可以异步操作数据,而mutation使用的时候需要commit,但是commit是同步函数,所以mutation只能是同步执行的。
8.异步action
actions通过将mutations里面处里数据的方法变成可异步的处理数据的方法。当然有人又会问,既然mutation不能处理异步而action可以,那么什么不直接用action呢?上文已经解释过,在vue里面,store中的状态是不能直接改变的,改变它的唯一方法就是显示地提交(commit) mutation。
为了模拟异步,下面写了一个setTimeout函数
在store.js里面添加action

const mutations = {
    increment:state => state.count++,       
    decrement:state => state.count--,
    upDate:state => state.count = 2,
    firstClick:() => console.log('我是第一次点击的'),
    secondClick:() => console.log('我是第二次点击的'),
}
const actions = {
    update:({commit}) => commit('upDate'),
    first:({commit}) => setTimeout(()=> commit('firstClick'),2000),
    second:({commit}) => commit('secondClick'),
}

在vue中同上面的引入,在template中加入操作按钮

<button @click="first">action第一次点击</button>
<button @click="second">action第二次点击</button>

这样,你先后点击两个按钮,控制台里就会先展示action第二次点击,说明action可以实现异步操作。

写到这儿,vuex就介绍的差不多了,下面让我们来总结一下。
在vuex中,state相当于数据库,action处理数据,然后通过mutation把处理后的数据放入数据库(state)中,谁要用就通过getter从数据库(state)中取。(action ==> mutation ==> state ==> getter)

猜你喜欢

转载自blog.csdn.net/weixin_40970987/article/details/81909531