이 기사에서는 Vuex를 소개하고 애플리케이션에서 Vuex를 사용하는 방법을 소개합니다. 도움이 필요한 친구들이 모두 참고할 수 있기를 바랍니다.
Vuex
는 Vue.js 생태계의 필수 도구입니다. 그러나 Vuex를 처음 접하는 개발자는 "상태 관리 패턴"과 같은 용어로 인해 실제로 Vuex가 필요한 것이 무엇인지 혼란스러워할 수 있습니다. [관련 추천: "vue.js 튜토리얼"]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"
라는 애플리케이션 아키텍처를 만들었습니다. Flux는 Vuex, Redux 및 기타 유사한 라이브러리의 기초를 형성합니다. 🎜🎜🎜Flux🎜🎜🎜 Facebook 개발자들은 한동안 "좀비 알림" 문제로 어려움을 겪고 있습니다. 그들은 결국 그 지속성이 단순한 결함 이상이라는 것을 깨달았습니다. 이는 애플리케이션 아키텍처의 근본적인 결함을 지적했습니다. 🎜🎜이 결함은 추상적으로 이해하기 가장 쉽습니다. 애플리케이션에 데이터를 공유하는 여러 구성 요소가 있는 경우 데이터 상태를 예측하거나 이해할 수 없을 정도로 상호 연결의 복잡성이 증가합니다. 따라서 애플리케이션을 확장하거나 유지 관리할 수 없습니다. 🎜🎜Flux
는 라이브러리가 아니라 패턴입니다. Flux를 다운로드하기 위해 Github로 이동할 수 없습니다. MVC와 유사한 디자인 패턴이다. Vuex 및 Redux와 같은 라이브러리는 다른 프레임워크가 MVC 패턴을 구현하는 것과 동일한 방식으로 Flux 패턴을 구현합니다. 🎜🎜사실 Vuex는 Flux 전체를 구현하지 않고 일부만 구현합니다. 하지만 지금은 걱정하지 마세요. 여기서 따르는 핵심 원칙을 이해하는 데 집중하겠습니다. 🎜🎜🎜원칙 1: 단일 소스 🎜🎜🎜구성 요소에는 알아야 할 로컬 데이터가 있을 수 있습니다. 예를 들어, 사용자 목록 구성 요소의 스크롤 막대 위치는 다른 구성 요소와 독립적일 수 있습니다. 🎜🎜그러나 구성 요소 간에 공유되는 모든 데이터(예: 애플리케이션 데이터)는 이를 사용하는 구성 요소와 별도로 별도의 위치에 보관해야 합니다. 🎜🎜이 단일 위치를 "스토어"라고 합니다. 구성 요소는 이 위치에서 애플리케이션 데이터를 읽어야 하며 충돌이나 차이를 방지하기 위해 자체 복사본을 유지할 수 없습니다. 🎜vue create vuex-example
store
에서 데이터를 자유롭게 읽을 수 있습니다. 그러나 store
의 데이터는 적어도 직접적으로는 변경할 수 없습니다. 🎜🎜대신 데이터 변경 의도를 store
에 알려야 하며, 이는 mutation
이라는 정의된 함수 세트를 통해 데이터 변경을 담당합니다. 🎜🎜왜 이 방법인가요? 데이터 변경 로직을 중앙 집중화하면 상태가 일관되지 않은 경우 각 특정 파일로 이동할 필요 없이 동일한 위치에서만 확인하면 됩니다. 우리는 일부 무작위 구성 요소(아마도 타사 모듈에서)가 예상치 못한 방식으로 데이터를 변경할 가능성을 최소화합니다. 🎜cd vuex-example npm i -S vuex@4 npm run serve
mutation
이 비동기적으로 호출되면 이 기능이 약화됩니다. 우리는 제출 순서를 알고 있지만 구성 요소가 제출하는 순서는 모릅니다. 🎜🎜동기식 변형
은 상태가 예측할 수 없는 이벤트의 순서와 타이밍에 의존하지 않도록 보장합니다. 🎜🎜🎜멋지네요. Vuex가 정확히 무엇인가요? 🎜🎜🎜이 모든 배경 지식을 통해 마침내 문제를 해결할 수 있습니다. Vuex는 Vue 애플리케이션에서 Flux 아키텍처를 구현하는 데 도움이 되는 라이브러리입니다. 위의 원칙을 적용함으로써 Vuex는 데이터가 여러 구성 요소 간에 공유되는 경우에도 애플리케이션 데이터를 투명하고 예측 가능한 상태로 유지합니다. 🎜🎜이제 Vuex에 대해 높은 수준으로 이해했으니 실제 프로젝트에서 Vuex 기반 애플리케이션을 만드는 방법을 살펴보겠습니다. 🎜🎜🎜Vuex를 사용하여 할 일 목록 만들기🎜🎜🎜Vuex 사용을 시연하기 위해 간단한 할 일 애플리케이션을 설정했습니다. 여기에서 코드의 작업 예제에 액세스할 수 있습니다. 🎜示例地址: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>
显然,在大型应用程序中,拥有全局状态管理解决方案将有助于让我们的应用程序可预测和可维护。
그러나 상대적으로 작은 프로젝트의 경우 Vuex를 사용하는 것이 과도하다고 느낄 때가 있으며 모든 사람이 실제 요구 사항을 따르는 것이 더 합리적이라고 생각합니다.
Vuex의 장점:
Vuex의 단점:
영어 원래 주소 : https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/
저자: Anthony Gore
재인쇄 주소: https://segmentfault.com/a/1190000039872016
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 소개를 방문하세요! !
위 내용은 Vuex란 무엇인가요? Vuex 4 초보자 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!