当前位置:   article > 正文

Vuex ——详细介绍

vuex

Vuex 是一个专门为 Vue.js 应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件状态,并以相应的规则保证状态以一种可预测的方式发生变化。可以理解为:将多个组件共享的变量全部存储在一个对象里面,然后将这个对象放在顶层的 Vue 实例中,让其他组件可以使用,它最大的特点是响应式。

一般情况下,我们会在 Vuex 中存放一些需要在多个界面中进行共享的信息。比如用户的登录状态、用户名称、头像、地理位置信息、商品的收藏、购物车中的物品等,这些状态信息,我们可以放在统一的地方,对它进行保存和管理。

Vuex 插件的安装

npm install --save vuex@3.6.2

注意版本问题:vue 的 2.x 版本对应 vuex 的 3.x 版本,vue 的 3.x 版本对应 vuex 的 4.x 版本

在 src 目录下新建 store 文件夹,创建 index.js文件引入、安装、创建并导出Vuex对象。

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. //1.安装插件
  4. Vue.use(Vuex)
  5. //2.创建对象
  6. const store = new Vuex.Store({
  7. state:{
  8. counter:1000
  9. },
  10. mutations:{
  11. },
  12. actions:{
  13. },
  14. getters:{
  15. },
  16. modules:{
  17. }
  18. })
  19. //3.导出使用
  20. export default store

vue-router 的使用方式一样,在 main.js 文件中挂载使用

  1. import Vue from 'vue'
  2. import App from './App'
  3. import router from './router'
  4. import store from './store'
  5. Vue.config.productionTip = false
  6. /* eslint-disable no-new */
  7. new Vue({
  8. el: '#app',
  9. router,
  10. store,
  11. render: h => h(App)
  12. })

store 对象中存放的东西是固定的,主要有:state、mutations、actions、getters、modules

下图是官方给出的vuex状态管理图例

Vuex的基本使用

安装浏览器插件:devtools 方便调试 

state:存放需要共享的状态信息,使用时通过 $store.state.counter 即可拿到状态信息。

对 state 的状态信息进行修改:先拿到 store 对象,然后通过 commit 提交 mutations 中的方法。

使用 devtools 调试界面,可以跟踪查看每一次事件操作。 

 Vuex 核心概念

State:

单一状态树即单一数据源,在一个项目中只使用一个store对象,来存储所有共享的状态信息。

Getters:

类似于计算属性,在数据展示前进行一些变化处理,具有缓存功能,能够提高运行效率。eg:

  1. getters:{
  2. powerCounter(state){
  3. return state.counter * state.counter
  4. },
  5. more20stu(state){
  6. return state.students.filter(s => s.age > 20)
  7. },
  8. more20stuLength(state,getters){
  9. return getters.more20stu.length
  10. },
  11. moreAgeStu(state){
  12. return function(age){
  13. return state.students.filter(s => s.age > age)
  14. }
  15. }
  16. }

使用时,通过:$store.getters.powerCounter 获取:

  1. <h2>{{$store.getters.powerCounter}}</h2>
  2. <h2>{{$store.getters.more20stu}}</h2>
  3. <h2>{{$store.getters.more20stuLength}}</h2>
  4. <h2>{{$store.getters.moreAgeStu(18)}}</h2>

需要手动传参数时,可以在 getters 中返回一个 function:eg

  1. moreAgeStu(state){
  2. return function(age){
  3. return state.students.filter(s => s.age > age)
  4. }
  5. }

调用时传入参数即可: 

<h2>{{$store.getters.moreAgeStu(18)}}</h2>

Mutations:

store/index.js

  1. mutations:{//定义一些方法
  2. increment(state){
  3. state.counter++
  4. },
  5. decrement(state){
  6. state.counter--
  7. },
  8. incrementCount(state, payload){
  9. //1.普通提交方式
  10. //state.counter += count
  11. //2.特殊提交方式
  12. state.counter += payload.count
  13. },
  14. addStudent(state, obj){
  15. state.students.push(obj)
  16. }
  17. }

组件调用 :传递的参数(payload)可以是一个对象

  1. <template>
  2. <div>
  3. <button @click="addCount(5)">+5</button>
  4. <button @click="addCount(10)">+10</button>
  5. <button @click="addStudent({id:105, name:'name6', age:29})">添加学生</button>
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. name:"HelloVuex",
  11. methods:{
  12. addCount(count){
  13. //1.普通的提交风格
  14. // this.$store.commit('incrementCount',count)
  15. //2.特殊的提交风格
  16. this.$store.commit({
  17. type:'incrementCount',
  18. count:count
  19. })
  20. },
  21. addStudent(stu){
  22. this.$store.commit('addStudent',stu)
  23. }
  24. }
  25. }
  26. </script>
  27. <style>
  28. </style>

 mutations在处理异步操作时,能够引起页面的响应式变化,但是 devtools 无法进行监听。

 比如:在 mutations 中执行以下代码

  1. updateInfo(state){
  2. setTimeout(() => {
  3. state.info.name = 'James'
  4. }, 1000);
  5. }

Actions:

