Introduction:
In developing a VUE application, sometimes webPack hot update doesn’t work, so you manually press F5 to refresh the page, and the page is redirected to the login page. After elimination, it was found that the userCode value stored in VUEX was undefine, which led to the problem of re-login. In vue application, how should the login permission function be done in Vuex? Why is everything in Vuex cleared when the page is refreshed? Let’s explore a wave.
This article mainly tells the following contents:
- Understand the principles of Vuex patterns
- Explain the application of Vuex with an example of a user logging in
- Finally, talk about the reason why the refresh browser vuex memory is empty
Understand the Vuex pattern
introduce
Vuex is a state management mode developed specifically for vue.js applications. It uses centralized storage to manage the state of all components of the application and rules to ensure that the state changes in a predictable way.
What is “state management mode”? Let’s start with a simple Vue counting application:
new Vue({
// state
data () {
return {
count: 0}},// view
template: `<div>{{ count }}</div>`.// actions
methods: {
increment() {
this.counte++
}
}
})
Copy the code
This state self-management application consists of the following parts:
- State, the data source that drives the application
- View, to declaratively map state to the view;
- Actions, in response to changes in state caused by user input on the view.
Here is a simple illustration of the idea of “one-way data flow” :
However, the simplicity of one-way data flow can easily be compromised when our application encounters state shared by multiple components.
- Multiple views depend on the same state.
- Actions from different views need to change the same state.
As for the first problem, the method of parameter passing is very tedious for multi-layer nested components, and it is useless for state passing between sibling components. For problem two, we often use parent-child components to reference directly or to change and synchronize multiple copies of state through events. (Component passing, deep copy, etc.)
So why don’t we extract the shared state of the components and manage it in a global singleton? In this mode, our tree of components forms a giant “view” where any component can pick up state or trigger behavior no matter where in the tree.
Vue core idea
At the heart of Vuex’s app is the Store, which is basically a container that contains most of the states in your app. Some students may ask, well, what if I define a global object and then encapsulate some data access interface? Vuex differs from pure global objects in two ways:
- Vuex’s state storage is reactive. When Vue reads state from the Store, if the state in the store changes, the corresponding components are updated efficiently. (If there is a window, do you need to manually bind the properties under window?)
- You can’t just change the state in the store. The only way to change the state in a store is to commit mutation explicitly. This makes it easy to track each state change.
By defining and isolating concepts in state management and enforcing compliance with certain rules, our code becomes more structured and maintainable.
Vuex specifies four properties: State (initialize the value of a variable), getter (get the value of a variable), Action (change the value asynchronously), and mutation (change the value synchronously). This borrows from the command-query separation of responsibilities.
- If a method modifies the state of the object, it is a command and must not return a value.
- If a method returns some value, it is a Query, and the state must not be changed.
Here is a user example of vuex.
In actual combat
A modern Web application usually includes log collection, buried points, login authentication and other functions, and the status of these functions are often used by various components in the entire application, so vuEX is more convenient.
- With Windows, the lack of time travel makes debugging a nightmare, as with publish-subscribe only mechanisms, very difficult to manage. (Such as a menu tree in a sidebar with which other components interact.) Because, at any time, any part of our application, after any data changes, does not leave a record of the changes. That is, it can be changed at will, and there is no record left, and the later project will not be able to maintain. Vuex can track variable changes and must be modified through fixed attributes.
- A large number of variables will cause naming pollution, but VUEX will not. Data can be modified in a unified way, and all variables can be modified at will. At the same time, the communication between parent component, grandson component and sibling component is solved.
- Vuex provides vuE-Tool, which allows you to visually view the state of your application’s data.
The user login
User information is used by the entire application. Most pages need to check whether they have logged in and obtain user information. Therefore, vuEX can greatly reduce back-end requests.
Process: After the user fills in the account and password, the server verifies that the user is correct. After the verification is successful, the server returns a token. After the token is obtained (the token can be stored in the cookie to ensure that the user login status can be remembered after refreshing. The front end then pulls a user_info interface based on the token.
Of course, in practical applications, the account and password are simply verified before being submitted to the server, and the user name is encrypted, and then the account and password are submitted to the server for verification.
In the login component, the Click event clicks the login button
try {
await this.$store.dispatch('LoginByUsername'.this.loginForm).then((a)= > {
this.$router.push({ path: '/'}); // Redirect to home page after successful login
}) catch (err) {
this.$message.error(err); // Failed to log in
})
Copy the code
action:
/ / store/moudules/user. Js file
actions {
async loginByUserName({ commit }, userInfo) {
const loginName = userInfo.loginName.trim()
// The password can be encrypted here
const data = await login({
loginName,
loginPwd,
})
const { userCode } = data;
// Call mutation to change the user state
commit(SET_USER_INFO, data);
commit(SET_USER_SESSION, userCode)
// Store to cookies
`Cookies.set('userCode', userCode)`
returndata; }},// The corresponding getter setting
usercode: state= > {
return state.userInfo.userCode ? state.userInfo.userCode: getUserCode();
}
Copy the code
At this point, I stored the token in the cookie, so that the user can keep the login state even if the refresh. (PS: We can also save the path of the last user visit and restore the user’s history visit page)
Since logins are asynchronous, we use action. If we don’t use action, we need to do something like this when it comes to asynchrony:
const data = await getUserInfo(); // Request backend information
store.commit('SET_USER_INFO', data); // Save to Vuex
Copy the code
The preceding operations can also be split by login and getUserInfor. After the first successful login, the backend returns only userCode. After the user logs in successfully, it intercepts the global hook router-beforeeach, requests specific user information, and stores updates to vuex. In this way, when a page needs user information (such as RegionCode), the page refresh does not follow the login logic, and the administrative code is lost.
router.beforeEach(async (to, from, next) => {
const hasSession = getUserCode(); // Retrieve data from cookies
if (hasSession) {
...// Obtain user permission information
} else{...// Jump to the login page}}Copy the code
Components use data stored in VUEX
this.$store.getters.usercode
Copy the code
All of the above data and operations are controlled by vuEX global management. The content of VUEX will be lost after the page is refreshed, so you need to repeat the above operations.
Why does Vuex clear its contents after a page refresh?
Because the store data is stored in runtime memory, when the page is refreshed, the page reloads the Vue instance and the store data is reassigned and initialized.
Let’s look at an example of Vuex:
export default new Vuex.Store({
actions,
getters,
state,
mutations,
modules
// ...
})
Copy the code
Let’s look at the implementation of Vuex’s Store:
export class Store {
constructor (options = {}) {
// Auto install if it is not done yet and `window` has `Vue`.
// To allow users to avoid auto-installation in some cases,
// this code should be placed here. See #731
if(! Vue &&typeof window! = ='undefined' && window.Vue) {
install(window.Vue)
}
if(process.env.NODE_ENV ! = ='production') {
assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
assert(typeof Promise! = ='undefined'.`vuex requires a Promise polyfill in this browser.`)
assert(this instanceof Store, `Store must be called with the new operator.`)}const {
plugins = [],
strict = false
} = options
// store internal state
this._committing = false
this._actions = Object.create(null)
this._actionSubscribers = []
this._mutations = Object.create(null)
this._wrappedGetters = Object.create(null)
this._modules = new ModuleCollection(options)
this._modulesNamespaceMap = Object.create(null)
this._subscribers = []
this._watcherVM = new Vue()
// bind commit and dispatch to self
const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) {
return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload, options) {
return commit.call(store, type, payload, options)
}
// strict mode
this.strict = strict
const state = this._modules.root.state
// init root module.
// this also recursively registers all sub-modules
// and collects all module getters inside this._wrappedGetters
installModule(this, state, [], this._modules.root)
// initialize the store vm, which is responsible for the reactivity
// (also registers _wrappedGetters as computed properties)
resetStoreVM(this, state)
// apply plugins
plugins.forEach(plugin= > plugin(this))
if (Vue.config.devtools) {
devtoolPlugin(this)}}}Copy the code
JavaScript code runs in memory, and all variables and functions are stored in memory while the code is running. Refresh the page, free the previously allocated memory, reload the footstep code, and re-assign variables. All these data must be stored externally. If you want to persist data, consider localStorage, Session Storage, IndexDB, etc. It allows us to store data on hard drives. If you select Cookies, do not set the expiration time, close the browser will be cleared.
conclusion
Learning VUEX allows us to better manage the state of our data and decide when to use vuex based on the type of data.
- It needs to be responsive
- Cross-level component communication
- Data is common, such as user information, or controlling container components (such as pop-ups)
(Full text)