Vuex核心概念

  1. State
  2. Getters
  3. Mutation
  4. Action
  5. Module

①State单一状态树(单一数据源)

(1)如果状态信息是保存到多个Store对象中,那么之后的管理和维护等等都会变得特别困难
(2)所以Vuex使用了单一状态树来管理应用层级的全部状态
(3)单一状态树能够以最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护。

② Getters 基本使用(类似于组件中的计算属性)

store \index:
import Vue from 'vue'
import Vuex from 'vuex'

// 1. 安装插件
Vue.use(Vuex)

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      { id: 110, name: 'tom', age: 18 },
      { id: 111, name: 'bob', age: 23 },
      { id: 112, name: 'helon', age: 24 },
      { id: 113, name: 'jack', age: 15 }
    ]
  },
  mutations: {
    // 方法
    increment (state) {
      state.counter++
    },
    decrement (state) {
      state.counter--
    }
  },
  actions: {

  },
  modules: {

  },
  getters: {
    // 返回counter的平方 计算属性
    powerCounter (state) {
      return state.counter * state.counter
    },
    more20stu (state) {
      // 获取年龄大于 20 岁的学生
      return state.students.filter(s => s.age > 20)
    },
    // 第二个参数传入的就是一个getters
    more20stuLen (state, getters) {
      return getters.more20stu.length
    },
    moreAgeStu (state) {
      // return function (age) {
      //   return state.students.filter(s => s.age > age)
      // }
      return age => state.students.filter(s => s.age > age)
    }
  }
})

// 3. 导出 store 对象
export default store

App.vue 组件:
<template>
  <div id="app">
    <h2>------------app 内容------------</h2>
    <h2>{{message}}</h2>
    <h2>{{$store.state.counter}}</h2>
    <button @click="addition">+</button>
    <button @click="subtraction">-</button>

    <h2>---------App内容: getters相关信息---------</h2>
    <h2>{{ $store.getters.powerCounter }}</h2>
    <h2>{{$store.getters.more20stu}}</h2>
    <h2>{{$store.getters.more20stuLen}}</h2>
    <h2>{{$store.getters.moreAgeStu(8)}}</h2>
    <h2>-----------hello vuex 内容------------</h2>
    <hello-vuex></hello-vuex>
  </div>
</template>
<script>
import HelloVuex from './components/HelloVuex.vue'
export default {
  name: 'App',
  components: {
    HelloVuex
  },
  data () {
    return {
      message: 'app组件'
    }
  },
  methods: {
    addition () {
      this.$store.commit('increment')
    },
    subtraction () {
      this.$store.commit('decrement')
    }
  }
}
</script>
<style lang="less">

</style>

HelloVuex.vue:
<template>
  <div>
    <h2>{{$store.getters.powerCounter}}</h2>
    <h2>{{$store.getters.more20stu}}</h2>
  </div>
  </template>

<script>
export default {

  name: 'HelloVuex',
  props: {
    counter: Number
  }

}
</script>

<style scoped>

</style>

③Mutations状态更新

●Vuex的store状态的更新唯一方式:提交Mutation
●Mutation主要包括两部分:
    ▲ 字符串的事件类型(type)
    ▲ 一个回调函数(handler),该回调函数的第一个参数就是state
● mutation的定义方式:

mutations: {
	increment() {
		state.count++
	}
}

● 通过mutation更新

addition () { 
	this.$store.commit('increment')
}
vuex-mutations传参数

①vuex-mutations携带参数

App组件

<template>
  <div id="app">
    <h2>------------app 内容 mutations------------</h2>
    <h2>{{message}}</h2>
    <h2>{{$store.state.counter}}</h2>
    <button @click="addition">+</button>
    <button @click="subtraction">-</button>
    <button @click="addCount(5)">+5</button>
    <button @click="addCount(10)">+10</button>
    <button @click="addStudent">添加学生</button>
    <h2>---------App内容: getters相关信息---------</h2>
    <h2>{{ $store.getters.powerCounter }}</h2>
    <h2>{{$store.getters.more20stu}}</h2>
    <h2>{{$store.getters.more20stuLen}}</h2>
    <h2>{{$store.getters.moreAgeStu(8)}}</h2>
    <h2>-----------hello vuex 内容------------</h2>
    <hello-vuex></hello-vuex>
  </div>
</template>
<script>
import HelloVuex from './components/HelloVuex.vue'
export default {
  name: 'App',
  components: {
    HelloVuex
  },
  data () {
    return {
      message: 'app组件'
    }
  },
  methods: {
    addition () {
      this.$store.commit('increment')
    },
    subtraction () {
      this.$store.commit('decrement')
    },
    addCount (count) {
      // 参数被称为是mutation的 载荷payload: 负载 
      this.$store.commit('incrementCount', count)
    },
    addStudent () {
      const stu = { id: 114, name: 'baicai', age: 18 }
      return this.$store.commit('addStudent', stu)
    }
  }
}
</script>
<style lang="less">

