Vue中状态管理器(vuex)详解以及实际应用场景

目录
  • Vue中 常见的组件通信方式可分为三类
  • Vuex简介
  • 1. State
  • 2. Getters
  • 3. Mutations
  • 4. Actions
  • 5. 使用 mapState、mapGetters、mapActions 简化
  • 总结
  • 传送门:Vue中 子组件向父组件传值 及 .sync 修饰符 详解
  • 传送门:Vue中 $ attrs、$ listeners 详解及使用
  • 传送门:Vue中 事件总线(eventBus)详解及使用
  • 传送门:Vue中 provide、inject 详解及使用

Vue中 常见的组件通信方式可分为三类

父子通信

父向子传递数据是通过 props,子向父是通过 events($emit);
通过父链 / 子链也可以通信($parent / $children);
ref 也可以访问组件实例;
provide / inject;
$attrs/$listeners;

兄弟通信

Bus;
Vuex;

跨级通信

Bus;
Vuex;
provide / inject、
$attrs / $listeners、

Vuex简介

当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

问题一:多个视图依赖于同一状态。

问题二:来自不同视图的行为需要变更同一状态。

对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。

对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。

因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?

在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!

通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

这就是 Vuex 背后的基本思想,借鉴了 Flux、Redux 和 The Elm Architecture。与其他模式不同的是,Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。

1. State

vuex中的数据源,我们需要保存的数据就保存在这里,在页面通过 this.$store.state来获取我们定义的数据;

store\index.js

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

export default new Vuex.Store({
  state: {
    count:10
  }
})

views\about.vue

<template>
  <div class="about">
    <h1>state:{{this.$store.state.count}}</h1>
  </div>
</template>

效果:

2. Getters

Getter 相当于 vue 中的 computed 计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算;

我们可以通过定义 vuex 的 Getter 来获取,Getters 可以用于监听、state中的值的变化,返回计算后的结果;

这里我们修改 views\about.vue 文件如下:

<template>
  <div class="about">
    <h1>getters:{{this.$store.getters.changeCount}}</h1>
    <h1>state:{{this.$store.state.count}}</h1>
  </div>
</template>

再修改 store\index.js 文件如下,其中getters中的getStateCount方法接收一个参数state,这个参数就是我们用来保存数据的那个对象;

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

export default new Vuex.Store({
  state: {
    count:10
  },
  getters:{
    changeCount(state){
      return state.count + 1
    }
  }
})

效果:

3. Mutations

如果需要修改 store 中的值唯一的方法就是提交 mutation 来修改;

我们现在 views\about.vue 文件中添加两个按钮,一个加1,一个减1;

这里我们点击按钮调用 addCount 和 reduceCount,然后在里面直接提交 mutations 中的方法修改值;

<template>
  <div class="about">
    <h1>getters:{{this.$store.getters.changeCount}}</h1>
    <h1>state:{{this.$store.state.count}}</h1>
    <button @click="addCount"> + </button>
    <button @click="reduceCount"> - </button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      n:10
    }
  },
  methods:{
    addCount(){
      this.$store.commit('add',this.n) // 传递参数
    },
    reduceCount(){
      this.$store.commit('reduce')
    }
  }
}
</script>

修改 store\index.js 文件,添加 mutations,在 mutations 中定义两个函数,用来对count加1和减1,这里定义的两个方法就是上面commit提交的两个方法如下:

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

export default new Vuex.Store({
  state: {
    count:10
  },
  getters:{
    changeCount(state){
      return state.count + 1
    }
  },
  mutations: {
    add(state,n){
      state.count = state.count + n
    },
    reduce(state){
      state.count = state.count - 1
    }
  }
})

效果:

4. Actions

通过 mutations ,我们达到了修改store中状态值的目的;

但是,mutation只能是同步,action 可以包含任意异步操作,在actions中提交mutation再去修改状态值;

接下来我们修改 store\index.js文件:

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

export default new Vuex.Store({
  state: {
    count:10
  },
  getters:{
 	 changeCount:state => state.count + 1
  },
  mutations: {
    add(state,n){
      state.count = state.count + n
    },
    reduce(state){
      state.count = state.count - 1
    }
  },
  actions: {
    addFun(context,n){
      context.commit('add',n) // 传递参数
    },
    reduceFun(context){
      context.commit('reduce')
    }
  }
})

