Vue | Vuex中五大属性及其辅助函数的使用说明

 

这篇文章主要介绍了vuex中五大属性和使用说明(包括辅助函数),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教。

1.state

vuex的基本数据,用来存储变量

// state存储基本数据
state: {  
   userId: '',  
}

在Vue中使用 this.$store.state.userId

我们可以通过Vue的computed获得Vuex的state

// An highlighted block
const store = new Vuex.Store({
    state: {
        count:0
    }
})

const app = new Vue({
    //..
    store,
    computed: {
        count: function(){
            return this.$store.state.count
        }
    },
    //..
})

mapState辅助函数

当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。

为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键。

将 Vuex store 中的状态映射为组件的计算属性, mapState有两种常用的写法,分别是对象语法和数组语法:

数组语法

import { mapState } from 'vuex';
 
export default {
 // 映射计算属性
 computed: mapState([
   // 映射 this.count 为 store.state.count
   'count'
 ])
 //...
}

在数组语法中,我们只需列出需要映射的状态属性名称,而不需要指定映射的模块。这种写法会自动将这些属性映射到组件的根状态(即this.$store.state)中。  

对象语法

写法一

import { mapState } from 'vuex';
 
export default {
 // 映射计算属性
 computed: mapState({
   // 映射 this.count 为 store.state.count
   count:state=>state.uploadfile.count
 })
 //...
}

在对象语法中,我们通过一个对象来定义映射关系,在键值对中指定组件中的计算属性名称作为键,然后使用箭头函数返回需要映射的状态值。 

写法二

import { mapState } from 'vuex';
 
export default {
  computed: {
    ...mapState('uploadfile', ['count'])
  },
  // ...
};

推荐使用第二种这种写法。原因如下:

① 语法更加简洁明了,直接指定模块名和需要映射的属性名称不需要额外的箭头函数或命名空间参数。

② 在组件中使用count时,可以清晰地知道该属性来自于哪个模块,提高了可读性。

③ 当需要映射多个属性时,可以在数组中列出所有需要映射的属性,使代码更加整洁。

总结:

在大型项目中,更推荐使用对象语法 ...mapState('module', ['property']) 来映射状态属性。这是因为大型项目通常具有复杂的模块化结构,并且存在多个模块之间的状态共享和交互。

以下是选择对象语法的原因:

模块明确:在大型项目中,往往存在多个模块,每个模块都有自己的状态属性。使用对象语法可以明确指定所需属性属于哪个模块,将状态属性与特定模块关联起来,提高了代码的可读性和可维护性。

避免命名冲突:在大型项目中,可能会存在多个模块中同名的状态属性。使用对象语法,可以避免不同模块中的状态属性名称冲突,减少潜在的错误。

模块解耦:使用对象语法可以将组件与特定模块解耦。当模块内部的状态结构发生变化时,只需更新模块内部的代码,而不需要修改组件中的映射代码。这有助于降低代码的耦合性和维护成本。

总之,对于大型项目来说,对象语法更具可扩展性、可读性和维护性,能更好地管理和组织模块化状态属性。使用对象语法能够更清晰地表达状态属性来自于哪个模块,并避免潜在的冲突和错误。


state:用来存储公共状态, state中存储的数据都是响应式的。

响应式原因:state里面有getters、setters方法;data中的数据也是响应式的,因为里面也有getters和setters方法。

在computed属性中来接收state中的数据,接收方式有2种(数组和对象,推荐对象)

优点:

① 本身key值是别名,要的是val值,key的值a 和 val="a"一样就行,随意写。减少state里面长的属性名。

② 可以在函数内部查看state中的数据,数组方式的话,必须按照state中的属性名。

2.getters

从基本数据(state)派生的数据,相当于state的计算属性,具有返回值的方法。

