前提:通過項目結構個人設置創建的項目
store文件下actions.js、mutations.js、state.js都是根級別的狀態管理,引用入口是通過index.js來實現,整個Vuex處理邏輯為:
一、state
-
實現方式1:訪問根(state.js)狀態的方式
在state.js定義的值,可以在任何組件中使用,其他組件使用計算屬性(computed)來獲得該值,然后通過store的實例來讀取:this.$store.state.appName,具體實現:
1、state.js:
const state = { appName: 'Robin' } export default state
2、store.vue
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }}</p> <p>appName: {{ appName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { appName () {
// 實現方式1:訪問根狀態的方式 return this.$store.state.appName //注意路徑,一定要是:store下的state模塊實例的appName值 } } } </script>
結果:
-
實現方式2:模塊里定義的state(model->user.js->state)的值訪問
思路:組件中通過 this.$store.state.user.userName來獲取,注意:一定要有模塊名(user),具體實現:
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }}</p> <p>appName: {{ appName }}</p> <p>userName: {{ userName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { appName () { return this.$store.state.appName }, userName () { return this.$store.state.user.userName } } } </script>
結果:
- 實現方式3:通過Vuex提供的工具函數:mapState
a、數組方式
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }}</p> <p>appName: {{ appName }}</p> <p>userName: {{ userName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' import { mapState } from 'vuex' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { ...mapState([ // ...為es6里面的展開操作符,它會展開一個對象,mapState最后會返回一個對象 'appName', 'userName' ]) } } </script>
b、對象方式
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }}</p> <p>appName: {{ appName }}</p> <p>userName: {{ userName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' import { mapState } from 'vuex' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { ...mapState({ appName: state => state.appName, // state為根級的state.js對象 userName: state => state.user.userName // state為根級的state.js對象 } ) } } </script>
- 實現方式4:如果模塊中使用了命名空間,那么state值該怎么取?(使用命名空間,會讓我們的模塊更加密閉,不受外界的干擾)
思路:可以使用Vuex提供的另一種方法:createNamespacedHelpers,通過它,來定義 mapState ,該方法需要傳入一個命名空間的模塊名,比如我們是在用user.js增加命名空間:createNamespacedHelpers('user'),這個時候 mapState 就包含了user這個模塊名稱了,注意書寫方式:
import { createNamespacedHelpers } from 'vuex' const { mapState } = createNamespacedHelpers('user')
使用的時候通過:...mapState的方式,以對象形式取值了:
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }}</p> <p>appName: {{ appName }}</p> <p>userName: {{ userName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' import { createNamespacedHelpers } from 'vuex' const { mapState } = createNamespacedHelpers('user') export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { ...mapState({ userName: state => state.userName } ) } } </script>
二、getters
相當於一個組件里面的計算屬性,可以通過組件里的一個值經過計算處理,來返回一個新的值,依賴的值如果發生了變化,那么使用了這個值的getters屬性也會發生相應的變化,也會更新
1、最基礎非getters方法:當inputValue改變的時候相應的計算屬性也會去重新計算,如果inputValue的data值不變,計算屬性是不會進行計算的
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }} -> lastLetter is {{ imputValueLastLetter }}</p> <p>appName: {{ appName }}</p> <p>userName: {{ userName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' import { mapState } from 'vuex' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { ...mapState({ appName: state => state.appName, userName: state => state.user.userName }), // 拿inputValue的最后一個字母 imputValueLastLetter () { return this.inputValue.substr(-1, 1) } } } </script>
2、Vuex里的getters: store->getters.js(根級別的getters)
例如:想展示一個值,這個值是依賴於state.js里的appName來計算的,需要在getter.js創建一個屬性:appNameWithVersion。 屬性值是一個函數,函數里面要有一個參數:state,這個state就是當前Vuex實例里的同級的state,然后通過
const getters = { appNameWithVersion: (state) => { return state.appName + 'V 2.0.0' } } export default getters
對 appNameWithVersion 進行處理,值獲取到后在store.vue中,通過
appNameWithVersion () { return this.$store.getters.appNameWithVersion }
進行傳值
整體store代碼:
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }} -> lastLetter is {{ imputValueLastLetter }}</p> <p>appName: {{ appName }} -> appNameWithVersion is {{ appNameWithVersion }}</p> <p>userName: {{ userName }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' import { mapState } from 'vuex' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { ...mapState({ appName: state => state.appName, userName: state => state.user.userName }), // 通過getters拿inputValue的最后一個字母 imputValueLastLetter () { return this.inputValue.substr(-1, 1) }, appNameWithVersion () { return this.$store.getters.appNameWithVersion } } } </script>
3、通過Vuex提供的工具方法,來獲取getter
a、數組形式:
import { mapState, mapGetters } from 'vuex'
...mapGetters([ 'appNameWithVersion' ])
b、如何取模塊中定義的getter呢:
(1)、user.js:
const state = { userName: 'Cristin' } // 取userName的第一個字母 const getters = { firstLetter: (state) => { return state.userName.substr(0, 1) } } const mutations = { // } const actions = { // } export default { namespaced: true, state, mutations, actions, getters }
(2)、store.vue:
<template> <div> <a-input v-model="inputValue"/> <p>{{ inputValue }} -> lastLetter is {{ imputValueLastLetter }}</p> <p>appName: {{ appName }} -> appNameWithVersion is {{ appNameWithVersion }}</p> <p>userName: {{ userName }} -> firstLetter is {{ firstLetter }}</p> <a-show :content = "inputValue"/> </div> </template> <script> import AInput from '_c/AInput.vue' import AShow from '_c/AShow.vue' import { mapState, mapGetters } from 'vuex' export default { name: 'store', data () { return { inputValue: '' } }, components: { AInput, AShow }, computed: { ...mapState({ appName: state => state.appName, userName: state => state.user.userName }), ...mapGetters([ 'appNameWithVersion' ]), ...mapGetters('user', [ 'firstLetter' ]) } } </script>
呈現: