Vue-admin工作整理(九): 狀態管理Vuex-state和getters


前提:通過項目結構個人設置創建的項目

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>

呈現:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM