vue的状态管理模式—vuex

栏目: 编程语言 · 发布时间: 5年前

内容简介:如果你在使用Vue.js,肯定有很多组件之间相互传递参数的经历。当遇到父子组件需要通信的时候,我们经常用的方法是传递参数。其实除了传递参数的方式,我们还可以结合业务需要考虑是否用Vuex去解决。官方文档的定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。状态管理模式、

如果你在使用Vue.js,肯定有很多组件之间相互传递参数的经历。当遇到父子组件需要通信的时候,我们经常用的方法是传递参数。其实除了传递参数的方式,我们还可以结合业务需要考虑是否用Vuex去解决。

Vuex是什么?

官方文档的定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

状态管理模式、 集中式存储管理 初次了解的话感觉有点难以理解,我们通过官方文档中提供的这张图加深下理解。

vue的状态管理模式—vuex

Vuex是一种设计思想。每一个Vuex应用的核心就是Store(仓库)。组件的状态和数据都放到一个统一的内存空间state去管理,state的数据映射到组件上,当组件的数据发生变化时,通过Dispatch Actions或者直接Commit Mutations的方法修改state。我们不能直接改变state中的状态。改变state中状态的唯一途径就是显式的提交(Commit)Mutations。这样使得我们可以方便的追踪每一个状态的变化,从而使我们能够实现一些功能帮助我们更好的了解我们的应用。state修改后反映到组件上,形成闭环。

当以往父子组件通信的时候,我们通常会采用props+emit的方式。vuex适合更为复杂的使用场景。比如:

  • 解决多个关联度比较低的兄弟组件之间的状态共享
  • 解决路由间跳转复杂的参数传递

实际应用

小编最近在做一个项目的填写发布页面的功能,简化来说就是从first页面填写信息后,点击跳转到second页面,同时传入first页面中填写的信息。那么如何用Vuex的方式实现呢?

vue的状态管理模式—vuex

首先我们需要在开发环境中安装Vuex:

npm install vuex --save
复制代码

然后在项目的src目录下增加store文件夹,目录如下

vue的状态管理模式—vuex

其中:

  • index.js:入口文件
  • state.js:存储状态。也就是变量。
  • getters.js:派生状态。也可以理解为set、get中的get。有两个可选参数,state、getters分别可以获取state中的变量和其它getters。和vue中的computed类似。
  • mutations.js:提交状态修改。可以理解为set、get中的set。每一个mutation都有一个字符串的事件类型和回调函数。第一个参数默认为state。vuex中唯一修改state的方式,不支持异步操作。和vue中的methods类似。
  • mutation-types.js:存储于mutations相关的字符串常量,方便检测和管理。
  • actions.js:和mutations类似。支持异步操作,也可以是对mutations的封装。

state.js 示例:

const state = {
    userInfo: {}
};
export default state;
复制代码

userinfo 存放我们需要提交的信息

mutation-types.js 示例:

export const SET_USERINFO = 'SET_USERINFO';
复制代码

mutation.js 示例:

import * as types from './mutation-types'

const mutations = {
    [types.SET_USERINFO](state, userInfo) {
        state.userInfo = userInfo;
    }
}
复制代码

是一个对象,里面存放一些方法,方法名就是mutation-types里存放的常量名,第一个参数对应的是state.js文件中的state;第二个参数是提交的参数。

getters.js 示例:

export const userInfo = state => state.userInfo;
复制代码

获取state的状态到组件。

index.js入口文件配置,组件Vuex示例:

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'

import createLogger from 'vuex/dist/logger'

Vue.use(Vuex)

// 开发环境为true,生产环境为false
const debug = process.env.NODE_ENV !== 'production'
export default new Vuex.Store({
    actions,
    getters,
    state,
    mutations,
    plugin: debug ? [createLogger()] : []
})

复制代码

最后再将store实例注入main.js里的vue实例中:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
new Vue({
    el: '#app',
    router,
    store,
    render: h => h(App)
})
复制代码

