1、为什么要用vuex

      在vue组件通信的过程中,我们通信的目的往往就是在组件之间传递数据或组件的状态(这里将数据和状态统称为状态),进而更改状态。但可以看到如果我们通过最基本的方式来
进行通信,一旦需要管理的状态多了,代码就会变得十分混乱。对所有状态的管理便会显得力不从心,尤其是多人合作的时候。此时vuex出现了,他就是帮助我们把公用的状态全抽出来放
在vuex的容器中,然后根据一定的规则来进行管理。

2、概念

  • 概念:vuex是一个状态管理工具,每一个Vuex应用的核心就是store(仓库);“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state),它的实例是唯一的-----单例模式;  一般把需要共享的数据放到store中;
  • 功能:存数据、取数据、改数据;
  • 出现场景:
    • 涉及到非父子关系的组件,例如兄弟关系、祖孙关系,甚至更远的关系组件之间的联系;
    • 在大型单页应用中,考虑如何更好地在组件外部管理状态;
  • 注意:vuex的数据处理流程是一个"单向"的数据流 ;
  • vuex的核心:
    • state:存放数据(状态);    取数据  this.$store.state.变量名
    • mutations:存放如何更改状态,同步方法放到mutations(同步)里面;    调用方法 this.$store.commit("方法名","参数")
    • getters:相当于计算属性,从state中派生出状态,比如将state中的某个状态进行过滤然后获取新的状态;      this.$store.getters.方法名(sum)
    • actions:mutations的加强版,异步方法放在了actions(动作)里面;      调用方法this.$store.dispatch("方法名"),异步方法则会调用mutations里面的同步方法
    • modules:就是当用这个容器来装这些状态还是显得混乱的时候,我们就可以把容器分成几块,把状态和管理规则分类来装。这和我们创建js模块是一个目的,让代码结构更清晰。

