【vue2.0进阶】轻松理解Vuex的3个核心概念及简单应用案例(计算器)

5 篇文章 0 订阅
3 篇文章 0 订阅

Vuex是一个提供状态管理机制,相比使用传统的全局对象,它有两大优点,一个是它的状态存储是响应式的,另一个是要不能随意修改Vuex的状态,必须按照它的规矩来办事。最后也了解了它有适用和不适用的业务场景。

如何使用Vuex

一、创建仓库Store

要使用Vuex,我们要创建一个实例 store ,我们称之为仓库,利用这个仓库 store 来对我们的状态进行管理。

 //创建一个 store
 const store = new Vuex.Store({});

创建 store 之后,我们再来了解Vuex的几个核心概念

核心:State

Vuex的作用类似全局对象,没错,Vuex 使用单一状态树,用一个对象State包含了整个应用层级的所有状态,你可以理解为这些状态就是一堆全局变量和数据。

 //创建一个 store
 const store = new Vuex.Store({
    //state存储应用层的状态
    state:{
        count:5  //总数:5
    }
 });

上面的例子中,假设我们有一个全局状态count的值为5。那么,我们就可以将其定义为 state 对象中的key和value,作为全局状态供我们使用。

state 中的状态被各个组件关联着,在开发调试过程中,我们可以结合vue-devtool工具,可以清晰地看到整个应用的数据,非常方便。

//(vue-devtool中的vuex面板)
(vue-devtool中的vuex面板)

但如果你使用的还是传统的方法,定义一个全局变量来管理这些全局数据,那么就非常不合理,不但不便于调试,而且全局变量容易造成全局污染等问题。

核心:Getters

还记得Vue中的 计算属性computed 吗?当我们需要在data的基础上再派生一些状态的时候,就会使用computed来实现。

同样,当我们需要从 state 中派生出一些状态的时候,就会使用到 getters ,你可以将 getters 理解 state 的计算属性。

getters 接受 state 作为其第一个参数:

 const store = new Vuex.Store({
   //state存储应用层的状态
   state:{
      count:5  //总数:5
    },
    //派生出来的状态
   getters:{
      //ES6 的箭头函数语法
    newCount:state => state.count * 3
    }
 });

假设我们要在state.count的基础上派生出一个新的状态newCount出来,就适合使用我们的 getters ,上面说我们使用了ES6的箭头函数语法。

 //ES6 箭头函数语法
 newCount:state => state.count * 3,

 //相当于
 //传统语法
 newCount:function (state ) {
    return state.count * 3;
 }

核心Mutations

Vuex相比传统的全局变量有两个优势,其中一个是Vuex中的状态不能随意修改,要修改必要按照Vuex提供的方式才能修改。要用Vuex,咱就得听它的。

Vuex给我们提供修改仓库 store 中的状态的唯一办法就是通过提交 mutation 。我们来看看如何定义一个mutation,它和上面的 getters ,会接受 state 作为第一个参数:

 const store = new Vuex.Store({
    //state存储应用层的状态
    state:{
        count:5  //总数:5
    },
    //更改store状态的唯一途径
    mutations:{
        increment(state){
            state.count ++;
        }
    }
 });

我们在 mutations 中定义了一个叫increment的函数,函数体就是我们要进行更改的地方,可以看到,我们只是简单地对 state 中的count进行了自增运算。

mutations 我们是定义好了,怎么使用呢?

非常简单,Vuex要求我们要想通过 mutations 更改内容,就必须提交mutation,语法如下:

 //提交一个名为increment的mutation
 store.commit('increment');

我们再提交commit 时候,字符串参数 increment,就是对应在 mutations中的increment

此外,store.commit( ) 还接受其他额外的参数,比如:

 //...
 //更改store状态的唯一途径
 mutations:{
    increment(state,n){
        state.count += n;
    }
 }
 //...
 store.commit('increment',10);

我们在提交的时候额外传了参数10,只要在定义 mutations 的时候定义与之相对应的形参就可以处理了。

理解了Vuex的三个核心概念,具体怎么用呢?

=================== 案例 : 计算器===========================

当然只讲概念还不够,必须要结合上案例才能理解得更深刻。

案例用Vuex实现一个简单的网页计算器。
Vuex适合在较为大型复杂的项目中使用。在实际开发过程中,简单的计算器也许只算得上是一个简单的小项目,你完全可以不用Vuex来实现。所以,以下我们演示的案例只作为demo来讲解Vuex,让大家能够轻松地搞懂Vuex的用法,不代表在实际开发中的做法。