// getter
getters: {
    userIdDouble: function(state){
      return state.userId * 2
  }

在vue中使用 this.$store.getters.userIdDouble

与state一样,我们也可以通过Vue的computed获得Vuex的getters。

getters接收state作为其第一个参数,接受其他 getters 作为第二个参数,如不需要,第二个参数可以省略如下例子:

const store = new Vuex.Store({
  state: {
      count:0
  },

  getters: {
      // 单个参数
      userIdDouble: function(state){
          return state.count * 2
      },
      // 两个参数
      userIdDoubleAndDouble: function(state, getters) {
          return getters.userIdDouble * 2
      }
  }
})


const app = new Vue({
    //..
    store,
    computed: {
        userIdDouble: function(state){
            return this.$store.getters.userIdDouble
        },
        userIdDoubleAndDouble: function(state,getters){
            return this.$store.getters.userIdDouble
        },
    },
    //..
})

getters类似于组件里面computed,同时也监听属性的变化,当state中的属性发生改变的时候就会触发getters里面的方法。getters里面的每一个方法中都会有一个参数 state 

mapGetters 辅助函数

与state一样,我们也可以通过Vue的Computed获得Vuex的getters

对象写法

写法一

import { mapGetters } from 'vuex';
 
export default {
   computed: {
     ...mapGetters({
       userIdDouble:'userIdDouble',
       // 等价于
       //userIdDouble: function(){
       //    return getters.uploadfile.userIdDouble
       //},
       userIdDoubleAndDouble:'userIdDoubleAndDouble'
       // 等价于
       //userIdDoubleAndDouble: function(){
       //    return getters.uploadfile.userIdDoubleAndDouble
       //}
     })
   },

   //..
}

写法二

import { mapGetters } from 'vuex';
 
export default {
   computed: {
     ...mapGetters('uploadfile',['userIdDouble','userIdAndDouble')
   },
   //..
}

数组写法

import { mapGetters } from 'vuex';
 
export default {
   computed: {
     ...mapGetters(['userIdDouble','userIdAndDouble')
   },
   //..
}

3. mutations

提交更新数据的方法,必须是同步的(如果需要异步使用action)。

每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。提交mutation是更改Vuex中的store中的状态的唯一方法。

mutation必须是同步的,如果要异步需要使用action。

每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。(提交荷载在大多数情况下应该是一个对象),提交荷载也可以省略的。

// mutations
 mutations: {
   SET_USER: (state, userId) => {
     state.userId = userId
   },
 },

commit:同步操作,写法: this. s t o r e . c o m m i t ( 'mutations方法名,值 ) this. store.commit('mutations方法名',值) this. store.commit(‘mutations方法名’,值)this.store.commit(‘SET_USER’,‘123456’)

使用mapMutations–代替 $store.commit()- 传参的时候直接在行内写参数就可以了-

mapMutations 辅助函数

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

import { mapMutations } from 'vuex'
export default {
//..
methods: {
  ...mapMutations([
    'increment' // 映射 this.increment() 为 this.$store.commit('increment')
  ]),
  ...mapMutations({
    add: 'increment' // 映射 this.add() 为 this.$store.commit('increment')
  })
}
}

 4. actions

和mutation的功能大致相同,不同之处在于 ==》

1. Action 提交的是 mutation,而不是直接变更状态。

2. Action 可以包含任意异步操作。Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。

// actions
actions: { // {} 是es6中解构,把对象解构成属性
  login({ commit }, value) {
    commit('SET_USER', value)
    // commit('SET_TOKEN', value2)
  },
  }

dispatch:异步操作,写法:

this.$store.dispatch(‘mutations方法名',值)

actions里面的函数主要用来处理异步操作以及一些业务逻辑,每一个函数里面都有一个形参,这个形参是一个对象,里面有一个commit方法,这个方法用来触发mutations里面的方法。 

mapActions辅助函数

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

// An highlighted block
import { mapActions } from 'vuex'
export default {
  //..
  methods: {
    ...mapActions([
      'incrementN' //映射 this.incrementN() 为 this.$store.dispatch('incrementN')
    ]),
    ...mapActions({
      add: 'incrementN' //映射 this.add() 为 this.$store.dispatch('incrementN')
    })
  }
}

mutations里面的函数主要用来修改state中的数据。mutations里面的所有方法都会有2个参数,一个是store中的state,另外一个是需要传递的参数。

理解stateactionsmutations,可以参考MVC框架。

  • state看成一个数据库,只是它是响应式的,刷新页面数据就会改变;
  • actions看成controller层,做数据的业务逻辑;
  • mutations看成model层,做数据的增删改查操作。

至此,可以简单总结一下辅助函数通过vuex的使用,比喻成映射关系为:

  • mapState/mapGettes--->computed ;
  • mapAcions/mapMutations---->methods

5. modules

使用单一状态树,导致应用的所有状态集中到一个很大的对象。但是,当应用变得很大时,store 对象会变得臃肿不堪。

为了解决以上问题,Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutation、action、getters、甚至是嵌套子模块——从上至下进行类似的分割:

例如:分模块形式管理数据,比如user模块管理用户信息数据,cart模块管理购物车数据,shop模块管理商品信息数据。

import vue from 'vue'
import Vuex from 'vuex'
Vue.use(vuex);
 
const state= ()=>{ token:''}
const actions = {
   set_token({commit},val){
     commit("to_token",val)
  }
}
const mutations = {
   to_token(state,val){
    state.token=val;
  }
}
const getters = {}
 
 
//user模块
let user = {
  namespaced: true, //一定要开始命名空间。
  state: { userid: 1234 },
  actions: {
  },
  mutations: {
    SET_USERID(state, val) {
      state.userid = val;
    }
  },
  getters: {
 
  }
}
 
//购物车数据的模块
let cart = {
  namespaced: true,
  state: { userid: 567 },
  actions: {
 
  },
  mutations: {
  },
  getters: {
 
  }
}
 
 
const store = new Vuex.Store({
  state,
  mutations,
  actions,
  getters,
  modules: {
    user,
    cart
  },
  plugins: [createPersistedState({
    storage: sessionStorage,
    key: "token"
  })]//会自动保存创建的状态。刷新还在
})
 
export default store

home.vue如何使用:获取user模块的`userid`

this.$store.state.user.userid
// 前面是指定模块user 中的SET_USERID 方法,后面是传参 可以是对象、数组、字符串等
this.$store.commit("user/SET_USERID",12345)

模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

简单来说就是可以把以上的 state、mutation、action、getters 整合成一个user.js,然后放到store.js里面。
 

小结:modules属性:模块,把公共的状态按照模块进行划分。

1、每个模块都相当于一个小型的Vuex ;

2、每个模块里面都会有state getters actions mutations ;

3、切记在导出模块的时候加一个 namespaced:true 主要的作用是将每个模块都有独立命名空间;

4、多人协作开发的时候,可能子模块和主模块中的函数名字会相同,这样在调用函数的时候,相同名字的函数都会被调用,就会发生问题。为了解决这个问题,导出模块的时候要加namespace:true

番外:vuex的五大属性关系一览

6.命名空间

模块开启命名空间后,享有独自的命名空间。示例代码如下:

export default {
	namespaced: true,
	....
}

mapStatemapGettersmapMutationsmapActions第一个参数是字符串(命名空间名称),第二个参数是数组(不需要重命名)/ 对象(需要重命名)。 

mapXXXs('命名空间名称',['属性名1','属性名2'])

mapXXXs('命名空间名称',{

  '组件中的新名称1':'Vuex中的原名称1',

  '组件中的新名称2':'Vuex中的原名称2',

})

7.Vuex使用方法

使用方法:

① 安装Vuex:npm install vuex --save

② 在main.js中,导入Vuex,并使用Vue.use()方法注册Vuex。

import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
Vue.use(Vuex)
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  }
})
new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

③ 在组件中使用vuex中的数据和方法。 

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>
<script>
export default {
  computed: {
    count() {
      return this.$store.state.count
    }
  },
  methods: {
    increment() {
      this.$store.commit('increment')
    }
  }
}
</script>

④ vuex综合案例

下面是一个简单的Vuex使用方法的示例:

// 引入Vue和Vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 创建一个Store
const store = new Vuex.Store({
  // 定义State
  state: {
    count: 0
  },
  // 定义Mutation
  mutations: {
    increment: state => state.count++,
    decrement: state => state.count--
  },
  // 定义Getter
  getters: {
    evenOrOdd: state => state.count % 2 === 0 ? 'even' : 'odd'
  },
  // 定义Action
  actions: {
    incrementIfOdd ({ commit, state }) {
      if ((state.count + 1) % 2 === 0) {
        commit('increment')
      }
    }
  }
})
new Vue({
  el: '#app',
  store,
  template: `
    <div>
      <p>Count: {{ count }}</p>
      <p>Even or Odd? {{ evenOrOdd }}</p>
      <button @click="increment">Increment</button>
      <button @click="decrement">Decrement</button>
      <button @click="incrementIfOdd">IncrementIfOdd</button>
    </div>
  `,
  computed: {
    count () {
      return this.$store.state.count
    },
    evenOrOdd () {
      return this.$store.getters.evenOrOdd
    }
  },
  methods: {
    increment () {
      this.$store.commit('increment')
    },
    decrement () {
      this.$store.commit('decrement')
    },
    incrementIfOdd () {
      this.$store.dispatch('incrementIfOdd')
    }
  }
})

这个代码创建了一个Vuex Store,并定义了State、Mutation、Getter、Action。然后将Store实例与Vue实例关联。在Vue组件中,使用计算属性(computed)和方法(methods)来访问State、Getter和Action。在方法中,使用commit来提交Mutation,使用dispatch来分发Action。 

参考资料

 —— Vue | Vuex模块化及命名空间namespaced的使用_儒雅烤地瓜的CSDN博客 ——

几分钟弄懂Vuex五大属性和使用方式_脚本之家 | Vuex中5个属性使用方法举例讲解_脚本之家

Vuex 深入浅出超详细_vue.js_知乎 | Vue的Vuex的4个辅助函数_vue.js_脚本之家

Vue进阶:Vuex 辅助函数详解_vue.js-CSDN博客 | Vuex 辅助函数_Vue.js-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值