3、基本使用

  • vuex的安装

    cnpm i vuex --save
  • 安装成功后,
    • 新手入门    注意:vuex中是不允许直接修改store的状态值,我们必须通过mutations进行修改操作

      • 新建store文件夹,内容如下

      • 在app.js里面进行引入

        import store from './store'
        new Vue({
        router,
        i18n,
        store,
        el: '#app',
        render: h => h(App)
        })
      • store文件夹中index.js的内容为
        import Vue from 'vue'
        import Vuex from 'vuex' import state from './state'
        import actions from './actions'
        import mutations from './mutations' Vue.use(Vuex) export default new Vuex.Store({
        state,
        actions,
        mutations
        })
      • 在state.js中定义状态
        export default {
        count: ,
        }
      • 在mutations.js里面定义同步方法
        export default {
        // 改变状态的执行者 用于同步更改状态
        stateMutationsAdd(state, payLoad) {
        // 第一个参数是state 第二个参数是调用mutations时传入的参数
        state.count += payLoad;
        },
        stateMutationsReduce(state, payLoad) {
        state.count -= payLoad;
        }
        }
      • 在actions.js里面定义异步操作
        export default {
        // actions并不直接更改状态 而是发起mutations来更改状态
        stateAsyncReduce(context) {
        // context 是一个与 store 实例具有相同方法和属性的 context 对象
        // 这个异步操作 我们可以发送http请求、定时器、
        setTimeout(() => {
        context.commit("stateMutationsReduce", )//不能用this.$store,为undefined
        }, )
        }
        }
      • 在vue组件中使用(将state与getters结合进组件需要使用计算属性,将mutations与actions结合进组件需要在methods里面进行调用)
        <template>
        <div class="home">
        <div class="block">
        <h1>vuex的基本使用</h1>
        <el-button size="mini" type="primary" @click="reduceNumber">-</el-button>
        &nbsp;&nbsp;{{count}}
        <el-button size="mini" type="primary" @click="addNumber">+</el-button>
        <h1>vuex练习结束</h1>
        </div>
        </div>
        </template>
        <script>
        export default {
        name: "home",
        data() {
        return {};
        },
        computed: {
        count() {
        return this.$store.state.count;
        }
        },
        methods: {
        /**
        * [addNumber 对count数据进行增加操作 采用同步方式]
        * @return {[type]} [description]
        */
        addNumber() {
        // 第一个参数是同步方法的名称 第二个参数是传递给方法的数据
        this.$store.commit("stateMutationsAdd", );
        },
        /**
        * [reduceNumber 对count数据进行减少操作 采用异步方式]
        * @return {[type]} [description]
        */
        reduceNumber() {
        // dispatch返回的是actions执行的结果,是一个promise对象,如果异步操作之后还需要其他操作,可以使用.then/.catch等
        this.$store.dispatch("stateAsyncReduce");
        }
        },
        mounted() {}
        };
        </script>
      • 效果图

        点击 + 进行同步增加     

        点击-进行异步减少,每隔1s减少5

    • 新手入门之后,我们可以尝试将mutations里面的一些方法名称提取出来,从而提高代码维护性;

      • state.js

        export default {
        count: ,
        }
      • mutation-types.js
        export const STATE_MUTATIONS_ADD = 'stateMutationsAdd'
        export const STATE_MUTATIONS_REDUCE = 'stateMutationsReduce'
      • mutations.js
        import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from './mutation-types'
        export default {
        // 改变状态的执行者 用于同步更改状态
        [STATE_MUTATIONS_ADD](state, payLoad) {
        // 第一个参数是state 第二个参数是调用mutations时传入的参数
        state.count += payLoad;
        },
        [STATE_MUTATIONS_REDUCE](state, payLoad) {
        state.count -= payLoad;
        }
        }
      • actions.js
        import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from './mutation-types'
        export default {
        // actions并不直接更改状态 而是发起mutations来更改状态
        stateAsyncReduce(context) {
        // context 是一个与 store 实例具有相同方法和属性的 context 对象
        // 这个异步操作 我们可以发送http请求、定时器、
        setTimeout(() => {
        context.commit(STATE_MUTATIONS_REDUCE, )//不能用this.$store,为undefined
        }, )
        }
        }
      • vue组件中的使用
        <template>
        <div class="home">
        <div class="block">
        <h1>vuex的基本使用</h1>
        <el-button size="mini" type="primary" @click="reduceNumber">-</el-button>
        &nbsp;&nbsp;{{count}}
        <el-button size="mini" type="primary" @click="addNumber">+</el-button>
        <h1>vuex练习结束</h1>
        </div>
        </div>
        </template>
        <script>
        import {
        STATE_MUTATIONS_ADD,
        STATE_MUTATIONS_REDUCE
        } from "../store/mutation-types";
        export default {
        name: "home",
        data() {
        return {};
        },
        computed: {
        count() {
        return this.$store.state.count;
        }
        },
        methods: {
        /**
        * [addNumber 对count数据进行增加操作 采用同步方式]
        * @return {[type]} [description]
        */
        addNumber() {
        // 第一个参数是同步方法的名称 第二个参数是传递给方法的数据
        this.$store.commit(STATE_MUTATIONS_ADD, );
        },
        /**
        * [reduceNumber 对count数据进行减少操作 采用异步方式]
        * @return {[type]} [description]
        */
        reduceNumber() {
        // dispatch返回的是actions执行的结果,是一个promise对象,如果异步操作之后还需要其他操作,可以使用.then/.catch等
        this.$store.dispatch("stateAsyncReduce");
        }
        },
        mounted() {}
        };
        </script>
    • 为了方便起见,利用vuex提供的mapState、mapGetters、mapMutations以及mapActions四个方法将这些功能结合进组件
      • 其他文件跟上述保持一致
      • vue组件中的使用
        <template>
        <div class="home">
        <div class="block">
        <h1>vuex的基本使用</h1>
        <el-button size="mini" type="primary" @click="stateAsyncReduce">-</el-button>
        &nbsp;&nbsp;{{count}}
        <p>使用getters{{name}}</p>
        <el-button size="mini" type="primary" @click="stateMutationsAdd(10)">+</el-button>
        <h1>vuex练习结束</h1>
        </div>
        </div>
        </template>
        <script>
        import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
        export default {
        name: "home",
        data() {
        return {};
        },
        computed: {
        ...mapState(["count"]),
        },
        methods: {
        ...mapActions(["stateAsyncReduce"]),
        ...mapMutations(["stateMutationsAdd"])
        },
        mounted() {}
        };
        </script>
    • 当你采用了上述方式进行整合之后,依旧存在过多的状态,导致代码混乱的现象,我们可以将store分割成模块(module),每个模块都拥有自己的state、getters、mutations以及actions,甚至是嵌套子模块,从上至下按照同样的方式进行分割。
      • 首先,我们看一下目录结构

      • store/index.js

        import Vue from 'vue'
        import Vuex from 'vuex'
        import * as actions from './actions'
        import modules from './modules'
        Vue.use(Vuex)
        export default new Vuex.Store ({
        actions,
        modules,
        strict: false
        })
      • store/mutation-types.js
        export const STATE_MUTATIONS_ADD = 'stateMutationsAdd'
        export const STATE_MUTATIONS_REDUCE = 'stateMutationsReduce'
      • store/actions.js(大型项目中我们可以将所有的异步操作提取出来)
        import * as types from './mutation-types'
        const makeAction = (type) => {
        return ({ commit }, ...args) => commit(type, ...args)
        }
        export function stateAsyncReduce(context) {
        // context 是一个与 store 实例具有相同方法和属性的 context 对象
        // 这个异步操作 我们可以发送http请求、定时器、
        setTimeout(() => {
        context.commit(types.STATE_MUTATIONS_REDUCE, )//不能用this.$store,为undefined
        }, )
        }
      • module/index.js
        const files = require.context('.', false, /\.js$/)
        const modules = {} files.keys().forEach((key) => {
        if (key === './index.js') return
        modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
        }) export default modules
      • module/home.js(home可以自定义,以后项目中随机建立的模块名称)
        import { STATE_MUTATIONS_ADD, STATE_MUTATIONS_REDUCE } from '../mutation-types'
        const state = {
        count:
        } const mutations = {
        [STATE_MUTATIONS_ADD](state, payLoad) {
        // 第一个参数是state 第二个参数是调用mutations时传入的参数
        state.count += payLoad;
        },
        [STATE_MUTATIONS_REDUCE](state, payLoad) {
        state.count -= payLoad;
        }
        } export default {
        state,
        mutations
        }
      • vue组件中的使用
        <template>
        <div class="home">
        <div class="block">
        <h1>vuex的基本使用</h1>
        <el-button size="mini" type="primary" @click="stateAsyncReduce">-</el-button>
        <span>{{count}}</span>
        <el-button size="mini" type="primary" @click="stateMutationsAdd(10)">+</el-button>
        <h1>vuex练习结束</h1>
        </div>
        </div>
        </template>
        <script>
        import { mapState, mapGetters, mapMutations, mapActions } from "vuex";
        export default {
        name: "home",
        data() {
        return {};
        },
        computed: {
        ...mapState({
        count: state => state.home.count
        })
        },
        methods: {
        ...mapActions(["stateAsyncReduce"]),
        ...mapMutations(["stateMutationsAdd"])
        },
        mounted() {}
        };
        </script>
      • 特别强调的是:
        ...mapState({
        count: state => state.home.count(home为模块的名称)
        })

