vuex使用

vuex

什么是vuex

Vuex是专门为vue.js应用程序开发的状态管理模式+库。在Vue中实现集中管理数据的一个Vue插件,对Vue中多个组件的共享状态进行集中式管理。也属于一种组件间的通信方式,且适用于任意组件间通信。

状态自管理应用包含的部分:

  • 状态,驱动应用的数据源
  • 视图,以声明方式将状态映射到视图
  • 操作,响应在视图上的用户输入导致的状态变化

单项数据流理念:img

因此我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏。

使用场景:

  1. 多个组件依赖同一个状态时
  2. 来自不同组件的行为需要变更同一个状态的时候。

**Vuex思想:**通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。

搭建vuex环境

创建文件:src/store/index.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})

main.js中创建vm时传入store配置项

......
//引入store
import store from './store'
......

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	store
})

vuex – State

属性介绍

state属性是vuex中用于存放组件之间共享的数据。通常将一些组件之间共享的状态主要存放在state属性中。

vuex使用单一状态树,用一个对象就包含了全部的应用层级状态。这意味着每个应用仅仅包含一个store实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。

state的使用

这里基于登录的业务逻辑,实现一个vuex集中管理token值,以便于发送请求时获取token值携带在header中的业务。

src/store/index.js中:

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {

}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {
  token:'',
  userMessage:{},
}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})

此时,我们在state中存放了两个变量:tokenuserMessage

当我们在其他组件中需要获取该变量时,使用this.$store.state.变量名获取

this.$store.state.token;
this.$store.state.userMessage;

当我们需要响应式获取vuex中存储的状态时,最简单的方式是使用计算属性

如果存放在data中,则不能响应式展示vuex中的数据,因为data中的内容只会在created钩子函数触发前初始化一次。而 computed则是通过【依赖追踪】实现的,在 computed 求值时引用的 Vue 变量变化时,会触发对 computed 的重新计算。所以我们可以使用computed 去引用 Vuex 状态变量,从而使得依赖追踪生效。

vuex – Mutations

更改vuex的store中的状态的唯一方式是提交mutation。(不能直接操作state修改数据)。

Vuex中的mutation非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数。

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {

}
//准备mutations对象——修改state中的数据
const mutations = {
  set_token(state,token){
    state.token = token;
    localStorage.token = token;
  },
  del_token(state){
    state.token = '';
    localStorage.removeItem('token');
  }
}
//准备state对象——保存具体的数据
const state = {
  token:'',
  userMessage:{},
}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})

此时,我们在mutations对象中定义了两个函数:set_tokendel_token,实现了将token存入本地存储和移出本地存储的功能。

提交的方式:使用this.$store.commit('方法名',参数)

this.$store.commit('set_token',token);
this.$store.commit('del_token');

此时,我们就实现了使用提交mutation的方法更改Vuex中的store状态。

vuex – Action

Action类似于mutation,与mutation的区别在于:

  • Action提交的是mutaion,而不是直接变更状态
  • Action可以包含任意异步的操作

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

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {
  set_token(context){
    context.commit(set_token)
  },
  del_token(context){
    context.commit(del_token)
  }
}
//准备mutations对象——修改state中的数据
const mutations = {
  set_token(state,token){
    state.token = token;
    localStorage.token = token;
  },
  del_token(state){
    state.token = '';
    localStorage.removeItem('token');
  }
}
//准备state对象——保存具体的数据
const state = {
  token:'',
  userMessage:{},
}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})
分发Action

Action通过store.dispatch方法触发:

this.$store.dispatch('set_token');
this.$store.dispatch('del_token');

Action的优势在于不会像使用mutation必须同步执行,在action内部可以执行异步操作:

actions: {
  incrementAsync ({ commit }) {
    setTimeout(() => {
      commit('set_token')
    }, 1000)
  }
}
// 以载荷形式分发
this.$store.dispatch('incrementAsync',{amount:10})
// 以对象形式分发
this.$store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

vuex–getters

使用场景

当需要对state中的数据进行二次加工,从state中派生出一些状态时会使用到。

getters接受state作为其第一个参数:

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)

//准备actions对象——响应组件中用户的动作
const actions = {
  token:'',
  userMessage:[
    {id:1,text:'111',done:true},
    {id:2,text:'222',done:true},
  ],
},
//抽取state中的状态
getters:{
  doneTod(state){
    return state.userMessage.filter(todo => todo.done);
  }
}
//准备mutations对象——修改state中的数据
const mutations = {
  set_token(state,token){
    state.token = token;
    localStorage.token = token;
  },
  del_token(state){
    state.token = '';
    localStorage.removeItem('token');
  }
}
//准备state对象——保存具体的数据
const state = {}

//创建并暴露store
export default new Vuex.Store({
	actions,
	mutations,
	state
})

此时定义的getters方法实现了从state.userMessage中抽取了done属性的操作。

通过属性访问

Getter会暴露为store.getters对象,可以以属性的形式访问:

this.$store.getters.doneTods

Getter 也可以接受其他 getter 作为第二个参数:

doneTodosCount (state, getters) {
    return getters.doneTodos.length
  }

通过方法访问

可以通过让 getter 返回一个函数,来实现给 getter 传参。在你对 store 里的数组进行查询时非常有用。

this.$store.getters.doneTod()

辅助函数的使用

mapState

当一个组件需要获取多个状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性。

import {mapState} from 'vuex'
computed: mapState({
  //箭头函数
  token: state => state.token,
  userMessage(state) {
    state.userMessage
  } 
})

当映射的计算属性的名称与state的子节点名称相同时,也可以给mapState传一个字符串数组。

computed: mapState(['token']);
对象展开运算符

mapState函数返回的是一个对象。通常,我们需要使用一个工具函数将多个对象合并为一个,以使我们可以将最终对象传给 computed 属性。但是自从有了对象展开运算符后,我们可以极大地简化写法:

//对象写法
computed:{
  localComputed(){
    ...mapState({
      token:'token',
      userMessage:'userMessage'
    })
  }
}
//数组写法
computed:{
  localComputed(){
    ...mapState(['token','userMessage'])
  }
}

mapGetters

mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性:

import { mapGetters } from 'vuex'
//数组写法
export default {
  // ...
  computed: {
  // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTod'
      // ...
    ])
  }
}
//对象写法
...mapGetters(doneTod:'doneTod')

mapActions方法

你在组件中使用 this.$store.dispatch('xxx') 分发 action,或者使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用(需要先在根节点注入 store):

import { mapActions } from 'vuex'
export default {
  // ...
  methods: {
    ...mapActions([
      'set_token', // 

      // `mapActions` 也支持载荷:
      'del_tooken' // 
    ]),
    ...mapActions({
      setToken: 'set_token' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}
mapMutations方法

你可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 store.commit 调用(需要在根节点注入 store)。

import { mapMutations } from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations([
      'set_token', // 将 `this.set_token()` 映射为 `this.$store.commit('set_token')`

      // `mapMutations` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      del: 'del_token' // 将 `this.del()` 映射为 `this.$store.commit('del_token')`
    })
  }
}

tions } from ‘vuex’

export default {
// …
methods: {
…mapMutations([
‘set_token’, // 将 this.set_token() 映射为 this.$store.commit('set_token')

  // `mapMutations` 也支持载荷:
  'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
]),
...mapMutations({
  del: 'del_token' // 将 `this.del()` 映射为 `this.$store.commit('del_token')`
})

}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值