Application structure
In fact, Vuex has no limitations on how to organize your code structure, instead it enforces a set of advanced principles:
1, the application level of the state is centrally placed in the store.
2, the only way to change the state is to submit mutations, this is a synchronized transaction.
3, asynchronous logic should be encapsulated in the action.
As long as you follow these rules, how to build the structure of your project depends on you. If your store file is very large, just split into action, mutation and getter multiple files.
For a slightly more complex application, we may all need to use the module. The following is a simple project architecture:
├──index.html
├──main.js
├──api
│└──. # Launch API request here
├──components
│├──app.vue
│└── ...
└──store
├──index.js # combination modules, export store
├──actions.js # Root Action
├──mutations.js # Root Mutations
└──modules
├──cart.js # Cart Module
└──products.js # Products Module
For more, see Shopping cart instances.
Modules
Because a single state tree is used, all the states applied are contained within a large object. However, as we continue to grow in size, the store becomes bloated.
To solve this problem, Vuex allows us to divide the store into module (modules). Each module contains its own state, mutation, action, and getter, or even nested modules, as follows is how it is organized:
Const MODULEA = {state
: {...}, mutations: {...}, actions: {...}
,
getters:
{...}} Const MODULEB = {state
: {...}, mutations: {...}
,
actions: {...}
} Const STORE = new Vuex.store ({
modules: {
A:modulea,
b:moduleb
}
})
Store.state.a//-& Gt Modulea ' s state
store.state.b//-> Moduleb's state
Module Local State
The mutations and getters methods of the module the first receive parameter is the local state of the module.
Const MODULEA = {
states: {count:0},
mutations: {
increment: (state) {
/S is the status of the module local.
state.count++
}
},
getters: {
Doublecount (state) {return
State.count * 2
}
}
}
Similarly, in the actions of the module, Context.state exposed The local state, Context.rootstate exposed is the root state.
Const MODULEA = {
///...
Actions: {
incrementifodd ({state, Commit}) {
if (state.count% 2 = 1) {
commit (' increment ')
}
}
}
}
Within the getters of the module, the root state is also exposed as the third parameter.
Const MODULEA = {
///...
Getters: {
sumwithrootcount (state, getters, rootstate) {return
State.count + rootstate.count
}
}
}
Name space
Note that the actions, mutations, and getters within the module are still registered in the global namespace-which allows multiple modules to respond to the same mutation/action type. You can avoid naming conflicts by adding a prefix or suffix to the name of the module to set the namespace. If your VUEX module is reusable and the execution environment is unknown, you should do so. Distance, we want to create a Todos module:
Types.js
//define constant name for getter, action, and mutation
//and add ' Todos ' prefix to module name
Export const Done_count = ' Todos/do Ne_count '
export const Fetch_all = ' Todos/fetch_all '
export const Toggle_done = ' Todos/toggle_done '
/ Modules/todos.js
Import * as types from '. /types '
//define getters with prefixed name, actions and mutations
Const TODOSMODULE = {State
: {todos: []},
getters : {
[Types. Done_count] (state) {
//...
}
},
actions: {
[Types. Fetch_all] (context, payload) {
//...
}
},
mutations: {
[Types. Toggle_done] (state, payload) {
//...}}
}
Registering a dynamic module
You can use the Store.registermodule method to register a module after the store is created:
Store.registermodule (' MyModule ', {
//...
})
The store.state.myModule of the module is exposed to the state of the module.
Other Vue plug-ins can attach a module to the store for the application and can then use the Vuex state management function by dynamically registering. For example, the Vuex-router-sync Library integrates Vue-router and VUEX by managing the routing state of an application in a dynamically registered module.
You can also use store.unregistermodule (modulename) to remove dynamically registered modules. But you can't use this method to remove static modules (that is, the modules declared when the store was created).
Plugins
Vuex's store receives the plugins option, which exposes each mutation hook. A Vuex plug-in is an easy way to receive sotre as a unique parameter:
Const Myplugin = store => {/
/when store is called
Store.subscribe after initialization (mutation, state) => {
//mutation The called
//mutation format is {type, payload}.
})
}
And then use it like this:
Const STORE = new Vuex.store ({
//...
) Plugins: [Myplugin]
})
Submit mutations within a plugin
Plug-ins cannot modify state directly-this is like your component, they can only be mutations to trigger the change.
By submitting mutations, plug-ins can be used to synchronize data sources to the store. For example, to synchronize the WebSocket data source to the store (this is just an example of a usage, in practice, the Createplugin method attaches more options to accomplish complex tasks).
Export default function Createwebsocketplugin (socket) {return
store => {
socket.on (' data '), data => {
Store.commit (' Receivedata ', data)
})
Store.subscribe (mutation => {
if (Mutation.type = = ' Update_ DATA ') {
socket.emit (' Update ', Mutation.payload)}}}
Const PLUGIN = createwebsocketplugin (socket)
Const STORE = new Vuex.store ({State
,
mutations,
Plugins: [plugin]
})
Generate a status snapshot
Sometimes plug-ins want to get state "snapshots" and changes in state before and after changes. To implement these features, a deep copy of the state object is required:
Const MYPLUGINWITHSNAPSHOT = store => {let
prevstate = _.clonedeep (store.state)
store.subscribe (mutation, State) => {let
nextstate = _.clonedeep (state)
//contrast prevstate and nextstate ...
Save state, for next mutation
prevstate = nextstate
})
}
* * A plug-in that generates a state snapshot can only be used during the development phase, using Webpack or browserify, so that the build tool helps us deal with:
Const STORE = new Vuex.store ({
//...
) Plugins:process.env.NODE_ENV!== ' production '
? [Mypluginwithsnapshot]
: []
})
Plug-ins are enabled by default. In order to release the product, you need to convert the Process.env.NODE_ENV!== ' production ' value to false using the Webpack defineplugin or browserify envify.
Built-in Logger Plugin
If you are using Vue-devtools, you may not need it.
Vuex brings a log plugin for general debugging:
Import Createlogger from ' Vuex/dist/logger '
const store = new Vuex.store ({
plugins: [Createlogger ()]
})
The Createlogger method has several configuration items:
Const LOGGER = Createlogger ({
collapsed:false,//automatically expand record mutation
transformer (state) {/
/convert before logging
/ /For example, returns only the specified subtree return
state.subtree
},
Mutationtransformer (mutation) {
//mutation format {type, Payload}
//We can format return
Mutation.type
} in the way we want
The log plug-in can also go directly through the <script> tag, and then it provides a global method Createvuexlogger.
Note that the Logger plug-in generates a status snapshot, so it is only used in the development environment.
Strict mode
To enable strict mode, simply pass in the strict:true when you create the Vuex store.
Const STORE = new Vuex.store ({
//...
) Strict:true
})
In strict mode, an error is thrown as long as the Vuex state is modified outside the mutation method. This ensures that all state modifications are explicitly tracked by the debugging tool.
Development phase vs. Release phase
Do not open the strict mode in the release phase! Strict mode monitors the state tree in depth to detect inappropriate modifications-ensuring that it is turned off during the release phase to avoid performance loss.
Similar to the handling of plug-ins, we can let the build tools handle:
Const STORE = new Vuex.store ({
//...
) Strict:process.env.NODE_ENV!== ' production '
})
Related references
Http://vuex.vuejs.org/en/plugins.html
Http://vuex.vuejs.org/en/strict.html
Http://vuex.vuejs.org/en/modules.html
Http://vuex.vuejs.org/en/structure.html
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.