1-Vuex是什么
专为Vue.js应用程序开发的状态管理模式,采用集中式存储管理应用的所有组件的状态,以相应的规则保证状态以一种可预测的方式发生变化。
- Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
- 你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
- 状态
组件内部状态 : 仅在一个组件内使用的状态(data字段)
应用级别状态 : 多个组件共用的状态
- 什么情况下使用Vuex
多个视图依赖于同一状态
来自不同视图的行为需要变更同一状态
- 使用Vuex(在src中新建store文件夹=》index.js)
- 安装vuex模块 : npm install vuex --save
- 作为插件使用: Vue.use(Vuex)
- 定义容器:new Vuex.Store()
- 注入根实例
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
//定义一个容器
let store = new Vuex.Store({
})
export default store
//main.js
import store from './store/'
new Vue({
el: '#app',
router,
store,//注入
components: { App },
template: '<App/>'
})
image.png
2-Vuex核心概念
- store : 类似容器,包含应用的大部分状态
- 一个页面只能有一个store
- 状态存储是响应式的
- 不能直接改变store中的状态,唯一途径是显示的提交mutations
- State:包含所有应用级别的状态的对象```
- Getters:在组件内部获取store中状态的函数
- Mutations:唯一修改状态的事件回调函数
- Actions:包含异步操作、提交mutation改变状态
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
mutations : {
addIncrement(state,payload){
state.count += payload.n
},
deIncrement(state,payload){
state.count -= payload.de
}
},
//异步操作、提交mutation改变状态,提交mutations
actions : {
addAction(context){
setTimeout(() => {
//改变状态,提交mutations
context.commit('addIncrement',{
n : 5
})
}, 1000);
}
}
addHandel(){
//触发一个action
this.$store.dispatch('addAction')
},
- Modules:将store分割成不同的模块
- 我的总结:数据统一放在state中,然后对于数据的处理,都统一在mutations中,接着在组件内部,绑定函数,触发mutations中的函数。
//定义一个容器
let store = new Vuex.Store({
state:{
count : 100
},
//唯一修改状态的事件回调函数
mutations : {
addIncrement(state){
state.count += 1
}
}
})
//组件内
export default {
computed: {
num(){
//获取状态
return this.$store.state.count
}
},
methods: {
addHandel(){
//改变状态,需要提交mutation : addIncrement
this.$store.commit('addIncrement')
}
}
}
3-实例分析Vuex流程
vuex流程图图解 :先从拿数据开始分析,拿数据就牵涉到异步操作,我们把异步操作定义在action中去,在页面中去触发一个action,action里面有一个ajax请求的后端接口,拿到数据后要渲染到页面中,只需要去改变状态(state)即可,然后就会重新的渲染到页面中去,所以拿到数据之后需要提交一个mutation,因为vuex中有一个原则:想改变状态,必须要提交一个mutation,然后在调试工具中就会监控一下提交的状态,所以我们想看上一个下一个状态就会很方便,vuex是响应的,状态一旦发生改变就会重新渲染组件。
基本使用
由于 store 中的状态是响应式的,在组件中调用 store 中的状态简单到仅需要在计算属性中返回即可。
computed: {
num(){
return this.$store.state.count
}
}
触发变化也仅仅是在组件的 methods 中提交 mutation。
methods: {
addHandel(){
//改变状态,需要提交mutation : addIncrement
// this.$store.commit('addIncrement',{
// n:5
// })
//触发一个action
this.$store.dispatch('addAction')
},
deHandel(){
//this.$store.commit('deIncrement')
this.$store.commit({
type : 'deIncrement',
de : 10
})
}
}
4-官网API摘要
1. 在 Vue 组件中获得 Vuex 状态
那么我们如何在 Vue 组件中展示状态呢?由于 Vuex 的状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态,每当 store.state.count 变化的时候, 都会重新求取计算属性,并且触发更新相关联的 DOM。
// 创建一个 Counter 组件
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return $store.state.count
}
}
}
2. Action
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
让我们来注册一个简单的 action:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit
提交一个 mutation,或者通过 context.state
和 context.getters
来获取 state 和 getters。当我们在之后介绍到 Modules时,你就知道 context 对象为什么不是 store 实例本身了。
实践中,我们会经常用到 ES2015 的 参数解构 来简化代码(特别是我们需要调用 commit
很多次的时候):
actions: {
increment ({ commit }) {
commit('increment')
}
}
3. Getter(类似计算属性)
在vue中,我们需要对变量进行进一步处理,可以放在computed里,不建议放在模板中,同样,vuex中,state中的状态如果需要进一步处理,我们可以放入getters.
//vuex中
getters:{
filterCount(state){
return state.count >= 120 ? 120 : state.count
}
}
//组件中
computed: {
num2(){
return this.$store.getters.filterCount
}
}
4-辅助函数
- mapState
- mapGetters
- mapMutations
- mapActions
import {mapState,mapGetters,mapActions,mapMutations} from 'vuex'
以下是两种写法的对比
computed: {
num(){
return this.$store.state.count
},
num2(){
return this.$store.getters.filterCount
}
}
===================================
computed: {
...mapState(['count']) ,
...mapGetters({
num2:'filterCount'
})
}
addHandel(){
//改变状态,需要提交mutation : addIncrement
this.$store.commit('addIncrement',{
n:5
})
//触发一个action
this.$store.dispatch('addAction')
},
deHandel(){
//this.$store.commit('deIncrement')
this.$store.commit({
type : 'deIncrement',
de : 10
})
}
============================
...mapActions({
deHandel :'addIncrement'
}),
...mapMutations({
addHandel:'deIncrement' //传参在模板上即可
})
网友评论