</style>

import Vue from 'vue'
import Vuex from 'vuex'

// 1. 安装插件
Vue.use(Vuex)

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      { id: 110, name: 'tom', age: 18 },
      { id: 111, name: 'bob', age: 23 },
      { id: 112, name: 'helon', age: 24 },
      { id: 113, name: 'jack', age: 15 }
    ]
  },
  mutations: {
    // 方法
    increment (state) {
      state.counter++
    },
    decrement (state) {
      state.counter--
    },
    incrementCount (state, count) {
      state.counter += count
    },
    addStudent (state, stu) {
      state.students.push(stu)
    }
  },
  actions: {

  },
  modules: {

  },
  getters: {
    powerCounter (state) {
      return state.counter * state.counter
    },
    more20stu (state) {
      return state.students.filter(s => s.age >= 20)
    },
    more20stuLen (state, getters) {
      return getters.more20stu.length
    },
    moreAgeStu (state) {
      // return function (age) {
      //   return state.students.filter(s => s.age > age)
      // }
      return age => state.students.filter(s => s.age > age)
    }
  }
})

// 3. 导出 store 对象
export default store

mutations的提交风格
除了普通的提交方式Vue还提供了另外一种风格,它是一个包含type属性的对象

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

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

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

Mutation响应规则
Vuex的store中的state是响应式的,当state中的数据发生改变时,Vue组件会自动更新
当给state中的对象添加新属性时,使用下面的方式:
    方式一: 使用Vue.set(obj, ‘newProp’, 123)
    方式二: 用新对象给就对象重新赋值
在这里插入图片描述

响应式方法: 可以做到响应式

import Vue from 'vue'
import Vuex from 'vuex'

// 1. 安装插件
Vue.use(Vuex)

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      { id: 110, name: 'tom', age: 18 },
      { id: 111, name: 'bob', age: 23 },
      { id: 112, name: 'helon', age: 24 },
      { id: 113, name: 'jack', age: 15 }
    ],
    info: {
      name: 'kobe',
      age: 40,
      height: 1.98
    }
  },
  mutations: {
    // 方法
    increment (state) {
      state.counter++
    },
    decrement (state) {
      state.counter--
    },
    incrementCount (state, payload) {
      console.log(payload)
      state.counter += payload.count
    },
    addStudent (state, stu) {
      state.students.push(stu)
    },
    changeName (state) {
      // state.info.name = 'xiongmao'
      // state.info.address = 'ooo' 这种方法并没有将address添加到响应式系统里面
      // 该方法是将address 添加到响应式系统里面
      // Vue.set(state.info, 'address', 'ooo')
      // 该方式做不到响应式
      // delete state.info.age
      // 该方法可以做到响应式
      Vue.delete(state.info, 'age')
    }
  },
  actions: {

  },
  modules: {

  },
  getters: {
    powerCounter (state) {
      return state.counter * state.counter
    },
    more20stu (state) {
      return state.students.filter(s => s.age >= 20)
    },
    more20stuLen (state, getters) {
      return getters.more20stu.length
    },
    moreAgeStu (state) {
      // return function (age) {
      //   return state.students.filter(s => s.age > age)
      // }
      return age => state.students.filter(s => s.age > age)
    }
  }
})

// 3. 导出 store 对象
export default store


Vuex-mutations类型常量
抽取常量

	export const INCREMENT = 'increment'

引用常量

	import { INCREMENT } from './mutations-type.js'
	[INCREMENT] (state) {
		state.info.name = 'coo'
	}

commit() 函数 发送请求

import { INCREMENT } from './store/mutations-type.js'
increment() {
	this.$store.commit(INCREMENT)
}

App.vue


<template>
  <div id="app">
    <h2>-------------App内容: info对象的内容是否是响应式的---------</h2>
    <h2>{{ $store.state.info }}</h2>
    <button @click="updateInfo">点击改变name内容</button>
    <h2>------------app 内容 mutations------------</h2>
    <h2>{{ message }}</h2>
    <h2>{{ $store.state.counter }}</h2>
    <button @click="addition">+</button>
    <button @click="subtraction">-</button>
    <button @click="addCount(5)">+5</button>
    <button @click="addCount(10)">+10</button>
    <button @click="addStudent">添加学生</button>

    <h2>---------App内容: getters相关信息---------</h2>
    <h2>{{ $store.getters.powerCounter }}</h2>
    <h2>{{ $store.getters.more20stu }}</h2>
    <h2>{{ $store.getters.more20stuLen }}</h2>
    <h2>{{ $store.getters.moreAgeStu(8) }}</h2>
    <h2>-----------hello vuex 内容------------</h2>
    <hello-vuex></hello-vuex>
  </div>
