欢迎光临
我们一直在努力

Vue探索之–Vuex状态管理模式

=”color: #595959; font-size: 14px;”>关于Vuex,官网是这么给的定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。本篇将通过一个小Demo来说一下Vuex的用处,一起来看看吧!

为什么会有Vuex

Vuex是为了存放组件之间的共享数据而诞生的,组件中的共享数据可以直接挂载到Vuex中,以供APP中所有的组件使用,而不必通过父子组件之间传值了,这就有效解决了非父子组件之间的传值问题,对于非共享数据是没必要放在Vuex中的,组件内部的私有数据只放在组件各自的data中即可。总言之,Vuex就是一个全局的共享型数据存储区域,可以看做一个数据仓库。

Vue探索之--Vuex状态管理模式
需求

有这么一个需求,及其对应初始代码块,如下图

Vue探索之--Vuex状态管理模式

Vue探索之--Vuex状态管理模式

代码如下:

App.vue

<template>
  <div class="box">
        <p class="input">
            <input type="text" placeholder="0">
        </p>
        <counter></counter>
        <amount></amount>
    </div>
</template>

<script>
import counter from './components/counter'
import amount from './components/amount'

export default {
  data(){
    return{
    }
  },
  components:{
    counter,
    amount
  }
}
</script>

<style lang="scss" scoped>
.box{
  width: 300px;
  height: 120px;
  background-color: #007acc;
  padding: 10px;
  .input{
  text-align: center;
  }
}
</style>

counter.vue

<template>
    <div class="mt">
        <button>-</button>
        <button>+</button>
    </div>
</template>

<script>
export default {

}
</script>

<style lang="scss" scoped>
.mt{
    display: flex;
    justify-content: space-around;
    button{
        width: 30px;
        height: 20px;
    }
}
</style>

amount.vue

<template>
    <div class="amount">
        <h3>当前的值为</h3>
    </div>
</template>

<script>
export default {

}
</script>

<style lang="scss" scoped>
.amount{
    h3{
        text-align: center;
        margin: 0;
    }
}
</style>
安装Vuex

下包npm install vuex --save

在main.js中做全局配置:

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

new一个store实例:

const store = new Vuex.Store({
  state:{
    count: 1
  },
  mutations:{}
})

将store实例挂载到Vue实例上:

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
  store // 挂载store

Vue探索之--Vuex状态管理模式
需求分析

如上,我们new出了一个store实例,在该实例中,定义了一个count的值为1,下面我们试着在组件中是否可以拿到这个count的值。

首先我们要知道怎么在组件中获取store中的数据,我们看到count是在store下的state中定义的,可以把state想像为组件中的data,是专门用来存储数据的。state中的数据在组件中都可以通过this.$store.state.xxx 来获取到,由于之前已经把stores实例挂载到了Vue实例上,所以在任何组件中都可以全局访问,这里 this 可以省略不写,这样count的值我们就可以拿到了。

渲染数据

input 是在App.vue定义的,找到input,作数据双向绑定

<input type="text" v-model="this.$store.state.count">

这时我们保存代码刷新浏览器可以看到,输入框内的值变为了1 如图

Vue探索之--Vuex状态管理模式

在amount组件中获取count

用插值表达式获取count的值

<div class=“amount”>
<h3>当前的值为{{$store.state.count}}</h3>
</div>

实现加减功能

先看下效果,如图

Vue探索之--Vuex状态管理模式

很简单,只需给两个按钮添加 click 事件,再定义两个方法就可以实现,来看下代码

绑定事件

<button @click="cut">-</button>
<button @click="add">+</button>

定义方法

methods:{
    add(){
        this.$store.state.count++;
    },
    cut(){
        this.$store.state.count--;
    }
}

注意:这样做虽然实现了需求,但是不推荐这么写,因为这样做不符合Vuex的设计理念,而且也不利于数据的维护,为什么这么说呢,来看张图

Vue探索之--Vuex状态管理模式

所以,如果要操作 store 中的 state 值,只能通过调用 mutations 提供的方法来操作数据,不推荐直接在组件中操作,因为每一旦导致数据紊乱,不能够快速定位到错误的原因。

