前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场

vuex

作者头像
epoos
发布于 2022-06-06 07:47:37
发布于 2022-06-06 07:47:37
1.1K00
代码可运行
举报
文章被收录于专栏:epoos.comepoos.com
运行总次数:0
代码可运行

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

状态管理包含以下几部分

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.state 驱动应用的数据源
2.view 以声明方式将state映射到视图
3.action 相应在 view 上的用户输入导致的状态变化

这三个状态之间互相交互,就形成了vue的单向数据流

但是这个单项数据流模式是很容易被破坏的。 如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1.多个视图依赖于同一状态。
2.来自不同视图的行为需要变更同一状态。

对于第一种状态,可以通过传参的形式解决,但是对于兄弟节点之间的状态传递就很麻烦了。 第二种状态,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。

这些做法都有其局限性,那么有什么办法能解决这些问题呢?

这就是vuex被设计出来的原因了。它的出现就是为了解决这些问题。

核心概念

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
state:vuex使用单一状态树,一个对象包含了全部应用层级的状态,是唯一数据源。

由于vuex的状态是存储是响应式的,从store实例中读取状态,最简单的方法就是在计算属性中返回某个状态。

除此之外,vue 还通过store选项,提供了一种机制,将状态从根组件 注入到每一个子组件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

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'

Vue.use(Vuex)

const debug = process.env.NODE_ENV !== 'production'

let store = new Vuex.Store({
  actions,
  getters,
  state,
  mutations,
})


const app = new Vue({
  el: '#app',
  store, // 把 store 对象提供给 “store” 选项,这可以把 store 的实例注入所有的子组件
  components: { Counter },
  template: `
    <div class="app">
      <counter></counter>
    </div>
  `
})

通过在根实例中注册store选项,该store实例会注入到根组件下所有子组件中 子组件能通过 this.$store 访问到。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
getter: 通过getter获取属性,可以在获取state的时候对属性进行过滤或者计算。

getter的返回值跟计算属性一样,会被缓存,只有当依赖属性变化的时候才会重新计算,可以看做是store的计算属性。 getter可以返回一个函数,来实现给getter传参。 当getter返回的是一个函数的时候,通过方法访问的时候,每次都会去进行调用,不会缓存结果。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mutation:更改vuex中store状态的唯一方法就是提交mutation

vuex中的mutation类似于事件 每个mutation都有一个字符串 事件类型(type)和一个回调函数(handler) 这个回调函数就是我们实际进行状态更改的地方,它接受一个state作为第一个参数。

定义一个mutation

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state, n) {
      // 变更状态
      state.count++
    }
  }
})

调用一个mutation

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 字符串的方式调用
store.commit('increment', n)

// 对象的方式调用cc
store.commit({
  type: 'increment',
  amount: 10
  ... // 更多字段
})

第二个参数‘n’叫做载荷,通常情况n是一个对象,这样方便传更多的参数。

特别注意:mutation必须是同步函数。 那么如果是异步请求怎么办呢?

此时,就需要用到另一个核心概念Action了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
action:action和mutation类型,区别在于,action是提交一个mutation而直接变更状态。

action可以包含任意异步操作。

Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象作为参数。 context可以有commit、state、getters、 因此,可以直接通过参数调用commit触发mutation。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 定义一个action
actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('increment')
    }, 1000)
  }
}

// 调用一个action action也支持荷载,支持对象和字符串的方式传参
// 以载荷形式分发
store.dispatch('incrementAsync', {
  amount: 10
})

// 以对象形式分发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

store.dispatch可以处理被触发action的处理函数返回的Promise,并且 store.dispatch仍旧返回Promise

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 定义异步的action
actions: {
  actionA ({ commit }) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        commit('someMutation')
        resolve()
      }, 1000)
    })
  }
}

// dispatch一个promise
store.dispatch('actionA').then(() => {
  // ...
})
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
module:将store分割成模块,每个模块拥有自己的state、mutation、action、getter、嵌套子模块等。这个模块就是module

如果store非常大的时候,非常不好管理,这时候就可以将其分割为小的module了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态

对于模块内部的 mutation 和 getter,接收的第一个参数是模块的局部状态对象。 对于模块内部的 action,局部状态通过 context.state 暴露出来,根节点状态则为 context.rootState 对于模块内部的 getter,根节点状态会作为第三个参数暴露出来

模块命名空间

默认情况下,模块内部的 action、mutation 和 getter 是注册在全局命名空间的——这样使得多个模块能够对同一 mutation 或 action 作出响应。 如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const store = new Vuex.Store({
  modules: {
    account: {
      namespaced: true, // 待命名空间的模块,(命名空间控制属性会继承)
    }
  }
})

相关链接

