Vuex 应用总结

vuex

在这里插入图片描述

什么情况下使用vuex

构建中大型单页面应用,如果是简单的应用一般不需要使用Vuex,使用它可能是繁琐冗余的。

创建一个简单的store

1.Vuex的状态存储是响应式的,当Vue 组件从store中读取状态的时候,store变化,对应的组件也会更新。
2.不能直接改变store中的状态,想要改变它唯一的途径就是通过 commit 提交 mutation,这样可以方便跟踪每一个状态的变化。

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

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

接下来我们可以通过 store.state 来获取状态对象,以及通过store.commit 方法触发状态变更:

store.commit('increment')

为了在vue组件中访问store,vue提供了一个从跟组件向所有子组件,以store选项注入的机制:

new Vue({
  el: '#app',
  store: store,
  // es6简写
  store
})

特别要注意的是,推荐通过提交mutation的方式来改变状态的值,不建议直接通过store.state.count来进行改变。

1.state

state 是Vuex中的基本数据!
state 就是用来存放数据,若是对数据进行处理输出,比如数据要过滤,一般我们可以写到computed中。但是如果很多组件都使用这个过滤后的数据,这就是getter存在的意义。我门可以认为,getter是store的计算属性。

2.getters
1.基础用法:

main.js

const store  = new Vuex.store({
	state: {
		list:[1,2,3,4,5,12,23,34]
	},
	getters: {
		filterList:state => {
			return state.list.filter(item => item > 5)
		}
	}
})

index.vue

<script>
  export default {
    name: "index.vue",
    computed: {
      list() {
        return this.$store.getters.filteredList;
      }
    }
  }
</script>
2.内部依赖

getter 可以依赖已经定义好的getter。比如我们需要统计过滤后的数量,就可以依赖之前定义好的过滤函数。

const store = new Vuex.Store({
  state: {
    list: [1, 3, 5, 7, 9, 20, 30]
  },
  getters: {
    filteredList: state => {
      return state.list.filter(item => item > 5)
    },
    listCount: (state, getters) => {
      return getters.filteredList.length;
    }
  }
})

取的时候和上面一样

<template>
 
  <div>
    过滤后的列表:{{list}}
    <br>
    列表长度:{{listCount}}
  </div>
</template>
 
<script>
  export default {
    name: "index.vue",
    computed: {
      list() {
        return this.$store.getters.filteredList;
      },
      listCount() {
        return this.$store.getters.listCount;
      }
    }
  }
</script>
3.mutation (提交更改数据的方法,同步!必须是同步):

使用vuex修改 state 时,有两种方式:

  1. 可以直接修改this.$store.state.XXX = xxx
  2. this.$store.dispatch(actionType, payload)或者 this. $store.commit(commitType, payload)
const store = new Vuex.Store({
  strict: true,            //    strict: true, 若开启严格模式只要不经过 mutation的函数,则会报错
  state: {
    cartNum: 0,          // 购物车数量
  },
  mutations: {
    // 加1
    INCREMENT(state) {
      state.cartNum++;
    },
  }
})
methods: {
      addCarts () {
                baseStore.commit('INCREMENT')
     },	    
}

异同点:
1)共同点: 能够修改state里的变量,并且是响应式的(能触发视图更新)
2)不同点:
若将vue创建 store 的时候传入 strict: true, 开启严格模式,那么任何修改state的操作,只要不经过 mutation的函数。

vue就会  throw error :    [vuex] Do not mutate vuex store state outside mutation handlers。
4.action (像一个装饰器,包裹mutations,使之可以异步)

action的功能和mutation是类似的,都是去变更store里的state,不过action和mutation有两点不同:
1.action主要处理的是异步操作,mutation必须同步执行,action既可以处理同步,也可以处理异步操作。
2.action 改变状态,最后是通过提交mutation

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      setInterval(function(){
        context.commit('increment')
      }, 1000)
    }
  }
})

注意:Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。

分发actions
store.dispatch('increment')
action和mutation的区别

Muation与Action作用是相同的,官网上说Mutation 必须是同步函数,Action处理异步函数。我觉得这是因为在vue devtool调试工具状态管理中,如果Mutation是异步函数,mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用就会导致devtool中状态管理不可追踪,这个问题就会导致调试非常难。而在action中的异步函数中提交mutation是可以追踪状态的。
总的来说,使用devtool调试,异步函数在muation中状态是不可追踪的,在action中状态是可以追踪的。如果你不使用devtool两者其实就是一样的,只不过mutation函数第一个参数是state,action 函数接受一个与 store 实例具有相同方法和属性的 context 对象。

5.modules (模块化Vuex)

在Vue 中state使用的是单一的状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将变得非常大,难于管理。
module:可以让每一个模块拥有自己的state,mutation,action,getters,使得结构非常清晰,方便管理。

const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
命名空间

默认情况下,模块内部的action,mutation和getter是注册在全局命名空间的—这样使得多个模块能够对同一mutation或action做出响应。
如果希望你的模块具有更高的封装度和复用性,你可以通过添加 namespaced:true的方式使其成为带命名空间的模块。当模块被注册后,它的所有getter,action以及mutation都会自动根据模块注册的路径调整命名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值