vuex What is it? ?
Specifically for vue Design of state management architecture , Unified management and maintenance vue Variable state of .
vuex The five core attributes of ?
Five core concepts :state,getters,actions,mutations,modules
state
state yes vuex Basic data of
because vuex State storage is responsive , therefore vue Component from store The easiest way to get the state in is to write it in a calculated property
By registering in the root instance store option , The store Instances are injected into all the child components under the root component , And the sub components can pass through the this.$store Visit to
const Counter = { template: `<div>{{ count }}</div>`, computed: { count () {
return this.$store.state.count } } }
mapState auxiliary function
When a component needs to obtain multiple states , Declaring these states as computed properties is a bit of a duplication and redundancy . In order to solve this problem , We can use it mapState
Auxiliary functions help us generate computational properties , Let you press the key a few times less .
// In the separately built version, the auxiliary function is Vuex.mapState import { mapState } from 'vuex' export default
{ // ... computed: mapState({ // Arrow functions make the code more concise count: state => state.count, //
Pass string parameter 'count' Equivalent to `state => state.count` countAlias: 'count', // In order to be able to use `this`
Get local state , Regular functions must be used countPlusLocalState (state) { return state.count +
this.localCount } }) } // Using object expanders ...mapState({ topNav: state =>
state.topNav.data, // take this.topNav Map to this.$store.topNav.data navigationInfo:
state => state.topNav.navigationInfo }),
Getters
Vuex Allow us to be here store Defined in “getter”( It can be said that store Calculation properties of ). It's like calculating properties ,getter
The return value of is cached according to its dependency , And it is recalculated only when its dependency value changes .
getters receive state As its first parameter , Accept others getters As the second parameter , If not required , The second parameter can be omitted in the following example :
const store = new Vuex.Store({ state: { count:0 }, getters: { // Single parameter
countDouble: function(state){ return state.count * 2 }, // Two parameters
countDoubleAndDouble: function(state, getters) { return getters.countDouble * 2
} } })
Access through properties
Getter Will be exposed as store.getters object , You can access these values in the form of properties :
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
Access by method
getters: { // ... getTodoById: (state) => (id) => { return
state.todos.find(todo => todo.id === id) } } // Access by method
store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
mapGetters The auxiliary function is simply to store In getter Map to local computed properties :
import { mapGetters } from 'vuex' export default { // ... computed: { //
Use the object expansion operator to expand the getter Mix in computed Object ...mapGetters([ 'doneTodosCount',
'anotherGetter', // ... ]) } } mapGetters({ // hold `this.doneCount` Map to
`this.$store.getters.doneTodosCount` doneCount: 'doneTodosCount' })
Mutation
change Vuex Of store The only way to change the state of is to commit mutation.
mutation It has to be synchronous , If you want to be asynchronous, you need to use action.
each mutation Has a string Event type (type) and One Callback function
(handler). This callback function is where we actually make the state change , And it will accept it state
As the first parameter , Submit the load as the second parameter .( The submitted load should be an object in most cases ), Submitted loads may also be omitted .
const store = new Vuex.Store({ state: { count: 1 }, mutations: { // No load submitted
increment(state) { state.count++ } // Submit load incrementN(state, obj) { state.count
+= obj.n } } }) // Call in component // No load submitted store.commit('increment') // Submit load
store.commit('incrementN', { n: 100 })
mapMutations auxiliary function
import { mapMutations } from 'vuex' export default { //.. methods: {
...mapMutations([ 'increment' // mapping this.increment() by
this.$store.commit('increment') ]), ...mapMutations({ add: 'increment' // mapping
this.add() by this.$store.commit('increment') }) } }
Action
Action be similar to mutation, The difference is that :
* Action Submitted mutation, Instead of changing state directly .
* Action Can contain any asynchronous operation . const store = new Vuex.Store({ state: { count: 0 },
mutations: { increment (state) { state.count++ } }, actions: { increment
(context) { context.commit('increment') } } })
be careful :Action Function accepts an and store Instances with the same methods and properties context object , So you can call context.commit Submit a
mutation, Or by context.state and context.getters To get state and getters.
Action adopt store.dispatch Method trigger :
store.dispatch('increment')
mapActions auxiliary function
You use it in components this.$store.dispatch('xxx') distribute action, Or use mapActions The auxiliary function will change the methods
Map to store.dispatch call ( It needs to be injected at the root node first store):
import { mapActions } from 'vuex' export default { //.. methods: {
...mapActions([ 'incrementN' // mapping this.incrementN() by
this.$store.dispatch('incrementN') ]), ...mapActions({ add: 'incrementN' // mapping
this.add() by this.$store.dispatch('incrementN') }) } }
Module
Using a single state tree , It causes all the states of the application to concentrate on a large object . however , When the application gets big ,store The object will become bloated .
In order to solve the above problems ,Vuex Allow us to store Split into modules (module). Each module has its own
state,mutation,action,getters, Even nested submodules —— A similar segmentation is performed from top to bottom :
import Vuex from 'vuex'; import topNav_store from "./topNav/store.js"; import
member_store from "./member/store.js"; import game_store from
"./coupon/game.js"; import approval from './approval/store.js' import
setRentInfo from './contract/store.js' export default new Vuex.Store({
modules:{ topNav:topNav_store, memberStore:member_store, game_store:game_store,
approval:approval, setRentInfo } })
Technology