vuex的相關使用
mapState,mapActions,mapGetters,mapMutations
vuex中數據的調用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { //存放狀態
nickname:'zhangsan',
age:20,
gender:'男'
},
mutations: {
setAge(state, age) {
state.age = age // 修改狀態
}
},
getters: {
// 類似mutations
welcome(state) {
return state.nickname + '歡迎回來'
}
},
actions: {
login({ commit }, username) {
// login默認接收第一個參數vuex實例,從中可以分離出{ commit, dispatch }可供使用
return new Promise(() => { // 模擬異步登錄
setTimeout((resolve) => {
commit(username) // 得到數據后提交mutations
resolve(true)
}, 1000)
})
}
},
modules: {}, // 用於分割模塊
strict: true // 嚴格模式,可防止用戶手動修改,詳細介紹見下文
})
使用
- 可以直接在vue元素上直接調用狀態值
<div class="home">{{ $store.state.nickname }}</div>
- 在computed中添加返回狀態值
<template>
<div class="home">
{{ nickname }}
</div>
</template>
<script>
export default {
name: 'home',
computed:{
nickname(){
return this.$store.state.nickname
}
}
}
</script>
- 更改狀態值的方法
- 通過mutations調用對應方法更改狀態值
// 在.vue文件中使用
this.$store.commit('setAge', 18)
// 在.js文件中使用, 首先需要引入store
import store from '@/store'
store.commit('setAge', 18)
- 遇到異步交互時更改狀態值
vuex規定更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation,所以還是需要調用mutations的方法,但是需要的一些異步方法不能在mutations里面進行。
vuex提供了actions供我們去對數據進行處理。
// .vue文件中調用actions方法
this.$store.dispatch('login', 'admin').then(res => {})
模塊化
Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割
上方代碼分割成模塊
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './user'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user
},
// strict: true // 嚴格模式,防止用戶手動更改狀態
strict: process.env.NODE_ENV !== 'production'
/* 但是盡量不要在生產環境下使用嚴格模式,嚴格模式會深度檢測狀態樹來檢測不合格的狀態變更,在發布環境下關閉嚴格模式,以避免性能損失 */
})
// user.js
export default {
namespaced: true, // 設置命名空間,可便於准確定位到狀態值,防止各個模塊狀態值的污染
state: { //存放狀態
nickname:'zhangsan',
age:20,
gender:'男'
},
mutations: {
setAge(state, age) {
state.age = age // 修改狀態
}
},
actions: {
login({ commit }, username) {
// login默認接收第一個參數vuex實例,從中可以分離出{ commit, dispatch }可供使用
return new Promise(() => { // 模擬異步登錄
setTimeout((resolve) => {
commit(username) // 得到數據后提交mutations
resolve(true)
}, 1000)
})
}
}
}
- 當加上命名空間后,數據獲取的時候就可以攜帶上名稱,名稱和
modules
中定義的名字一樣,
如:
this.$store.state.user.nickname
this.$store.dispatch('user/login')
vuex中的映射方法
此處演示的例子均為
namespace:true
的情況
- 使用mapState輔助函數
import {mapState} from 'vuex'
export default {
name: 'home',
computed: {
...mapState('user', ['nickname','age','gender']) // 可直接使用
}
}
import { mapActions } from 'vuex'
methods: {
// ...mapActions('user', ['login']) //為了避免和狀態值重名,也可以使用完整路徑,如下
...mapActions(['user/login'])
}
// 在使用的時候
this['user/login']('admin').then(res => {})
- 使用方法類似mapState
import { mapGetters } from 'vuex'
computed: {
...mapGetters('user', ['welcome'])
}
- 和mapActions類似
import { mapMutations } from 'vuex'
methods: {
...mapMutations(['user/login'])
}
// 在使用的時候
this['user/login']('admin').then(res => {})
各屬性介紹
getters
- getters屬於vuex中的計算屬性,通過getters進一步處理,允許傳參,第一個參數就是state
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { //存放狀態
nickname:'Simba',
firstname:'張',
lastname:'三豐',
age:20,
gender:'男',
money:1000
},
getters:{
realname(state){
return state.firstname+state.lastname
},
money_us(state){
return (state.money/7).toFixed(2)
}
},
mutations: {},
actions: {},
modules: {}
})
- vue頁面調用的時候
computed: {
valued (){
return this.value/7
},
...mapGetters(['name', 'age']) // 可直接使用
}
Mutations
- mutations需要通過commit來調用其里面的方法,它也可以傳入參數,第一個參數是state,第二個參數是載荷(payLoad),也就是額外的參數
mutations: { //類似於methods
addAge(state,payLoad){
state.age+=payLoad.number
}
}
<div class="home">
<div><button @click="test">測試</button></div>
</div>
methods:{
test(){
// 可通過前台操作觸發執行mutations里面的方法
this.$store.commit('addAge',{
number:5
})
}
}
#### actions
- action中屬於一部操作,mutations屬於同步操作
- action不要直接取操縱state,是通過操作mutations進而去改變state里面的值
- action中的方法默認的就是異步,並且返回promise
```javascript
actions: {
getUserInfo(){
return {
nickname:'Simba',
age:20
}
}
}
// 在actions中定義一個方法:getUserInfo,並且返回一個對象
created(){
var res = this.getUserInfo()
console.log(res)
},
methods:{
...mapActions(['getUserInfo'])
}
// mapActions(['getUserInfo']) 相當於以下代碼
getUserInfo(){
return this.$store.dispatch(‘getUserInfo’)
}
export default new Vuex.Store({
state: {
nickname: '',
age:0,
gender: '',
money:0
},
mutations: {
setUerInfo(state,payLoad){
state.nickname = payLoad.nickname
state.age = payLoad.age
state.gender = payLoad.gender
state.money = payLoad.money
}
},
actions: { //actions沒有提供state當參數
async getToken({commit}){
var res = await axios.get('/token接口')
commit('setToken',res)
},
async getUserInfo(context){
//context可以理解為它是整個Store的對象.類似於this.$store,
他里面包含了state,getter,mutations,actions
const res = await axios.get('/接口url')
context.commit('setUerInfo',res)
//相當於 this.$store.commit,第一個參數是方法名,第二個參數是要傳入的數據
context.dispatch('getToken')
//actions也可以調用自己的其他方法
},
}
})