mutations属性

经过以上的分析,我们知道操作的方法需要定义在mutations中,来看下代码

mutations:{
    // 加法
    addition(state){
        state.count++;
    },
    // 减法
    subtraction(state){
        state.count--;
    }
}

注意mutations 中所有方法的第一个参数已经被规定死了,永远是 state

在我们定义了方法后,怎么调用呢?这里,如果组件想要调用mutations中的方法,只能通过 this.$store.commit('xxx') 来调用,其中xxx为方法名。下面我们来调用一下,代码如下

methods:{
    add(){
        this.$store.commit('addition');
    },
    cut(){
        this.$store.commit('subtraction');
    }
}

看下效果,如图

Vue探索之--Vuex状态管理模式

mutations中方法如何传参

上面我们已经实现了初始的需求,如果想点击加减按钮,让数值加减的跨度可变该怎么实现呢,这里可以给方法传参,来看代码

mutations:{
    // 加法 
    addition(state, num){
        state.count += num;
    },
    // 减法
    subtraction(state, num){
        state.count -= num;
    }
}

接收参数

methods:{
    add(){
        this.$store.commit('addition'5);
    },
    cut(){
        this.$store.commit('subtraction'3);
    }
}

如上我们给 addition 和 subtraction 除了state外各自传了一个num的参数,并且在组件中调用,下面刷新看是否可以实现’点击加每次加5,点击减每次减3’ 如图

Vue探索之--Vuex状态管理模式

mutations中方法是否可以传多个参

上面我们传了一个num参数,发现可以,那么是否能够传多个参数呢,来试试吧

addition(state, num1, num2){
    state.count += (num1 + num2);
}

调用

add(){
    this.$store.commit('addition'23);
}

运行结果如图

Vue探索之--Vuex状态管理模式

结果发现,不行,这里我们打印一下第三个参数 console.log(num2) 发现是 undefined 如图

Vue探索之--Vuex状态管理模式
Vue探索之--Vuex状态管理模式

既然不接受第三个参数,第二个参数变成对象的话会是怎样,来这样试试

addition(state, obj){
    state.count += (obj.num1 + obj.num2);
    // console.log(num2);
}

调用

add(){
    this.$store.commit('addition', {num1: 3, num2: 2});
}

运行发现是可以传对象的,结果如图

Vue探索之--Vuex状态管理模式

结论:所以说 mutations 中方法最多只能有两个参数,其一是state状态对象,第二个是我们通过 commit 提交过来的参数。

getter属性

Vuex 允许我们在 store 中定义“getter”(可以认为是 store 的计算属性)。就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。

来看个需求

Vue探索之--Vuex状态管理模式我们不想让amount组建中h3中的字符串是手动写死的,怎么实现?

可以用 getter 来实现, 看代码

const store = new Vuex.Store({
  state:{
    count: 1
  },
  mutations:{
    // 加法 
    addition(state, obj){
      state.count += (obj.num1 + obj.num2);
      // console.log(num2);
    },
    // 减法
    subtraction(state, num){
      state.count -= num;
    }
  },
  getters:{
    content: (state) => {
      return '当前值为:' + state.count;
    }
  }
})

通过属性($store.getters.xxx)访问,代码

<div class="amount">
    <!-- <h3>当前的值为{{$store.state.count}}</h3> -->
    <h3>{{ $store.getters.content }}</h3>
</div>

看下运行结果,如图

Vue探索之--Vuex状态管理模式

注意getters 在这里只负责对外提供数据,不负责修改数据。

此外还有Action和Module属性,这里我们的需求没有用到,不多做介绍。

Action属性

Action 类似于 mutation,不同点在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。点我查看Action

Module属性

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。点我查看Module

Vue探索之--Vuex状态管理模式

总结

以上通过一个Demo对Vuex做了简单的了解,在开发中具体场景具体分析是否要用Vuex。官方建议:“如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex”。最后在这里祝大家新年快乐!Happy New Year !

Vue探索之--Vuex状态管理模式

赞(0) 打赏
未经允许不得转载:卧龙岗 » Vue探索之–Vuex状态管理模式
分享到: 更多 (0)

相关推荐

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