Author: Anthony Gore
Translator: Frontend Xiaozhi
Source: vuejsdevelopers
There are dreams and dry goods. search 160aee812f375d [Moving to the World] Follow this brushing wisdom who is still doing dishes in the early morning.This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line big factory interview complete test sites, materials and my series of articles.
Vuex
is an essential tool in the Vue.js ecosystem. But developers who are new to Vuex may be repelled by terms such as "state management mode" and confused about what they actually need Vuex for.
This article can be regarded as an introduction to Vuex, and of course it will also provide advanced concepts of Vuex and show you how to use Vuex in your application.
Problems solved by Vuex
To understand Vuex, we must first understand the problem it solves.
Suppose we have developed a multi-user chat application. The interface has a user list, a private chat window, an inbox with chat history, and a notification bar to notify the user of unread messages of other users that are not currently viewed.
Millions of users chat with millions of other users through our app every day. However, someone complained about an annoying problem: the notification bar occasionally gave wrong notifications. The user is notified that there is a new unread message, but when they view it, it is just a message that has already been read.
What the author describes is the real situation that Facebook developers encountered in their chat system a few years ago. In the process of solving this problem, the developers created an application architecture "Flux" Flux forms the basis of Vuex, Redux and other similar libraries.
Flux
Facebook developers struggled with the "zombie notification" issue for some time. They finally realized that its persistence was not just a simple flaw-it pointed out some potential flaws in the application architecture.
This defect is easiest to understand in abstraction: when there are multiple components that share data in an application, the complexity of their interconnection will increase to the point where it is impossible to predict or understand the state of the data. Therefore, the application cannot be extended or maintained.
Flux
is a pattern, not a library. We cannot go to Github to download Flux. It is a design pattern similar to MVC. Libraries like Vuex and Redux implement the Flux pattern in the same way as other frameworks implement the MVC pattern.
In fact, Vuex does not implement all of Flux, just a subset. But don't worry about this problem for now, we focus on understanding the key principles it follows.
Principle 1: Single source
The component may have local data that only needs to be known. For example, the position of the scroll bar in the user list component may not be related to other components.
However, any data to be shared between components (ie application data) must be kept in a separate location, separate from the components that use it.
This single location is called "store". The component must read the application data from this location and cannot keep its own copy to prevent conflicts or disagreements.
import { createStore } from "vuex";
// Instantiate our Vuex store
const store = createStore({
// "State" 组件的应用程序数据
state () {
return {
myValue: 0
};
}
});
// 组件从其计算的属性访问 state
const MyComponent = {
template: "<div>{{ myValue }}</div>",
computed: {
myValue () {
return store.state.myValue;
}
}
};
Principle 2: Data is read-only
The component can read data freely store
But store
cannot be changed, at least not directly.
Instead, they must inform store
their intention to change the data. store
is responsible for making changes through a set of defined functions (called mutation
Why use this method? If we centralize the data change logic, then in the case of inconsistent states, we only need to check in the same place instead of each specific file. We minimize the possibility of some random components (possibly in third-party modules) changing data in unexpected ways.
const store = createStore({
state() {
return {
myValue: 0
};
},
mutations: {
increment (state, value) {
state.myValue += value;
}
}
});
// 需要更新值吗?
// 错误的,不要直接更改 store 值
store.myValue += 10;
// 正确的,调用正确的 mutations。
store.commit('increment', 10);
Principle 3: The mutation is synchronous
If the application implements the above two principles in its architecture, it is much easier to debug data inconsistencies. You can record the submission and observe how the status changes (it is indeed possible to do this when using Vue Devtools).
But if our mutation
is called asynchronously, this ability will be weakened. We know the order of submission, but we don't know the order in which the components are submitted.
Synchronizing mutation
ensures that the state does not depend on the sequence and timing of unpredictable events.
That's cool, so what exactly is Vuex?
With all this background knowledge, we can finally solve this problem-Vuex is a library that helps us implement Flux architecture in Vue applications. By implementing the above principles, even when data is shared between multiple components, Vuex can still keep our application data in a transparent and predictable state.
Now that we have an advanced understanding of Vuex, let's take a look at how to create Vuex-based applications in actual projects.
Make a to-do-list using Vuex
To demonstrate the use of Vuex, we set up a simple to-do application. You can access a valid example of the code here
Example address: https://codesandbox.io/s/happy-williams-rdni7
If you try a wave on your own computer, you can use the following command:
vue create vuex-example
Install Vuex
cd vuex-example
npm i -S vuex@4
npm run serve
Create a Vuex store
Now, create Vuex store, created in the project src/store/index.js
:
mkdir src/store
touch src/store/index.js
Open the file and import the createStore
method. This method is used to define store
and its characteristics. Now, we export the store
so that it can be accessed in the Vue application.
// src/store/index.js
import { createStore } from "vuex";
export default createStore({});
Add store to Vue instance
In order to be able to access the Vuex store from any component, we need to import the store
module store
as a plugin on the main Vue instance
// src/main.js
import { createApp } from "vue";
import App from "@/App";
import store from "@/store";
const app = createApp(App);
app.use(store);
app.mount("#app");
Create a simple application
As mentioned above, the focus of Vuex is usually to create scalable global state in large applications. However, we can demonstrate its functionality in a simple to-do application.
The effect after completion is as follows:
Now, delete the HelloWorld file:
rm src/components/HelloWorld.vue
TodoNew.vue
Now, add a new component TodoNew
, which is responsible for creating new to-do items.
touch src/components/TodoNew.vue
Open TodoNew.vue
and enter the following:
// src/components/TodoNew.vue
<template>
<form @submit.prevent="addTodo">
<input
type="text"
placeholder="Enter a new task"
v-model="task"
/>
</form>
</template>
Turning now to the component definition, there are two local state property - task
and a new to-do provides a unique identifier of id
.
// src/components/TodoNew.vue
<template>...</template>
<script>
export default {
data() {
return {
task: "",
id: 0
};
},
methods: {
addTodo: function() {
//
}
}
};
</script>
Define store state
After a meeting, we will create a component that displays to-do items. Since it and the TodoNew
component both need to access the same data, this is the ideal choice state
Now, go back to state
and define the attribute state. Here we use the createStore
function provided by Vux4, which returns an object. The object has a property todos
, which is an empty array.
// src/store/index.js
import { createStore } from "vuex";
export default createStore({
state () {
return {
todos: []
}
}
});
Define mutation
It can be known from Principle 2 that the Vuex state cannot be changed directly, and the function mutator
Now, we add a mutation
store
, and add a function attribute addTodo
. The first parameter of mutator
The second optional parameter is store, and the second is the data to be passed.
// src/store/index.js
import { createStore } from "vuex";
export default createStore({
state () {
return {
todos: []
}
},
mutations: {
addTodo (state, item) {
state.todos.unshift(item);
}
}
});
Use commit to call mutation
Now, you can TodoNew
use its components, in TodoNew
define a component addTodo
method.
To access store
, we can use the global attribute this.$store
. Use the commit
method to create a new mutation
. Two parameters need to be passed-the first is mutation
, and the second is the object we want to pass, which is a new to-do item (composed of id
and task
values).
// src/components/TodoNew.vue
methods: {
addTodo: function() {
const { id, task } = this;
this.$store.commit("addTodo", { id, task });
this.id++;
this.task = "";
}
}
review
so far:
- The user enters the to-do item through the input box and binds it to the variable
task
- After submitting the form, the
addTodo
method will be called - Create a to-do object and "submit" it to
store
.
// src/components/TodoNew.vue
<template>
<form @submit.prevent="addTodo">
<input
type="text"
placeholder="Enter a new task"
v-model="task"
/>
</form>
</template>
<script>
export default {
data() {
return {
task: "",
id: 0
};
},
methods: {
addTodo: function() {
const { id, task } = this;
this.$store.commit("addTodo", { id, task });
this.id++;
this.task = "";
}
}
};
</script>
Read store data
Now, we have created the function for adding to-do items. The next step is to display them.
Create a new component TodoList.vue
file.
touch src/components/TodoList.vue
The content is as follows:
// src/components/TodoList.vue
<template>
<ul>
<li
v-for="todo in todos"
:key="todo.id"
>
{{ todo.description }}
</li>
</ul>
</template>
todos
is a calculated attribute in which we return the contents of the Vuex store.
// src/components/TodoList.vue
<script>
export default {
computed: {
todos() {
//
}
}
};
</script>
Define getters
And direct access store
different content, getter
is similar to the function of calculating an attribute store. These tools are great for filtering or transforming data before returning it to the application.
For example, there is getTodos
below, which returns an unfiltered state. In many cases, you can use filter
or map
to convert this content.
todoCount
returns the length of the todo
By ensuring that the component is willing to keep a local copy of the data, getter
helps achieve principle 1 , which is a single source of data.
// src/store/index.js
export default createStore({
...
getters: {
getTodos (state) {
return state.todos;
},
todoCount (state) {
return state.todos.length;
}
}
})
Returning to the TodoList
component, we complete the function this.$store.getters.getTodos
// src/components/TodoList.vue
<script>
export default {
computed: {
todos() {
return this.$store.getters.getTodos;
}
}
};
</script>
App.vue
To complete this application, all we have to do now is to import and declare our component App.vue
// src/App.vue
<template>
<div>
<h1>To-Do List</h1>
<div>
<TodoNew />
<TodoList />
</div>
</div>
</template>
<script>
import TodoNew from "@/components/TodoNew.vue";
import TodoList from "@/components/TodoList.vue";
export default {
components: {
TodoNew,
TodoList
}
};
</script>
Do you really need Vuex?
Obviously, in large applications, having a global state management solution will help make our applications predictable and maintainable.
But for relatively small projects, sometimes I feel that using Vuex is too much to use, and it is more reasonable for everyone to follow the actual needs.
Advantages of
- Easy to manage global status
- Powerful debugging global status
Vuex disadvantages:
- Additional project dependencies
- Cumbersome template
~ End, I’m Shuawanzhi, I’ll do it, see you next time!
Original: https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/
code is deployed, the possible bugs cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .
communicate with
There are dreams and dry goods. search 160aee812f4229 [Great Move to the World] Follow this brushing wisdom who is still doing dishes in the early morning.This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line interview complete test site, information and my series of articles.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。