4、遇到的问题

暂无

简述Vue中使用Vuex的更多相关文章

  1. 在vue中使用vuex 一个简单的实例

    1.安装vuex:npm install vuex --save 2.在main.js文件中引入vuex (请忽略其它代码) 3.建一个vuex文件夹,然后在建一个store.js(这两个文件名字可以 ...

  2. 简述vue中父子组件是怎样相互传递值的(基础向)

    前言 首先,你需要知道vue中父组件和子组件分别指的是什么?   父组件:vue的根实例——用new Vue()构造函数创建的vue实例(实例会有一个挂载点,挂载点里的所有内容可理解为父组件的内容) ...

  3. 简述vue中v-if和v-show的区别

    vue中的 v-if 和 v-show 二者都可以动态的控制元素的隐藏和显示,但是他们控制的原理是不同的 v-if v-if 控制元素显示或隐藏是把dom元素整个的渲染或者删除,如果删除,也就是页面中 ...

  4. 在mpvue或者Vue中使用VUEX

    第一个页面Index,主页哦 import Vue from'vue' import Vuex from'vuex' import getters from'./getters' import sta ...

  5. 简述Vue中的过滤器

    1.过滤器的基本概念 概念:本质上是函数: 作用:用户输入数据后,它能够进行处理,并返回一个数据结果:(无return语句不会报错,但是这种过滤器没有丝毫意义) 格式:管道符(  |  )进行连接,而 ...

  6. 简述Vue中的计算属性

    1.什么是计算属性 如果模板中的表达式存在过多的逻辑,那么模板会变得臃肿不堪,维护起来也异常困难,因此为了简化逻辑出现了计算属性: <template> <div id=" ...

  7. Vue学习笔记:Vuex

    为什么需要Vuex 管理共享状态 解决一份数据在多个组件中试用的困难 系统化的状态管理,区别于小型状态过来 底层设计模式: 全局单例模式 应用场景 适合中大型项目: 小项目反而会因为引入更多概念和框架 ...

  8. Vue中Vuex的详解与使用(简洁易懂的入门小实例)

    怎么安装 Vuex 我就不介绍了,官网上有 就是 npm install xxx 之类的.(其实就是懒~~~哈哈) 那么现在就开始正文部分了 众所周知 Vuex 是什么呢?是用来干嘛的呢? Vuex ...

  9. vueX、vue中transition的使用、axios

    引入一篇好文章链接:看一遍就会的vuex文章;完!!! vue中transtion的使用:transition文章;完!!! axios的文章:axios;完!!!

随机推荐

  1. Java多线程和并发(九),ReentrantLock(公平锁)

    目录 1.ReentrantLock 2.ReentrantLock的实现 3.synchronized和ReentrantLock的区别 九.ReentrantLock(公平锁) 1.Reentra ...

  2. py脚本修改后自动重启

    在用socket.io, pika之类启动一个脚本死循环做server或者client的时候: 1脚本被编辑之后,是不会自动重启 2当代码报错的时候,会立即退出, 只能手动重新运行 python ap ...

  3. Akka 介绍

    欢迎使用 Akka,Akka 是一套被用来在在多处理器核心和网络之间被设计可扩展和具有相关弹性的开源工具集.Akka 允许你更加关注商业需求而不是书写低级别的代码来提供可靠性,容错率和高性能. 很多常 ...

  4. hdu 1081 dp问题:最大子矩阵和

    题目链接 题意:给你一个n*n矩阵,求这个矩阵的最大子矩阵和 #include<iostream> #include<cstdio> #include<string.h& ...

  5. THUSC2016 成绩单

    题目链接:Click here Solution: 我们设\(f[l][r][x][y]\)表示在原区间\(l\sim r\) 内还未被取走的值最大为\(x\)最小为\(y\)时的代价,这里我们只考虑 ...

  6. FJOI2017前做题记录

    FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...

  7. Presto部署指南

    1.Presto简介说明 Presto是一个开源的分布式SQL查询引擎,适用于交互式分析查询,数据量支持GB到PB字节. Presto的设计和编写完全是为了解决像Facebook这样规模的商业数据仓库 ...

  8. C++入门经典-例3.20-使用continue跳出循环

    1:continue不是立即跳出循环体,而是跳过本次循环结束前的语句,回到循环的条件测试部分.代码如下: // 3.20.cpp : 定义控制台应用程序的入口点. // #include " ...

  9. Zookeeper 选举过程

    Zookeeper 选举过程 问题 选举过程 服务器之间是怎么通信的? 答:QuorumCnxManager使用TCP-socket实现选举过程中的连接通信 Leader的选举过程在什么时候实现? L ...

  10. CentOS 7,使用yum安装Nginx

    https://www.centos.bz/2018/01/centos-7%EF%BC%8C%E4%BD%BF%E7%94%A8yum%E5%AE%89%E8%A3%85nginx/ 文章目录 [隐 ...