然后我们去修改views\about.vue文件:

<template>
  <div class="about">
    <h1>getters:{{this.$store.getters.changeCount}}</h1>
    <h1>state:{{this.$store.state.count}}</h1>
    <button @click="addCount"> + </button>
    <button @click="reduceCount"> - </button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      n:10
    }
  },
  methods:{
    addCount(){
      this.$store.dispatch('addFun',this.n) // 传递参数
    },
    reduceCount(){
      this.$store.dispatch('reduceFun')
    }
  }
}
</script>

效果:

5. 使用 mapState、mapGetters、mapActions 简化

如果我们不喜欢这种在页面上使用 “this. s t r o e . s t a t e . c o u n t ” 和 “ t h i s . stroe.state.count” 和 “this. stroe.state.count”和“this.store.dispatch(‘funName’)” 这种很长的写法,

那么我们可以使用 mapState、mapGetters、mapActions 就不会这么麻烦了;

我们修改 views\about.vue 文件如下:

<template>
  <div class="about">
    <h1>getters:{{this.$store.getters.changeCount}}</h1>
    <h1>通过mapGetters获取:{{changeCount}}</h1>
    <h1>通过mapState获取:{{count}}</h1>
    <h1>state:{{this.$store.state.count}}</h1>
    <button @click="addCount"> + </button>
    <button @click="reduceCount"> - </button>
  </div>
</template>

<script>
import {mapGetters,mapActions,mapState} from 'vuex'
export default {
  data(){
    return {
      n:10
    }
  },
  computed:{
    ...mapState({
      count:state => state.count
    }),
    ...mapGetters([
      'changeCount'
    ])
  },
  methods:{
    ...mapActions(
      {reduceCount:'reduceFun'},
    ),
    addCount(){
      this.$store.dispatch('addFun',this.n)
    },
    // reduceCount(){
    //   this.$store.dispatch('reduceFun')
    // }
  }
}
</script>

效果:

总结