我们先看看我们要实现的简单计算器的效果:
在这里插入图片描述
(我是gif,加载有点慢)

此计算器的功能包括了简单的加、减、乘、除运算,和一个清空数据的按钮。

项目分析 :
分析一: 考虑到运算的结果result和所有输入的值enter(看下图指示),是跟每个组件相关联的,我们会将result和enter作为应用层的状态(全局数据)处理,这里就会简单使用到我们的Vuex提供的仓库store。

分析二: 每个键盘的按键,我们可以封装成一个个自定义的组件:

(看作16个keyboard组件)

简单分析完毕,马上开始我们的代码部分,CSS部分相对简单,不在此展开讲解。

1步:安装Vuex

老规矩,在项目中安装Vue和Vuex,要保证Vuex在安装之前,Vue已经成功安装。

 <script src="js/vue.js"></script>
 <script src="js/vuex.js"></script>

第2步:创建仓库store

 //创建仓库store
 const store = new Vuex.Store({
    state:{
       result:"",//运算结果
     enter:""  //输入的值
    }
 });

我们刚开始分析的时候,把result和enter看作是应用层级的状态,所以定义为仓库store的state对象的属性值来管理它们,初始化为空字符串。

3 步:自定义组件

在Vue2.0基础系列的第九节《掌握vue的另一个核心:组件》 ,我们讲解过如何规划和实现一个自定义的组件,还不了解的同学可以先从前面的章节学起。

可以看到,每个键盘所代表的值不一样。分别从0~9,还有各种运算按键,所以我们要将这些值动态地传入组件内部。

因此:我们可以这样实现 组件。

 //自定义组件
 Vue.component('keyboard',{
    //接受的参数value,代表键盘的值
   props:['value'],
    //模板
   template:`<div
               :data-value="value">
                {{value}}
             </div>`
 });

我们添加了一个动态的属性data-value,后面我们会使用到它。

有了组件,我们就可以编写我们的页面Html的代码,并使用这个 组件。

4 步:页面布局

 <div id="app">
    <div class="result">运算结果</div>
    <div class="enter">输入的值</div>
    <div class="keys">
        <div class="list">
            <!--键盘区域-->
        </div>
    </div>
 </div>

第5步:创建Vue实例。

要使用Vue,就必须创建一个Vue实例。

 //创建Vue实例
 const app = new Vue({
    //挂载元素
    el:"#app",
 });

通过以上5步,我们做了以下准备:

  1. 安装了Vue和Vuex
  2. 创建了仓库store
  3. 定义了键盘组件
  4. 页面的布局
  5. 创建了Vue实例

但貌似距离实现我们的计算器,是否还有点距离。

接下来我们一步一步完善以上的代码,将这4部分关联起来,实现完整的计算器。

首先,我们的键盘区域还没有完善,我们先来实现它。

 <div class="list">
    <!--键盘区域,还没实现-->
 </div>

16个按键的值我们会事先定义好,放在Vue实例的data中,所以我们将Vue实例的代码修改如下:

 //创建Vue实例
 const app = new Vue({
    //挂载元素
    el:"#app",
    data:{
        //16个按键的值
        keys:[
            'clear', '+', '-', '*',
            '7', '8', '9', '/',
            '4', '5', '6', '0',
            '1', '2', '3', '=',
        ]
    }
 });

有了这16个值,我们利用vue提供的v-for指令和 组件,实现键盘区域的渲染。

我们对页面中的键盘区域部分代码进行修改。
修改前:

 <div class="list">
    <!--键盘区域-->
 </div>

修改后:

 <div class="list">
    <keyboard
        v-for="item in keys"
        :value="item">
    </keyboard>
 </div>

我们通过 v-for 指令,将keys中的每一个值动态地传入到 组件中去。

结合我们事先写好的CSS样式,我们可以看到键盘区域的渲染效果:
(效果图)

但是我们也看到,键盘上面的几个中文:“运算结果”和“输入的值”不是我们想要的,我们再来修改它。

你会发现,我们需要的运算结果result和输入的值enter是应用层的状态,它俩被我们定义在了仓库store上。那么问题来了,我们如何将仓库store和vue实例关联起来呢?

Vuex提供了store选项,允许我们将仓库store引入到根组件,并且此跟组件的所有子组件都可以使用到仓库store,而且子组件无需显示的引入。有了这个机制,我们就很方便地将仓库store和vue实例关联起来了。