如果确实需要进行一些异步操作,比如网络请求,建议在 Actions 中进行处理,这样 devtools 就能够进行跟踪,由 Actions 处理异步操作,具体的函数部分仍交由 Mutations 进行处理。

  1. actions:{
  2. //context:上下文 === store
  3. aUpdateInfo(context,payload){
  4. setTimeout(() => {
  5. context.commit('updateInfo',payload)
  6. console.log(payload);
  7. }, 5000);
  8. }
  9. }

组件中使用时,调用:this.$store.dispatch('aUpdateInfo') 

  1. updateInfo(){
  2. // this.$store.commit('updateInfo')
  3. this.$store.dispatch('aUpdateInfo','参数')
  4. }

 结合Promise使用:

  1. actions:{
  2. //context:上下文 === store
  3. aUpdateInfo(context, payload){
  4. return new Promise((resolve, reject)=>{
  5. setTimeout(() => {
  6. context.commit('updateInfo');
  7. console.log(payload);
  8. resolve('11111')
  9. }, 1000);
  10. })
  11. }
  12. }
  1. updateInfo(){
  2. // this.$store.commit('updateInfo')
  3. this.$store
  4. .dispatch('aUpdateInfo','参数')
  5. .then(res =>{
  6. console.log('里面完成了提交');
  7. console.log(res);
  8. })
  9. }

Modules:

分模块管理数据

  1. const moduleA = {
  2. state:{
  3. name: 'moduleA'
  4. },
  5. mutations:{
  6. updateName(state,payload){
  7. state.name = payload
  8. }
  9. },
  10. getters:{
  11. fullname(state){
  12. return state.name + '1111'
  13. },
  14. fullname2(state, getters){
  15. return getters.fullname + '2222'
  16. },
  17. fullname3(state, getters, rootState){
  18. //传入第三个参数:rootState为上一个store对象中的state
  19. return getters.fullname2 +rootState.counter
  20. }
  21. },
  22. actions:{
  23. aUpdateName(context){//context 中 的commit只指向该模块中的mutations
  24. setTimeout(() => {
  25. context.commit('updateName','xiaowang')
  26. console.log(context)
  27. },
  28. const store = new Vuex.Store({
  29. state:{
  30. counter:1000,
  31. students:[
  32. {id:110, name: 'name1', age: 12},
  33. {id:111, name: 'name2', age: 21},
  34. {id:112, name: 'name3', age: 22},
  35. {id:113, name: 'name4', age: 20},
  36. {id:114, name: 'name5', age: 18}
  37. ],
  38. info:{
  39. name: 'kobe',
  40. age: 40,
  41. height: 1.89
  42. }
  43. },
  44. mutations:{//定义一些方法
  45. increment(state){
  46. state.counter++
  47. },
  48. decrement(state){
  49. state.counter--
  50. },
  51. incrementCount(state, payload){
  52. //1.普通提交方式
  53. //state.counter += count
  54. //2.特殊提交方式
  55. state.counter += payload.count
  56. },
  57. addStudent(state, obj){
  58. state.students.push(obj)
  59. },
  60. updateInfo(state){
  61. state.info.name = 'Jams'//响应式:事先定义过的为响应式
  62. // state.info['address'] = 'chengdu'//响应式
  63. // Vue.set(state.info,'address1','Asgin')//响应式
  64. // delete state.info.age//响应式
  65. // Vue.delete(state.info,'height')//响应式
  66. }
  67. },
  68. getters:{
  69. powerCounter(state){
  70. return state.counter * state.counter
  71. },
  72. more20stu(state){
  73. return state.students.filter(s => s.age > 20)
  74. },
  75. more20stuLength(state,getters){
  76. return getters.more20stu.length
  77. },
  78. moreAgeStu(state){
  79. return function(age){
  80. return state.students.filter(s => s.age > age)
  81. }
  82. }
  83. },
  84. actions:{
  85. //context:上下文 === store
  86. aUpdateInfo(context, payload){
  87. return new Promise((resolve, reject)=>{
  88. setTimeout(() => {
  89. context.commit('updateInfo');
  90. console.log(payload);
  91. resolve('11111')
  92. }, 1000);
  93. })
  94. }
  95. },
  96. modules:{
  97. a: moduleA
  98. }
  99. })

组件中使用 :$store.state.a

  1. <h2>Modules中的内容</h2>
  2. <h2>{{$store.state.a.name}}</h2>
  3. <button @click="updateName">修改模块ModuleA中的名字</button>
  4. <h2>{{$store.getters.fullname3}}</h2>
  5. <button @click="aupdateName">actions修改name</button>

执行模块中的方法 :直接 $store.commit 提交,故 mutations 之间定义的方法名不能重复。

  1. updateName(){
  2. this.$store.commit('updateName','lisa')
  3. },
  4. aupdateName(){
  5. this.$store.dispatch('aUpdateName')
  6. }

打印出的 context 信息如下:

 包含根状态下的一些 state (rootState) 和 mutations (rootMutations)。 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/257134
推荐阅读
相关标签
  

闽ICP备14008679号