</template>
<script>
import HelloVuex from './components/HelloVuex.vue'
import { INCREMENT } from './store/mutations-types'
export default {
  name: 'App',
  components: {
    HelloVuex
  },
  data () {
    return {
      message: 'app组件'
    }
  },
  methods: {
    addition () {
      this.$store.commit(INCREMENT)
    },
    subtraction () {
      this.$store.commit('decrement')
    },
    addCount (count) {
      // 1.普通的提交封装
      // this.$store.commit('incrementCount', count)
      // 2. 特殊的提交封装
      this.$store.commit({
        // 事件类型
        type: 'incrementCount',
        count
      })
    },
    addStudent () {
      const stu = { id: 114, name: 'baicai', age: 18 }
      return this.$store.commit('addStudent', stu)
    },
    updateInfo () {
      return this.$store.commit('changeName')
    }
  }
}
</script>
<style lang="less">
</style>

mutations-type.js

export const INCREMENT = 'increment'

/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import { INCREMENT } from './mutations-types.js'
// 1. 安装插件
Vue.use(Vuex)

// 2. 创建对象
const store = new Vuex.Store({
  state: {
    counter: 1000,
    students: [
      { id: 110, name: 'tom', age: 18 },
      { id: 111, name: 'bob', age: 23 },
      { id: 112, name: 'helon', age: 24 },
      { id: 113, name: 'jack', age: 15 }
    ],
    info: {
      name: 'kobe',
      age: 40,
      height: 1.98
    }
  },
  mutations: {
    // 方法
    [INCREMENT] (state) {
      state.counter++
    },
    decrement (state) {
      state.counter--
    },
    incrementCount (state, payload) {
      console.log(payload)
      state.counter += payload.count
    },
    addStudent (state, stu) {
      state.students.push(stu)
    },
    changeName (state) {
      // state.info.name = 'xiongmao'
      // state.info.address = 'ooo' 这种方法并没有将address添加到响应式系统里面
      // 该方法是将address 添加到响应式系统里面
      // Vue.set(state.info, 'address', 'ooo')
      // 该方式做不到响应式
      // delete state.info.age
      // 该方法可以做到响应式
      Vue.delete(state.info, 'age')
    }
  },
  actions: {

  },
  modules: {

  },
  getters: {
    powerCounter (state) {
      return state.counter * state.counter
    },
    more20stu (state) {
      return state.students.filter(s => s.age >= 20)
    },
    more20stuLen (state, getters) {
      return getters.more20stu.length
    },
    moreAgeStu (state) {
      // return function (age) {
      //   return state.students.filter(s => s.age > age)
      // }
      return age => state.students.filter(s => s.age > age)
    }
  }
})

// 3. 导出 store 对象
export default store

注意: 尽量不要在mutations里面进行异步操作

④vuex-actions的使用

1.如果在mutations里面直接写异步程序,
例如

 changeName() {
 	setTimeout(() => {
        state.info.name = 'oookkk'
      }, 1000)
    }

那么vue调试工具将跟踪不到数据的变化state中记录的信息将会变成错误的信息,没有实时更新
注意: 尽量不要在mutations里面进行异步操作
在这里插入图片描述
在这里插入图片描述
如果有异步操作,vue组件通过dispatch("") Action要执行的函数,
然后Action函数里面要commit 提交mutations通过mutations修改state

App组件

  updateInfo () {
      return this.$store.dispatch('aUpdateInfo')
    }

/store/index.js

  actions: {
    // context 上下文
    aUpdateInfo (context) {
      setTimeout(() => {
        context.commit('changeName')
      }, 1000)
    }
  }

mutations

	mutations: {
    // 方法
    [INCREMENT] (state) {
      state.counter++
    },
    decrement (state) {
      state.counter--
    },
    incrementCount (state, payload) {
      console.log(payload)
      state.counter += payload.count
    },
    addStudent (state, stu) {
      state.students.push(stu)
    },
    changeName (state) {
      state.info.name = 'xiongmao'
      // state.info.address = 'ooo' 这种方法并没有将address添加到响应式系统里面
      // 该方法是将address 添加到响应式系统里面
      // Vue.set(state.info, 'address', 'ooo')
      // 该方式做不到响应式
      // delete state.info.age
      // 该方法可以做到响应式
      // Vue.delete(state.info, 'age')
      // setTimeout(() => {
      //   state.info.name = 'oookkk'
      // }, 1000)
    }
  },

dispatch 传参问题

方法一
App.vue:

updateInfo() {
	this.$store.dispatch('aUpdateInfo', {
		message: '携带的信息',
		success: () => {
			console.log('success')
		}
	}
}

action

  actions: {
    // context 上下文
    aUpdateInfo (context, payload) {
      setTimeout(() => {
        context.commit('changeName')
        // 回调函数
        payload()
      }, 1000)
    }
  }

方法二:优雅写法
App.vue

updateInfo() {
	this.$store.dispatch('aUpdateInfo', '传递的信息').then(res => {
        console.log('里面完成了提交')
        console.log(res)
      })
}

action


aUpdateInfo (context, payload) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          context.commit('changeName')
          console.log(payload)
          resolve('resolve')
        }, 1000)
      })
    }

⑤vuex-modules的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值