震惊!喝个茶的时间就学会了vuex

写在前面

我很欣赏震惊部,由于他们的标题每次写的都很好0.0javascript

什么是vuex

先给出官网地址html

官方解释: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的全部组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
大白话:对数据(data)统一的管理,若是涉及到了数据的处理,来,到vuex里面进出吧!就像是超市对商品的统一管理同样前端

为了使用vuex而作的准备

安装vuex

npm install --save vuex
<!--这里假定你已经搭好vue的开发环境了--> 
复制代码

配置vuex

一、首先建立一个js文件,假定这里取名为store.js
二、在main.js文件中引入上面建立的store.jsvue

//main.js内部对store.js的配置
import store from '"@/store/store.js' 
//具体地址具体路径
new Vue({
    el: '#app',
    store, //将store暴露出来
    template: '<App></App>',
    components: { App }
});
复制代码

store.js中的配置

import Vue from 'vue'; //首先引入vue
import Vuex from 'vuex'; //引入vuex
Vue.use(Vuex) 

export default new Vuex.Store({
    state: { 
        // state 相似 data
        //这里面写入数据
    },
    getters:{ 
        // getters 相似 computed 
        // 在这里面写个方法
    },
    mutations:{ 
        // mutations 相似methods
        // 写方法对数据作出更改(同步操做)
    },
    actions:{
        // actions 相似methods
        // 写方法对数据作出更改(异步操做)
    }
})

//可能有的地方书写的风格不是这样的,若是须要的了解的能够百度看看其余人的
复制代码

好了,基本的配置到这里就结束了,接下来咱们能够开始使用它们了;
下面结合一个购物车示例,咱们来全面了解一下vuex的使用java

开始使用vuex

咱们约定store中的数据是如下形式git

state:{
    goods: {
        totalPrice: 0,
        totalNum:0,
        goodsData: [
            {
                id: '1',
                title: '好吃的苹果',
                price: 8.00,
                image: 'https://www.shangdian.com/static/pingguo.jpg',
                num: 0
            },
            {
                id: '2',
                title: '美味的香蕉',
                price: 5.00,
                image: 'https://www.shangdian.com/static/xiangjiao.jpg',
                num: 0
            }
        ]
    }
},
getters:{ //其实这里写上这个主要是为了让你们明白他是怎么用的,
    totalNum(state){
        let aTotalNum = 0;
        state.goods.goodsData.forEach((value,index) => {
            aTotalNum += value.num;
        })
        return aTotalNum;
     },
     totalPrice(state){
        let aTotalPrice = 0;
        state.goods.goodsData.forEach( (value,index) => {
            aTotalPrice += value.num * value.price
         })
         return aTotalPrice.toFixed(2);
    }
},
mutations:{
    reselt(state,msg){
        console.log(msg) //我执行了一次;
        state.goods.totalPrice = this.getters.totalPrice;
        state.goods.totalNum = this.getters.totalNum;
    },
    reduceGoods(state,index){ 
        //第一个参数为默认参数,即上面的state,后面的参数为页面操做传过来的参数
        state.goods.goodsData[index].num-=1;
        
        let msg = '我执行了一次'
        this.commit('reselt',msg);
    },
    addGoods(state,index){
        state.goods.goodsData[index].num+=1;
        
        let msg = '我执行了一次'
        this.commit('reselt',msg);
        /** 想要从新渲染store中的方法,一概使用commit 方法 你能够这样写 commit('reselt',{ state: state }) 也能够这样写 commit({ type: 'reselt', state: state }) 主要看你本身的风格 **/
    }
},
actions:{
    //这里主要是操做异步操做的,使用起来几乎和mutations方法如出一辙
    //除了一个是同步操做,一个是异步操做,这里就很少介绍了,
    //有兴趣的能够本身去试一试
    //好比你能够用setTimeout去尝试一下
}
复制代码

好了,简单的数据咱们就这样配置了,接下来看看购物车页面吧;github

第一种方式使用store.js中的数据(直接使用)

<template>
    <div id="goods" class="goods-box">
        <ul class="goods-body">
            <li v-for="(list,index) in goods.goodsData" :key="list.id">
                <div class="goods-main">
                    <img :src="list.image">
                </div>
                <div class="goods-info">
                    <h3 class="goods-title">{{ list.title }}</h3>
                    <p class="goods-price">¥ {{ list.price }}</p>
                    <div class="goods-compute">
                        <!--在dom中使用方法为:$store.commit()加上store.js中的属性的名称,示例以下-->
                        <span class="goods-reduce" @click="$store.commit('reduceGoods',index)">-</span>
                        <input readonly v-model="list.num" />
                        <span class="goods-add" @click="$store.commit('addGoods',index)">+</span>
                    </div>
                </div>
            </li>
        </ul>
        <div class="goods-footer">
            <div class="goods-total">
                合计:¥ {{ goods.totalPrice }}
                <!-- 若是你想要直接使用一些数据,可是在computed中没有给出来怎么办? 能够写成这样 {{ $store.state.goods.totalPrice }} 或者直接获取gettles里面的数据 {{ $store.gettles.totalPrice }} -->
            </div>
            <button class="goods-check" :class="{activeChecke: goods.totalNum <= 0}">去结帐({{ goods.totalNum }})</button>
        </div>
    </div>
