Vuex介绍以及同步取值与异步问题

前言:我们在之前就有了子类与父类之间的传参,又有利用总线进行传参,但两者都有一定的弊端。如:总线定义组件太多容易混淆等;所以接下来我们会利用VueX进行参数传值


一:VueX简介


官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。可以想象为一个“前端数据库”(数据仓库),
   让其在各个页面上实现数据的共享包括状态,并且可操作
   
   Vuex分成五个部分: 
   1.State:单一状态树
   2.Getters:状态获取
   3.Mutations:触发同步事件
   4.Actions:提交mutation,可以包含异步操作
   5.Module:将vuex进行分模块


二:VueX各个js文件的作用

1:关系图(四个js文件的关系):

2:官方关系图: 

 

1.State

单一状态树用一个对象就包含了全部的应用层级状态;每个应用将仅仅包含一个 store 实例

 2.Getters

状态获取(可以认为是store的计算属性),在组件中的computed中引入

                             getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算

                             Getter 接受 state 作为其第一个参数,也可以接受其他 getter 作为第二个参数

 3.Mutations
  •   触发同步事件更改 Vuex 中 store 的状态的唯一方法是commit mutation;
  •   mutation类似于事件,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler);
  •  回调函数对状态进行更改, state 作为第一个参数
  4.Actions

提交mutation,可以包含异步操作

  •    Action提交的是mutation,而不是直接变更状态
  •    Action可以包含任意异步操作
  •    Action的回调函数接收一个 context 上下文参数,注意,这个参数可不一般,它与 store 实例有着相同的方法和属性
  5.store

每一个Vuex应用的核心就是store(仓库),store基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。

三、利用vuex同步存值

前提:在进行vuex的操作时,必须要将Vuex的配置给安装好:

1:安装(将以下命名在项目的cmd窗口中运行)

npm install vuex -S

2 .创建store模块,分别维护state/actions/mutations/getters

store:

        index.js

        state.js

        actions.js

        mutations.js

        getters.js

3 .在store/index.js文件中新建vuex的store实例,并注册上面引入的各大模块

import Vue from 'vue'
import Vuex from 'vuex'
import state from './State'
import getters from './Getters'
import actions from './Actions'
import mutations from './Mutations'
Vue.use(Vuex)
const store = new Vuex.Store({
 	state,
 	getters,
 	actions,
 	mutations
 })
 
 export default store

4 .在main.js中导入并使用store实例

 import store from './store'

在main.js中导入store实例

new Vue({
  el: '#app',
  data(){
    return {
      Bus:new Vue({
 
      })
    }
  },
  router,
  store,
  components: { App },
  template: '<App/>'
})

5 .之后按要求编码,即可使用vuex的相关功能

1:思路

同步存值主要是用到Mutations.js文件,下面我将用代码来验证Mutations.js文件同步存值的功能。(上述第二点有讲到Mutations.js的用途及功能)

代码验证思路:现在有两个界面,一个是VuexPage1(用户管理)界面,另一个是VuexPage2(角色管理)界面,当我在VuexPage1点击改变值的方法时,就会调用Mutations.js文件中的setResturantName方法,VuexPage1的值发生改变时,这时VuexPage1中的值也会随之改变两个界面中的值同时进行改变。

2:代码
1:VuexPage1代码
<template>
  <div>
    <h3>页面一,欢迎来到{{msg}}</h3>
    <button @click="buy">盘它(同步)</button>
    <button @click="buyAsync">盘它(异步)</button>
    <button @click="doAjax">盘它(异步)</button>
  </div>
</template>
 
<script>
  export default {
    data() {
      return {
 
      };
    },
    computed: {
      msg() {
        return this.$store.state.resturantName;
      }
    },
    methods: {
      buy() {
        this.$store.commit('setResturantName', {
          resturantName: 'qqq'
        });
      },
      buyAsync() {
        this.$store.dispatch('setResturantNameByAsync', {
          resturantName: '麦当劳'
        });
      },
      doAjax() {
        this.$store.dispatch('setResturantNameByAsync',{
          _this:this
        });
      }
    }
  }