完成这些基本的配置之后,接下来我们就要到项目中的调用了。Vuex为我们提供了一系列的语法糖:mapMutations,mapGetters,mapActions,省去了繁琐的操作。我们可以直接按照vue调用methods和computed的方式去调用。

首先我们看下第一步first.vue的部分: template:

<template>
  <div class="page">
    <div>姓名: <input type="text" v-model="name"></div>
    <div>年龄: <input type="text" v-model="age"></div>
    <div>
      <button @click="jumpToNextPage">下一页</button>
    </div>
  </div>
</template>
复制代码

script:

import { mapMutations, mapActions } from "vuex";
export default {
  data() {
    return {
      name: '张三',
      age: '20',
      personInfo: {}
    };
  },
  methods: {
    jumpToNextPage() {
      this.personInfo.name = this.name;
      this.personInfo.age = this.age;
      this.$router.push({
        path: `/second/`
      });
      this.setInfo(this.personInfo);
    },
    ...mapMutations({
      setInfo: 'SET_USERINFO'
    })
  }
};
复制代码

我们在这一步获取用户填写的信息提交到mutations。

首先我们需要从vuex引入mapMutations去操作state的变化。根据文档提供的方法,在methods里通过扩展运算符的方式调用。我们在mapMutations里需要做一个映射,setInfo对应的是mutation-types里的常量SET_USERINFO。然后在点击跳转到下一页按钮的时候执行this.setUser()这个方法,并且传入信息参数。

修改mutations之后,接下来就是在第二页获取state的变化了。

接下来我们来看second.vue的部分: template:

<template>
    <div class="page">
      姓名:{{userInfo.name}}
      年龄:{{userInfo.age}}
    </div>
</template>
复制代码

script:

import { mapGetters } from "vuex";
export default {
  data() {
    return {
    };
  },
  computed: {
    ...mapGetters(["userInfo"])
  },
  created() {
    console.log(this.userInfo);
  },
  methods: {
  }
};
复制代码

第一步我们同样需要从vuex中引入mapGetter。然后在computed中,同样按照扩展运算符的方式引入需要得到的数据。此处userInfo对应的是getter.js中定义的userInfo。

这样我们就通过vuex完成了从修改提交数据到获取数据的整个过程。

刚才的部分我们是直接提交mutations,现在我们再来看下如何通过actions来提交mutations的变化。

actions.js 示例:

import * as types from './mutation-types';

export const actionsSetUserInfo = function ({ commit, state }, userInfo) {
  commit(types.SET_USERINFO, userInfo);
}
复制代码

引入mutation-types之后,定义提交mutation的函数,actionSetUserInfo。commit和state是默认参数,userInfo是修改的参数数据。

此时first.vue修改为:

import { mapMutations, mapActions } from "vuex";
export default {
  data() {
    return {
      name: '张三',
      age: '20',
      personInfo: {}
    };
  },
  methods: {
    jumpToNextPage() {
      this.personInfo.name = this.name;
      this.personInfo.age = this.age;
      this.$router.push({
        path: `/second/`
      });
      this.actionsSetUserInfo(this.personInfo);
    },
    ...mapActions({
      'actionsSetUserInfo'
    })
  }
};
复制代码

这样,actions.js 里actionSetUserInfo就被执行。通过commit mutation修改state中的用户信息。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

创造突破性产品

创造突破性产品

Jonathan Cagan、Craig M.Vogel / 机械工业出版社 / 2004-1 / 35.00元

在《创造突破性产品:从产品策略到项目定案的创新》中作者总结多年的研究成果,指明了与产品创新相关的一系列因素,并提供了一套全新的开发突破性产品的理论与方法,该书旨在帮助企业,技术和设计人员: 获得对用户的需求和市场新的趋势的准确洞察力; 认识可以创造新市场的产品机会缺口; 指导产品模糊前期的构造; 正确地运用定性和定量的研究方法; ......一起来看看 《创造突破性产品》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码