八、Vuex详解

Vuex是做什么的?

官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
简单解释:把需要多个组件共享的变量全部存储在一个对象里面,然后将这个对象放在顶层的Vue实例中,让其他组件可以使用,多个组件就可以共享这个对象中的所有变量属性。
Vuex就是为了提供这样一个在多个组件间共享状态的插件。
有什么状态是需要我们在多个组件间共享的呢?
 • 如果你做过大型开放,你一定遇到过多个状态,在多个界面间的共享问题
 • 比如用户的登录状态、用户名称、头像、地理位置信息等等
 • 比如商品的收藏、购物车中的物品等等
 • 这些状态信息,我们都可以放在统一的地方,对它进行保存和管理,而且它们还是响应式的

单界面的状态管理

State:就是我们的状态。(当做data中的属性)
View:视图层,可以针对State的变化,显示不同的信息
Actions:这里的Actions主要是用户的各种操作:点击、输入等等,会导致状态的改变

<template>
  <div>
    <h2>{{counter}}</h2>
    <button @click="counter++">+</button>
    <button @click="counter--">-</button>
  </div>
</template>
<script>
  export default{
    name: 'helloworld',
    data() {
      return {
        counter: 0
      }
    }
  }
</script>

在这个案例中,个数counter的状态需要管理
 • counter需要某种方式被记录下来,也就是我们的State
 • counter目前的值需要被显示在界面中,也就是我们的View部分
 • 界面发生某些操作时(我们这里是用户的点击,也可以是用户的input),需要去更新状态,也就是我们的Actions
在这里插入图片描述

多界面的状态管理

将共享的状态抽取出来,交给我们的大管家,统一进行管理,之后你们的每个试图,按照我规定好的规定,进行访问和修改等操作

  1. 安装插件
npm install vuex --save
  1. 如何使用(Vuex3)

①src下创建文件夹store,创建index.js
②import vue和vuex
③安装插件、创建对象、导出对象

//1.安装插件
Vue.use(Vuex)
//2.创建对象(使用vuex里面的store属性)
const store = new Vuex.Store({
    state:{
          counter: 100 //共享状态
     }, //state保存状态,相当于变量
    mutations:{
          //方法,默认有一个参数state
         increment(state){
              state.counter++
         }
     }, //相当于计算属性 同步操作在这里
    actions:{}, //异步操作发送网络在这里 再提交
    getters:{},
    modules:{}
})
//3.导出store对象
export default store

④在main.js中挂载store
import导入store,并且放在new Vue中写个store,在其他Vue组件中,我们就可以通过this.$store的方式,获取到这个store对象了
⑤第一个组件中使用
在main.js挂载完之后所有的vue组件都有一个$store对象

<h2>{{$store.state.counter}}</h2>

⑥第二个组件中也想使用

<h2>{{$store.state.counter}}</h2>
  1. Devtools
    跟踪state修改状态
  2. mutations
    组件中使用mutations
<button @click="addition">+</button>
<script>
methods:{
  addition() {
     this.$store.commit('increment')
  }
}
</script>

在这里插入图片描述

核心概念

  1. State
    Vuex也使用了单一状态树来管理应用层级的全部状态,单一状态树能够让我们最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护。
  2. Getters

getters类似于computed属性,当数据需要计算后显示的

<script>
getters:{
    powerCount(state){
         return state.counter * state.counter
     }
}
</script>
<h2>{{$store.getters.powerCount}}</h2> <!--属性不需要加小括号-->

getters作为参数

<script>
getters:{
    more20stu(state){
      // 正常写
      /* return state.students.filter(s => {
       return s.age > 20
      }) */
      // 简写
      return state.students.filter(s => s.age > 20)
    },
    more20stuLength(state,getters){
      return getters.more20stu.length
    }
}
</script>
<h2>{{ $store.getters.more20stu }}</h2>
<h2>{{ $store.getters.more20stuLength }}</h2>

getters默认是不能传递参数的,如果希望传递参数,那么只能让getters本身返回另一个函数

<script>
    moreAgeStu(state){
      //正常写法
      /* return function (age){
        return state.students.filter( s => s.age > age )
      }*/
      //箭头函数写法
      return age => {
        return state.students.filter( s => s.age > age )
      }
    }
</script>
<h2>{{ $store.getters.moreAgeStu(25) }}</h2>
  1. Mutation
    Vuex的store状态的更新唯一方式:提交Mutation
    Mutation主要包括两部分:
     • 字符串的事件类型(type)
     • 一个回调函数(handler),该回调函数的第一个参数就是state。

①Mutation传递参数
通过mutation更新

//有参数时,App.vue中
methods: {
	addCount(count) {
	   this.$store.commit('incrementCount',count)
	}
}

//index.js中
mutations: {
  //方法
  incrementCount(state, count){
    state.counter += count
  }
}

<button @click="addCount(5)">+5</button>
<button @click="addCount(10)">+10</button>

②Mutation提交风格
包含type属性的对象

this.$store.commit({
    type: 'changeCount',
    count: 100
})

Mutation中的处理方式是将整个commit的对象作为payload使用, 所以代码没有改变, 依然如下:

changeCount(state, payload){
    state.count = payload.count
}

③Mutation响应规则(Vuex的store中的state是响应式的, 当state中的数据发生改变时, Vue组件会自动更新)
提前在store中初始化好所需的属性(后添加的属性内容不是响应式的).
当给state中的对象添加新属性时, 使用下面的方式(vue2方法):
方式一:使用Vue.set(obj, 'newProp', 123) //三个参数:要改的对象,key(类型可以是字符串或number),value
方式二:用新对象给旧对象重新赋值state.info['height'] = payload.height

//index.js
state: {
  info: {
    name: 't',
    age: 18,
    height: 158
  }
},
mutations: {
    updateInfo(state){
      //修改name属性内容。(是响应式的)
      //state.info.name = 'ti'

      //增加地址属性①。(vue2不是响应式的,vue3是响应式的)✔️
      //state.info['address'] = '洛杉矶'

      //增加地址属性②。(vue2是响应式的,vue3不是响应式的会报错不兼容Vue.set)
      //Vue.set(state.info, 'address', '洛杉矶')

      //删除属性①。(vue2不是响应式的,vue3是响应式的)✔️
      delete state.info.age

      //删除属性②。(vue2是响应式的,vue3不是响应式的会报错不兼容Vue.delete)
      //Vue.delete(state.info, 'age')
    }
}
//App.Vue
<p>{{ $store.state.info }}</p>
<button @click="updateInfo">修改信息</button>
  methods: {
    updateInfo(){
      this.$store.commit('updateInfo')
    }
  }

④使用常量替代 Mutation 事件类型

// mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'

// store.js
import { createStore } from 'vuex'
import { SOME_MUTATION } from './mutation-types'

const store = createStore({
  state: { ... },
  mutations: {
    // 我们可以使用 ES2015 风格的计算属性命名功能来使用一个常量作为函数名
    [SOME_MUTATION] (state) {
      // 修改 state
    }
  }
})

⑤Mutation必须是同步函数

  1. Action
    Action类似于Mutation, 是用来代替Mutation进行异步操作的,默认参数context
    Action方法可以返回promise,在另外一个地方用.dispatch拿到promise
  2. Module
    Vuex允许我们将store分割成模块(Module), 而每个模块拥有自己的state、mutation、action、getters等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值