[vuex]https://vuex.vuejs.org/zh/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-08-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ES5的继承和ES6的继承有什么区别?让Babel来告诉你
如果以前问我ES5的继承和ES6的继承有什么区别,我一定会自信的说没有区别,不过是语法糖而已,充其量也就是写法有区别,但是现在我会假装思考一下,然后说虽然只是语法糖,但也是有点小区别的,那么具体有什么区别呢,不要走开,下文更精彩!
街角小林
2022/03/21
6910
ES5的继承和ES6的继承有什么区别?让Babel来告诉你
JS原生方法原理探究(六)从 Babel 转译过程浅谈 ES6 实现继承的原理
都说 ES6 的 Class 是 ES5 的语法糖,那么 ES6 的 Class 是如何实现的呢?其实现继承的原理又是什么呢?不妨我们通过 Babel 转译代码的方式,看看其中有什么门道。
Chor
2021/06/08
1.2K0
【THE LAST TIME】一文吃透所有JS原型相关知识点
首先我想说,【THE LAST TIME】系列的的内容,向来都是包括但不限于标题的范围。
Nealyang
2019/11/04
1.1K0
JS 继承
用过 React的读者知道,经常用 extends继承 React.Component:
grain先森
2019/03/28
3K0
JS 继承
JavaScript继承的实现方式:原型语言对象继承对象原理剖析
对象的继承:A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的。
周陆军
2021/08/14
8290
前端-如何继承 Date 对象?由一道题彻底弄懂 JS 继承
于是,随手用JS中经典的组合寄生法写了一个继承,然后,刚准备完美收工,一运行,却出现了以下的情景:
grain先森
2019/03/29
1.1K0
前端-如何继承 Date 对象?由一道题彻底弄懂 JS 继承
ES5和ES6函数你不知道的区别【面试篇】 前言1. PolyFill2.性能上3 hooks和 class 的性能4.用法上5.总结
1.利用原生 js 撸一个简单的 class; 2.根据上面的用法知道 class 必须通过 new 调用,不能直接调用;
火狼1
2020/05/09
2K0
ES6 + Babel + React低版本浏览器采坑记录
IMWeb前端团队
2018/01/08
1.8K0
自己实现一个VUE响应式--VUE响应式原理
这里的响应式(Reactive)不同于CSS布局的响应式(Responsive), 这里的响应式是指数据和视图的绑定,数据一旦更新,视图会自动更新。下面让我们来看看Vue是怎么实现响应式的,Vue 2.0和Vue 3.0的实现原理还不一样,我们来分开讲。
蒋鹏飞
2020/10/15
6640
自己实现一个VUE响应式--VUE响应式原理
我的 Web 前端面试经历——百度
面试是个漫长的过程,从海投到收获电话面试,一面、二面、三面,一个步骤出错那么后面就宣告终结。同时,面试过程中你也可能会遇到一些面试官的刁难,甚至部分面试官会说些比较打击你的话,但是大部分面试官都是很棒的!
李才哥
2019/07/10
6640
我的 Web 前端面试经历——百度
玩转ES6(四)Set、Map、Class类和decorator 装饰器
在看Class之前建议看一下js的面向对象 https://juejin.im/post/5b8a8724f265da435450c591
前端迷
2019/12/03
8730
Babel下的ES6兼容性与规范
IMWeb前端团队
2017/12/28
2.1K0
Object 中的几个很相似的方法
这里主要讨论这么几个方法,他们用法很相似,但又有所不同。在实际开发中就有可能陷入其中,搞不清到底用哪个方法比较好。下面就开始一一介绍。
多云转晴
2019/10/23
6170
Object 中的几个很相似的方法
前端面试 【JavaScript】— JS如何实现继承?
这样写的时候子类虽然能够拿到父类的属性值,但是问题是父类原型对象中一旦存在方法那么子类无法继承。
越陌度阡
2021/11/22
7800
前端面试 【JavaScript】— JS如何实现继承?
ES6-标准入门·Class 类
直至 ES6,JavaScript 终于有了“类”的概念,它简化了之前直接操作原型的语法,也是我最喜欢的新特性之一,但此类非彼类,它不同于熟知的如 Java 中的类,它本质上只是一颗语法糖。
数媒派
2022/12/01
2900
es6类和继承的实现原理
javascript使用的是原型式继承,我们可以通过原型的特性实现类的继承, es6为我们提供了像面向对象继承一样的语法糖。
ConardLi
2019/09/08
1.7K0
JS面向对象编程
通过instanceof来判断当前的的对象是否是实例化出来的,如果是实例化出来的this指向实例化出来的对象,也就是这里的Person,否则作为普通函数来说当前的this指向window
小丞同学
2021/08/16
4.1K0
类_TypeScript笔记4
TypeScript里的类的定义与ES6 Class规范一致,静态属性,实例属性,访问器等都支持:
ayqy贾杰
2019/06/12
7640
babel到底将代码转换成什么鸟样?
前言 将babel捧作前端一个划时代的工具一定也不为过,它的出现让许多程序员幸福地用上了es6新语法。但你就这么放心地让babel跑在外网?反正我是不放心,我就曾经过被坑过,于是萌生了研究babel代
李成熙heyli
2018/01/05
2.2K0
babel到底将代码转换成什么鸟样?
【ES6基础】Object的新方法
Object对象可谓是JS的重要核心内容,在你使用JS的过程中,你会发现自己的工作大部分都是在操作对象,ES6、ES7、ES8引入了不少新的方法,本篇文章笔者将带着大家一起熟悉下重点的新方法。
前端达人
2019/06/04
5340
【ES6基础】Object的新方法
相关推荐
ES5的继承和ES6的继承有什么区别?让Babel来告诉你
更多 >
LV.1
某大厂前端开发工程师
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验