Dieser Artikel führt Sie durch Vuex und stellt vor, wie Sie Vuex in Anwendungen verwenden. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird für alle hilfreich sein.
Vuex
ist ein wesentliches Werkzeug im Vue.js-Ökosystem. Aber Entwickler, die neu bei Vuex sind, könnten durch Begriffe wie „Zustandsverwaltungsmuster“ abgeschreckt werden und verwirrt sein, wofür sie Vuex tatsächlich benötigen. [Verwandte Empfehlung: „vue.js-Tutorial"]Vuex
是 Vue.js 生态系统中必不可少的工具。但是新接触 Vuex 的开发人员可能会被诸如“状态管理模式”这样的术语所排斥,并且对他们实际需要Vuex的目的感到困惑。【相关推荐:《vue.js教程》】
本文算是 Vuex的入门,当然也会 Vuex 的高级概念,并向大家展示如何在应用程序中使用 Vuex。
要理解Vuex,首先要理解它要解决的问题。
假设我们开发了一个多用户聊天应用。界面有用户列表、私人聊天窗口、带有聊天记录的收件箱和通知栏,通知用户当前未查看的其他用户的未读消息。
数以百万计的用户每天通过我们的应用与数以百万计的其他用户聊天。然而,有人抱怨一个恼人的问题:通知栏偶尔会给出错误的通知。用户被通知有一条新的未读消息,但当他们查看时,它只是一条已经被看过的消息。
该作者所描述的是几年前 Facebook 开发人员在其聊天系统中遇到的真实情况。 解决这一问题的过程中 开发人员创建名为 "Flux"的应用程序体系结构。 Flux 构成了Vuex,Redux 和其它类似库的基础。
Facebook开发者为“僵尸通知”这个问题,苦苦挣扎了一段时间。他们最终意识到,它的持久性不仅仅是一个简单的缺陷——它指出了应用程序架构中的一些潜在缺陷。
抽象中最容易理解该缺陷:当应用程序中有多个共享数据的组件时,它们互连的复杂性将增加到无法预测或理解数据状态的地步。 因此,该应用程序无法扩展或维护。
Flux
是一个模式,不是一个库。我们不能去Github下载 Flux。它是一种类似MVC的设计模式。像Vuex和Redux这样的库实现Flux模式的方式与其他框架实现MVC模式的方式相同。
事实上,Vuex并没有实现Flux的全部,只是一个子集。不过现在不要担心这个问题,我们关注于理解它所遵循的关键原则。
组件可能具有仅需要了解的本地数据。 例如,滚动条在用户列表组件中的位置可能与其他组件无关。
但是,要在组件之间共享的任何数据(即应用程序数据)都必须保存在一个单独的位置,与使用它的组件分开。
这个单一位置称为 "store"。 组件必须从该位置读取应用程序数据,并且不能保留其自己的副本以防止冲突或分歧。
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; } } };
组件可以从store
中自由读取数据。 但是不能更改 store
中的数据,至少不能直接更改。
取而代之的是,它们必须告知 store
要更改数据的意图,store
由负责通过一组定义的功能(称为mutation
)进行更改。
为什么采用这种方法? 如果我们集中数据更改逻辑,那么在状态不一致的情况下,我们只需要在同一地方排查就行了,不用到具体的每个文件中。 我们将某些随机组件(可能在第三方模块中)以意外方式更改数据的可能性降至最低。
const store = createStore({ state() { return { myValue: 0 }; }, mutations: { increment (state, value) { state.myValue += value; } } }); // 需要更新值吗? // 错误的,不要直接更改 store 值 store.myValue += 10; // 正确的,调用正确的 mutations。 store.commit('increment', 10);
如果应用程序在其体系结构中实现了上述两个原则,那么调试数据不一致就容易得多。可以记录提交并观察状态如何变化(在使用Vue Devtools 时确实可以这样做)。
但如果我们的mutation
被异步调用,这种能力就会被削弱。我们知道提交的顺序,但我们不知道组件提交它们的顺序。
同步mutation
Flux
ist ein Muster, keine Bibliothek. Wir können nicht zu Github gehen, um Flux herunterzuladen. Es handelt sich um ein Designmuster ähnlich wie MVC. Bibliotheken wie Vuex und Redux implementieren das Flux-Muster auf die gleiche Weise, wie andere Frameworks das MVC-Muster implementieren. 🎜🎜Tatsächlich implementiert Vuex nicht den gesamten Flux, sondern nur einen Teil davon. Aber machen Sie sich jetzt darüber keine Sorgen, sondern konzentrieren wir uns darauf, die Grundprinzipien zu verstehen, denen es folgt. 🎜🎜🎜Prinzip 1: Single Source 🎜🎜🎜Komponenten verfügen möglicherweise über lokale Daten, die sie nur kennen müssen. Beispielsweise kann die Position der Bildlaufleiste in einer Benutzerlistenkomponente unabhängig von anderen Komponenten sein. 🎜🎜Allerdings müssen alle Daten, die zwischen Komponenten geteilt werden sollen (d. h. Anwendungsdaten), an einem separaten Ort aufbewahrt werden, getrennt von den Komponenten, die sie verwenden. 🎜🎜Dieser einzelne Standort wird als „Laden“ bezeichnet. Die Komponente muss Anwendungsdaten von diesem Speicherort lesen und kann keine eigene Kopie behalten, um Konflikte oder Abweichungen zu verhindern. 🎜vue create vuex-example
store
frei lesen. Aber die Daten in store
können nicht geändert werden, zumindest nicht direkt. 🎜🎜Stattdessen müssen sie store
über ihre Absicht informieren, die Daten zu ändern, was dafür verantwortlich ist, die Daten über einen definierten Satz von Funktionen namens mutation
zu ändern, um Änderungen vorzunehmen. 🎜🎜Warum diese Methode? Wenn wir die Datenänderungslogik zentralisieren, müssen wir den Status bei inkonsistentem Status nur an derselben Stelle überprüfen, ohne zu jeder einzelnen Datei zu gehen. Wir minimieren die Möglichkeit, dass eine zufällige Komponente (vielleicht in einem Modul eines Drittanbieters) Daten auf unerwartete Weise verändert. 🎜cd vuex-example npm i -S vuex@4 npm run serve
Mutation
asynchron aufgerufen wird, wird diese Fähigkeit geschwächt. Wir kennen die Reihenfolge der Einreichungen, aber wir wissen nicht, in welcher Reihenfolge die Komponenten sie einreichen. 🎜🎜Synchronische Mutation
stellt sicher, dass der Zustand nicht von der Reihenfolge und dem Zeitpunkt unvorhersehbarer Ereignisse abhängt. 🎜🎜🎜Das ist cool, also was genau ist Vuex? 🎜🎜🎜Mit all diesem Hintergrundwissen können wir das Problem endlich in Angriff nehmen – Vuex ist eine Bibliothek, die uns bei der Implementierung der Flux-Architektur in Vue-Anwendungen hilft. Durch die Durchsetzung der oben genannten Prinzipien hält Vuex unsere Anwendungsdaten in einem transparenten und vorhersehbaren Zustand, selbst wenn Daten von mehreren Komponenten gemeinsam genutzt werden. 🎜🎜Da wir nun ein umfassendes Verständnis von Vuex haben, wollen wir uns ansehen, wie man eine Vuex-basierte Anwendung in einem realen Projekt erstellt. 🎜🎜🎜Erstellen Sie eine To-Do-Liste mit Vuex🎜🎜🎜Um die Verwendung von Vuex zu demonstrieren, haben wir eine einfache To-Do-Anwendung eingerichtet. Hier können Sie auf funktionierende Codebeispiele zugreifen. 🎜示例地址:https://codesandbox.io/s/happ...
如果大家自己的电脑尝试一波,那么可以使用下面的命令:
vue create vuex-example
cd vuex-example npm i -S vuex@4 npm run serve
现在,创建 Vuex store,在项目中创建 src/store/index.js
:
mkdir src/store touch src/store/index.js
打开文件并导入createStore
方法。此方法用于定义store
及其特性。现在,我们导出该store
,以便在Vue应用中能访问它。
// src/store/index.js import { createStore } from "vuex"; export default createStore({});
为了可以从任何组件中访问 Vuex store,我们需要在主文件中导入 store
模块,并将store
作为插件安装在主Vue实例上
// 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");
如上所述,Vuex 的重点是通常在大型应用程序中创建可扩展的全局状态。 但是,我们可以在一个简单的待办应用程序中演示其功能。
完成后效果如下所示:
现在,删除 HelloWorld 文件:
rm src/components/HelloWorld.vue
现在,添加一个新组件 TodoNew
,它负责创建新的待办事项。
touch src/components/TodoNew.vue
打开 TodoNew.vue
并输入以下内容:
// src/components/TodoNew.vue <template> <form @submit.prevent="addTodo"> <input type="text" placeholder="Enter a new task" v-model="task" /> </form> </template>
现在转到组件定义,有两个局部状态属性-task
和给新待办事项提供唯一标识符的id
。
// src/components/TodoNew.vue <template>...</template> <script> export default { data() { return { task: "", id: 0 }; }, methods: { addTodo: function() { // } } }; </script>
过会,我们会创建一个显示待办事项的组件。 由于它和TodoNew
组件都需要访问相同的数据,因此这是我们在 Vuex 存储中保存的全局state
的理想选择。
现在,回到state
并定义属性状态。 这里使用 Vux4 提供的 createStore
函数,该函数返回一个对象。 该对象具有一个属性 todos
,它是一个空数组。
// src/store/index.js import { createStore } from "vuex"; export default createStore({ state () { return { todos: [] } } });
从原则2可以知道,Vuex state 不能直接更改,需要定义mutator
函数。
现在,我们向store
添加一个mutation
属性,并添加一个函数属性addTodo
。 所有mutator
方法第一个参数。 第二个可选参数是 store,第二个是传递的数据。
// src/store/index.js import { createStore } from "vuex"; export default createStore({ state () { return { todos: [] } }, mutations: { addTodo (state, item) { state.todos.unshift(item); } } });
mutation
现在,可以在TodoNew
组件中使用它,在 TodoNew
组件定义一个addTodo
方法。
要访问store
,我们可以使用全局属性this.$store
。 使用commit
方法创建一个新的mutation
。 需要传递了两个参数-首先是mutation
的名称,其次是我们要传递的对象,是一个新的待办事项(由id
和task
值组成)。
// src/components/TodoNew.vue methods: { addTodo: function() { const { id, task } = this; this.$store.commit("addTodo", { id, task }); this.id++; this.task = ""; } }
到目前为止:
用户将待办事项通过输入框输入,并绑定到 task
变量。
提交表单后,将调用addTodo
方法
创建一个待办事项对象并将其“提交”到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>
现在,我们已经创建了用于添加待办事项的功能。 接下来,就是把它们显示出来。
创建一个新组件TodoList.vue
文件。
touch src/components/TodoList.vue
内容如下:
// src/components/TodoList.vue <template> <ul> <li v-for="todo in todos" :key="todo.id" > {{ todo.description }} </li> </ul> </template>
todos
是一个计算属性,我们在其中返回Vuex store 的内容。
// src/components/TodoList.vue <script> export default { computed: { todos() { // } } }; </script>
与直接访问store
内容不同,getter
是类似于存储的计算属性的函数。在将数据返回到应用程序之前,这些工具非常适合过滤或转换数据。
例如,下面有getTodos
,它返回未过滤的状态。 在许多情况下,可以使用filter
或map
来转换此内容。
todoCount
返回todo
数组的长度。
通过确保组件愿意保留数据的本地副本,getter
有助于实现原则1,即单一数据来源。
// src/store/index.js export default createStore({ ... getters: { getTodos (state) { return state.todos; }, todoCount (state) { return state.todos.length; } } })
返回TodoList
组件,我们通过返回this.$store.getters.getTodos
来完成功能。
// src/components/TodoList.vue <script> export default { computed: { todos() { return this.$store.getters.getTodos; } } }; </script>
App.vue
要完成此应用程序,现在要做的就是导入并在App.vue
中声明我们的组件。
// src/App.vue <template> <p> <h1>To-Do List</h1> <p> <TodoNew /> <TodoList /> </p> </p> </template> <script> import TodoNew from "@/components/TodoNew.vue"; import TodoList from "@/components/TodoList.vue"; export default { components: { TodoNew, TodoList } }; </script>
显然,在大型应用程序中,拥有全局状态管理解决方案将有助于让我们的应用程序可预测和可维护。
Aber bei relativ kleinen Projekten habe ich manchmal das Gefühl, dass die Verwendung von Vuex übertrieben ist und es für jeden sinnvoller ist, sich an den tatsächlichen Bedürfnissen zu orientieren.
Vorteile von Vuex:
Nachteile von Vuex:
Englisch Ursprüngliche Adresse : https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/
Autor: Anthony Gore
Nachdruckadresse: https://segmentfault.com/a/1190000039872016
Weitere Kenntnisse zum Thema Programmierung finden Sie unter: Einführung in die Programmierung! !
Das obige ist der detaillierte Inhalt vonWas ist Vuex? Anfängerleitfaden zu Vuex 4. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!