到此这篇关于Vue中状态管理器(vuex)详解以及实际应用场景的文章就介绍到这了,更多相关Vue状态管理器vuex详解内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue的Flux框架之Vuex状态管理器

    学习vue之前,最重要是弄懂两个概念,一是"what",要理解vuex是什么:二是"why",要清楚为什么要用vuex. Vuex是什么? Vuex 类似 React 里面的 Redux 的状态管理器,用来管理Vue的所有组件状态. 为什么使用Vuex? 当你打算开发大型单页应用(SPA),会出现多个视图组件依赖同一个状态,来自不同视图的行为需要变更同一个状态. 遇到以上情况时候,你就应该考虑使用Vuex了,它能把组件的共享状态抽取出来,当做一个全局单例模式进行管理

  • Vuex中状态管理器的使用详解

    目录 一.Vuex是什么? 二.什么时候使用Vuex 三.Vuex的核心概念和API 四.应用举例 五.vuex中各种辅助函数的用法,可以使我们更加方便的运用vuex 一.Vuex是什么? Vuex在Vue项目开发时使用的状态管理工具.简单来说,就是对Vue的应用中多个组件的共享状态进行集中式的管理(读/写) Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取Sta

  • Vue中状态管理器(vuex)详解以及实际应用场景

    目录 Vue中 常见的组件通信方式可分为三类 Vuex简介 1. State 2. Getters 3. Mutations 4. Actions 5. 使用 mapState.mapGetters.mapActions 简化 总结 传送门:Vue中 子组件向父组件传值 及 .sync 修饰符 详解 传送门:Vue中 $ attrs.$ listeners 详解及使用 传送门:Vue中 事件总线(eventBus)详解及使用 传送门:Vue中 provide.inject 详解及使用 Vue中

  • Vue3状态管理的使用详解

    背景 随着Vue3的逐步应用,对状态管理的需求越来越多.起初是基于Vuex4进行状态管理的,但是Vuex4也暴露了一些问题.从个人角度来说,Vuex4类似于过渡期产品,对TypeScript的支持性并不完整.如果使用TypeScript编写组件,需要遵循一定步骤后,才可以正确进行类型推断,并且对modules的使用上也并不友好.Vuex核心贡献者Kia King也表示Vuex5已经在计划中,并且能提供完整的TypeScript支持,那么在Vuex5面世之前,或者直接"舍弃"Vuex的话

  • 发布订阅模式在vue中的实际运用实例详解

    订阅发布模式定义了一种一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象.这个主题对象在自身状态变化时,会通知所有订阅者对象,使它们能够自动更新自己的状态. 比如addEventListener 这个api就是个发布订阅模式 如果用过vue的同学,可以把他类比于 watch 下面我们看一个例子 var observe={ fnsObj:{}, // 订阅方法 on:function(key,fn){ if(!observe.fnsObj[key]){ observe.fnsObj[key]

  • Vue 中使用 typescript的方法详解

    什么是typescript typescript 为 javaScript的超集,这意味着它支持所有都JavaScript都语法.它很像JavaScript都强类型版本,除此之外,它还有一些扩展的语法,如interface/module等. typescript 在编译期会去掉类型和特有语法,生成纯粹的JavaScript. Typescript 5年内的热度随时间变化的趋势,整体呈现一个上升的趋势.也说明ts越来越️受大家的关注了. 安装typescript npm install -g ty

  • vue中的ElementUI的使用详解

    登录+sessionStorage 效果展示 登录成功后会把用户id存入前端的sessionStorage,拦截器会根据是否存在用户id来进行拦截 也可以将用户权限存入sessionStorage,然后当访问某个页面的时候在created方法中判断是否具有权限 <template> <div class="login-wrap"> <el-form class="login-container" ref="loginFormR

  • 封装一下vue中的axios示例代码详解

    在vue项目中,和后台交互获取数据这块,我们通常使用的是axios库,它是基于promise的http库,可运行在浏览器端和node.js中.他有很多优秀的特性,例如拦截请求和响应.取消请求.转换json.客户端防御cSRF等.所以我们的尤大大也是果断放弃了对其官方库vue-resource的维护,直接推荐我们使用axios库.如果还对axios不了解的,可以移步axios文档. 安装 npm install axios; // 安装axios 好了,下面开始今天的正文. 此次封装用以解决: (

  • Node.js基础入门之模块与npm包管理器使用详解

    目录 require函数 模块分类 第三方模块 1. 安装第三方模块 2. 引入第三方模块 3. 示例测试 系统模块 require注意事项 exports导出对象 1. exports示例 2. exports注意事项 module模块对象 package.json包描述文件 1. 什么是package.json ? 2. 如何创建package.json文件? NPM基础 1. 常用npm命令 2. npm 示例 cnpm基础 1. 什么是cnpm ? 2. 使用cnpm 控制台输出 1.

  • SpringBoot自定义MessageConverter与内容协商管理器contentNegotiationManager详解

    目录 1.自定义消息转换器MessageConverter 2.自定义内容协商管理器contentNegotiationManager 1.自定义消息转换器MessageConverter 在WebMvcAutoConfiguration类中有一个方法configureMessageConverters(),它会配置默认的MessageConverter public void configureMessageConverters(List<HttpMessageConverter<?>

  • AngularJS中的拦截器实例详解

    AngularJS中的拦截器实例详解 异步操作 有时候需要在拦截器中做一些异步操作.幸运的是, AngularJS 允许我们返回一个 promise 延后处理.它将会在请求拦截器中延迟发送请求或者在响应拦截器中推迟响应. 下面是项目中用到的代码. ZbtjxcApp.factory('myHttpInterceptor', ['$q', '$window','$location', function($q, $window,$location) { return { // 全局响应 'respo

  • vue中使用codemirror的实例详解

    这篇文章在vue里使用codemirror遇到的问题,写的很不错,还有下载的方法,大家可以点击查看. 以下是自己使用过的,做出来的例子: 做出来的效果图: 记住使用之前要npm下载哦 npm install vue-codemirror --save main.js import { codemirror } from 'vue-codemirror' import 'codemirror/lib/codemirror.css' Vue.use(VueCodemirror) 再到组件中使用 im

随机推荐