前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue状态管理模式:Vuex入门教程

Vue状态管理模式:Vuex入门教程

作者头像
德顺
发布2020-11-12 10:23:49
1.7K0
发布2020-11-12 10:23:49
举报
文章被收录于专栏:前端资源前端资源

什么是 Vuex ?

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

使用 Vue CLI 脚手架安装的 Vue 3.0 已经默认集成了 Vuex,下面记录的是 Vue 2.0 安装使用 Vuex 教程。

安装:

npm:

代码语言:javascript
复制
npm install vuex --save

yarn:

代码语言:javascript
复制
yarn add vuex

通过 Vue.use() 安装:

代码语言:javascript
复制
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

状态管理

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

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态
  • 对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。
  • 对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码

我们可以把组件的共享状态抽取出来,以一个全局单例模式管理。

开始使用:

安装 Vuex 之后,在 /src 目录下 创建一个 store 文件夹,然后在该文件夹内创建一个 index.js 文件。

./src/store/index.js:

代码语言:javascript
复制
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

然后在 /main.js 中引入并初始化 sotre :

代码语言:javascript
复制
import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  store: store,
}).$mount('#app')

这样就可以在任意页面调用 store 中的参数了:

代码语言:javascript
复制
console.log(this.$store.state.count)
# 0

核心实现:

每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:

Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

State、Getter、Mutation、Action、Module

代码语言:javascript
复制
export default new Vuex.Store({
  modules: {
    
  },
  state: {
    
  },
  getters: {
    
  },
  mutations: {
    
  },
  actions: {
    
  }
})

State 单一状态树:

Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

代码语言:javascript
复制
this.$store.state.<name>

最佳实践:使用计算属性获得每次 state 中变化 :

代码语言:javascript
复制
computed: {
  titleName () {
    return this.$store.state.name
  }
},

mapState 辅助函数:

作用:帮助我们生成计算属性

代码语言:javascript
复制
import { mapState } from 'vuex'

computed: {
  titleName () {
    return this.$store.state.name
  },
  ...mapState(['name', 'url'])
},

注意:建议仅将全局使用的属性放入 state,局部变量或组件级变量还是放入局部或组件作用域中。

Getter :

store 的 computed 可以接受两个参数:state、getters:

代码语言:javascript
复制
getters: {
  countAdd: (state, getters) => (num) => {
    return state.count + num
  },
  countRise: (state, gettters) => (num) => {
    return state.count * num + gettters.countAdd(5)
  }
},

mapGetters 辅助函数:

代码语言:javascript
复制
import { mapGetters } from 'vuex'

//默认名称
...mapGetters(['countAdd', 'countRise']),

//自定义名称
...mapGetters({
  myRise: 'countRise'
})

Mutation、Action Mutation(译:突变):

  • 作用:更改 Vuex 的 store 中的状态
  • 特点:只支持同步
  • 调用方式
代码语言:javascript
复制
store.commit('mutationFunc')

payload(state,option):

state为要改变的state对象,option为参数对象(负载对象)

代码语言:javascript
复制
//定义
mutations: {
  increment (state, payload) {
    state.count += payload.amount
  }
}
代码语言:javascript
复制
//调用
store.commit('increment', {
  amount: 10
})

建议: 使用常量替代 Mutation 事件类型

代码语言:javascript
复制
mutations: {
  SOME_MUTATION_1 (state, options) {
    //...
  }
  SOME_MUTATION_2 (state, options) {
    //...
  }
}

注意: Mutation 必须是同步函数

mapMutations 辅助函数:

提交mutations:

  1. 直接使用store提交
代码语言:javascript
复制
this.$store.commit('SOME_MUTATION_1')
  1. 在methods中使用mapMutations辅助函数
代码语言:javascript
复制
import { mapMutations } from 'vuex'

//methods
methods: {
  //注册
  ...mapMutations(['CHANGE_NAME']),
  //按钮点击
  btnClick: function () {
    this.CHANGE_NAME({ name: 'newName' })
  }
}

Action(译:行动):

  • 作用:Action 提交的是 mutation,而不是直接变更状态
  • 特点:支持异步操作
  • 分发 Action
  • 通过 store.dispatch 方法触发:
代码语言:javascript
复制
this.$store.dispatch('changeNameAction', { name: 'XXX' })
  1. 通过mapActions
代码语言:javascript
复制
import { mapActions } from 'vuex'

...mapActions(['changeNameAction']),
this.changeNameAction({ name: 'WTF' })
  • 组合 Action
代码语言:javascript
复制
actionA: ({ commit }, option) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      commit('CHANGE_NAME', option)
      console.log('运行了actionA')
      resolve()
    }, 3000)
  })
},
actionB: ({ commit }, option) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      commit('CHANGE_NAME', option)
      console.log('运行了actionB')
      resolve()
    }, 5000)
  })
},
actionC: async ({ commit, dispatch }, option) => {
  await dispatch('actionA', option)
  await dispatch('actionC', { name: 'CCC' })
}
代码语言:javascript
复制
...mapActions(['actionC']),
this.actionC({ name: 'AAA' })
//结果?

Modules

作用:store为单一对象,内容过多,影响执行效率及代码量过多 解决:分包(模块) 1.创建modules目录,以业务区分不同文件进行模块划分

代码语言:javascript
复制
src
|__store
    |__index.js
    |__modules
        |__sectionA.js
        |__sectionB.js
        |__sectionC.js
        |__...

2.store/index.js中modules引入

代码语言:javascript
复制
import sectionA from './modules/sectionA'
import sectionB from './modules/sectionB'
import sectionC from './modules/sectionC'

export default new Vuex.Store({
  modules: {
    sectionA,
    sectionB,
    sectionC
  },
})
模块动态注册
代码语言:javascript
复制
store.registerModule('sectionA', {
  // ...
})

store.registerModule(['sectionB','sectionC'], {
  // ...
})

未经允许不得转载:w3h5 » Vue状态管理模式:Vuex入门教程

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 Vuex ?
  • 安装:
  • 状态管理
  • 开始使用:
  • 核心实现:
  • mapState 辅助函数:
  • Getter :
  • mapGetters 辅助函数:
  • Mutation、Action Mutation(译:突变):
  • mapMutations 辅助函数:
    • 模块动态注册
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档