</template>
<script> export default { name: 'Goods', computed:{ goods(){ return this.$store.state.goods; } } } </script>
复制代码

若是上面的方式写参数让你看的很别扭,咱们继续看第二种方式vuex

第一种方式使用store.js中的数据(经过辅助函数使用)

<!--goods.vue 购物车页面-->
<template>
    <div id="goods" class="goods-box">
        <ul class="goods-body">
            <li v-for="(list,index) in goods.goodsData" :key="list.id">
                <div class="goods-main">
                    <img :src="list.image">
                </div>
                <div class="goods-info">
                    <h3 class="goods-title">{{ list.title }}</h3>
                    <p class="goods-price">¥ {{ list.price }}</p>
                    <div class="goods-compute">
                        <span class="goods-reduce" @click="goodsReduce(index)">-</span>
                        <input readonly v-model="list.num" />
                        <span class="goods-add" @click="goodsAdd(index)">+</span>
                    </div>
                </div>
            </li>
        </ul>
        <div class="goods-footer">
            <div class="goods-total">
                合计:¥ {{ goods.totalPrice }}
                <!-- getters里面的数据能够直接这样写 {{ totalPrice }} -->
            </div>
            <button class="goods-check" :class="{activeChecke: goods.totalNum <= 0}">去结帐({{ goods.totalNum }})</button>
        </div>
    </div>
</template>
<script> import {mapState,mapGetters,mapMutations} from 'vuex'; /** 上面大括弧里面的三个参数,即是一一对应着store.js中的state,getters,mutations 这三个参数必须规定这样写,写成其余的单词无效,切记 毕竟是这三个属性的的辅助函数 **/ export default { name: 'Goods', computed:{ ...mapState(['goods']) ...mapGetters(['totalPrice','totalNum']) /** ‘...’ 为ES6中的扩展运算符,不清楚的能够百度查一下 若是使用的名称和store.js中的同样,直接写成上面数组的形式就行, 若是你想改变一下名字,写法以下 ...mapState({ goodsData: state => state.goods }) **/ }, methods:{ ...mapMutations(['reduceGoods','addGoods']), /** 这里你能够直接理解为以下形式,至关于直接调用了store.js中的方法 reduceGoods(index){ // 这样是否是以为很熟悉了? }, addGoods(index){ } 好,仍是不熟悉,咱们换下面这种写法 onReduce(index){ //咱们在methods中定义了onReduce方法,相应的Dom中的click事件名要改为onReduce this.reduceGoods(index) //这至关于调用了store.js的方法,这样是否是以为满意了 } **/ } } </script>
复制代码

最后来看看Module

在项目比较复杂的时候,数据所有写在一个state 方法所有集中一个mutations中,将会使咱们的文件显得太过于臃肿,并且不易维护,那怎么办呢?
仍是那句话办法总比问题多,vuex为咱们提供了module这样一个模块的概念。
咱们能够利用它来根据咱们个个组件或者页面所须要的数据一一分割成不一样的模块,看下面示例npm

const moduleA = {
  state: { /*data**/ },
  mutations: { /**方法**/ },
  actions: { /**方法**/ },
  getters: { /**方法**/ }
}

const moduleB = {
  state: { /*data**/ },
  mutations: { /**方法**/ },
  actions: { /**方法**/ }
  getters: { /**方法**/ }
}

export default new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

//那怎么调用呢?看下面!

//在模块内部使用
state.goods //这种使用方式和单个使用方式样,直接使用就行

//在组件中使用
store.state.a.goods //先找到模块的名字,再去调用属性
store.state.b.goods //先找到模块的名字,再去调用属性
复制代码

看看效果图吧

效果图

写在最后

谢谢你们的阅读,若是本文让你能有所收获,深表荣幸,若是喜欢的,点个赞行 0.0数组

最后打一波广告:欢迎你们关注个人微信公众号:大前端js,固然为了回馈你们关注,里面我放了一些学习资源,热烈欢迎你们关注交流前端方面但不局限前端方面的知识;

以前发出来的有不少单词出错的地方,对这样的错误,深表歉意,也很是感谢你们的指正

原创不易,非商业转载时请注明出处与原文连接,商业转载请获得本人容许,谢谢!

文章讲解的小例子已经放到GitHub上面去了,github项目地址,喜欢的话就给个Star吧 0.0

相关文章
相关标签/搜索