具体怎么使用呢?很简单,我们将Vue实例的代码修改如下:

 //创建Vue实例
 const app = new Vue({
    //挂载元素
   el:"#app",
    //ES6语法,相当于"store":store
    store,
    //.....data部分不变,此处省略.......
 });

这样我们就可以将store引入,且能通过 this.$store 访问到它。

好了,引入它之后,我们就来使用state中的应用层的数据result和enter。怎么使用呢?

由于计算结果result和输入值enter经常会被 <keyboard/> 组件操作更新,所以我们这里需要使用Vue的 computed 计算属性。

所以,我们给Vue实例增加计算属性,增加一下代码:

 //创建Vue实例
 const app = new Vue({
    //.....其他代码不变....
    //增加计算属性
   computed:{
      result(){
        //通过this.$store获取仓库的数据result
        return this.$store.state.result;
      },
      enter(){
       //通过this.$store获取仓库的数据result
        return this.$store.state.enter;
      }
    }
 });

我们成功地将仓库的状态result和enter关联到了我们的实例中的计算属性result和enter,这样,每当仓库中的运算结果result和输入值enter发生了变化,实例中的计算属性result和enter也会做出响应式更新。

我们把计算属性result和enter绑定在html上,来渲染我们的页面。修改的部分如下,修改前:

 <div class="result">运算结果</div>
 <div class="enter">输入的值</div>

修改后:

 <div class="result">
    <!--绑定计算属性result-->
    {{ result }}
 </div>
 <div class="enter">
    <!--绑定计算属性enter-->
    {{ enter === ""?0:enter}}
 </div>

由于业务需要,输入的值默认为0,所以我们做了简单的三元运算,当ente为空字符串的时候,我们在页面上显示:0。

我们此时看到的页面效果:(效果图)

似乎离我们的计算器越来越近了,但我们点击任意一个键盘的时候,似乎还没有任何反应。

接下来,我们就来完成最后一步:点击键盘,对仓库store的状态result和enter进行修改。

我们上一节说过,在Vuex中不能任意修改应用层的状态,要修改,就得用它提供的唯一途径:通过commit提交mutation。

没问题,提交就提交嘛,那还不简单。

当用户点击键盘的时候,我们就提交一个mutation,并把当前按的键的值传过去。为此,我们修改 组件的代码。

修改后如下:

//定义组件
 Vue.component('keyboard',{
    props:['value'],
    //点击事件的监听处理getKeyboardValue
    template:`<div 
             @click="getKeyboardValue"
             :data-value="value">
             {{value}}
           </div>`,
    methods:{
     //点击事件处理函数
    getKeyboardValue(event){
       //获取当前的按键的值
     let value=event.target.dataset.value;
       //通过commit提交mutation
       this.$store.commit('calculate',value)
     }
    }
 });

增加了监听点击事件的处理函数getKeyboardValue,我们会提交一个名为calculate的mutation给仓库,并将当前按键的值一起提交过去。

哦,别忘了,我们的仓库还没有定义名为calculatemutations,赶紧去定义一个。

我们将仓库store的代码完善一下。修改后,如下:

 //创建仓库store
 const store = new Vuex.Store({
    state:{
        result:"",
        enter:""
    },
    //定义名为calculate的mutation
    mutations:{
        calculate(state,value){    
          if(value === '='){
            //按键的值为=,进行结果计算
            state.result = eval(state.enter);
            state.enter += value;
          }else if(value === 'clear'){
            //按键的值为clear,清空数据
            state.result = state.enter = "";
          }else{
            //输入结果enter进行拼接
            state.enter += value;
          }
        }
    }
 });

这样,就实现了点击 组件,修改仓库store中的状态,由于Vue实例的计算属性是依赖仓库store的状态的,所以一旦状态被修改,计算属性就会重新计算,从而更新视图。

看流程图会更加清晰:

(流程图)流程图

我们最后来看看计算器的效果:
(我是gif,加载有点慢)

由于我们的项目中使用了vue,浏览器安装了vue-devtool的同学可以打开控制台,清晰地看到整个计算器应用的组件状态的变化,方便调试。

//(vue-devtool面板)(vue-devtool面板)

整个案例就介绍完了,如果看完云里雾里的话,别慌,这很正常,你必须花时间去敲上几遍代码,才能理解滴更加深刻。

代码,还得多敲,看是看不懂的!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值