</script>
 
<style>
</style>
2:VuexPage2代码
<template>
  <div>
    <h3>页面二,欢迎来到{{msg}}</h3>
 
 
  </div>
</template>
 
<script>
  export default{
    data(){
      return {
 
      };
    },
    computed:{
      msg(){
        return this.$store.getters.getresturantName;
      }
    }
  }
</script>
 
<style>
</style>
3:Mutations.js代码
export default {
  setResturantName: (state, payload) => {
    state.resturantName = payload.resturantName;
  }
}
3:效果
1:VuexPage1页面

2:VuexPag2页面

3:点击同步两个界面同时改变

4:其中关于方法中两个参数的讲解

        // type(事件类型): 其值为setResturantName

        // payload:官方给它还取了一个高大上的名字:载荷,其实就是一个保存要传递参数的容器

注意:

      注1:mutations中方法的调用方式

           不能直接调用this.$store.mutations.setResturantName('KFC'),必须使用如下方式调用:

           this.$store.commit(type,payload);

          // 1、把载荷和type分开提交

           store.commit('setResturantName',{

             resturantName:'KFC'

           })

           // 2、载荷和type写到一起

          store.commit({

            type: 'setResturantName',

            resturantName: 'KFC'

          })
 

问题:为什么Mutations.js必须是同步函数?

异步方法,我们不知道什么时候状态会发生改变,所以也就无法追踪了

           如果我们需要异步操作,Mutations就不能满足我们需求了,这时候我们就需要Actions了

           mutations: {

            someMutation (state) {

              api.callAsyncMethod(() => {

                state.count++

              })

            }

           }

完成以上操作后,整个效果就会出来了。

四、利用vuex取值

前言:

vuex取值主要是运用了Getters.js文件中的取值方法,为什么会用到Getters.js文件?下图中给出了答案,

1:Getters.js

export default {
  getResturantName: (state) => {
    return state.resturantName;
  }
}

2:VuexPage1

    computed: {
      msg() {
        // return "KFC"
        // return this.$store.state.resturantName;注意要用下面的形式
        return this.$store.getters.getResturantName;
      }
    }
  }

五、Vuex的异步加载问题

前言:

1、Vuex的异步加载主要是用到了Action.js文件,其次还需要用到Mutations.js文件。异步简单点讲就是两个方法互补干涉,互不影响,两个方法同时进行。

2、明确效果:

当我点击盘它的按钮时,餐馆变为笑声餐馆,点击最后老板时就会变为卓京餐馆,变成卓京餐馆的时候中间间隔三秒,就是为了凸显出异步二字,

1:Actions.js

export default{
  setResturantNameAsync: (context, payload) => {
    // context等价于this.$store,也就是代表了Vuex的上下文
    //在这个文件中可以调用同步文件mutation.js同步方法
    //payload为载荷保存且传递的参数
    // state.resturantName = payload.resturantName;
    setTimeout(function(){
      context.commit("setResturantName",payload);
    },3000);
  }
}

这个文件中的代码和同步文件中的代码不一样,这里的context等价于this.$store,也就是代表了Vuex的上下文,payload在上面已经讲解到

      pantaAsync(){
        this.$store.dispatch("setResturantNameAsync",{
          resturantName:"卓京食堂"
        })
      }

完成上述步骤后,异步就完成了,效果也就随之出来。

2:关于异步的实现思路

当我点击VuexPage1中的最后老板方法时,我就会调用store中的dispatch(异步)方法,里面有两个参数,第一个参数是要调的方法名,第二个是要改的餐馆名字(也就是一个对象,载荷),之后进入到Action.js中,调用方法,这里调用了一个3秒的方法,之后就会跳到Mutations.js中调用同步存值的方法,这时两个界面的值就会同时改变了,从一开始讲的异步,其实是两个方法进行对比,这里是将改变和最后老板两个方法进行对比,当你点击第一个方法时,会发生改变,点击第二个方法时,也会发生改变。互不影响,互不干涉

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值