新聞中心
Vuex 是 Vue.js 生態(tài)系統(tǒng)中必不可少的工具。但是新接觸 Vuex 的開發(fā)人員可能會被諸如“狀態(tài)管理模式”這樣的術語所排斥,并且對他們實際需要Vuex的目的感到困惑。

創(chuàng)新互聯(lián)公司專注于保靖網站建設服務及定制,我們擁有豐富的企業(yè)做網站經驗。 熱誠為您提供保靖營銷型網站建設,保靖網站制作、保靖網頁設計、保靖網站官網定制、微信小程序定制開發(fā)服務,打造保靖網絡公司原創(chuàng)品牌,更為您提供保靖網站排名全網營銷落地服務。
本文算是 Vuex的入門,當然也會 Vuex 的高級概念,并向大家展示如何在應用程序中使用 Vuex。
Vuex 解決的問題
要理解Vuex,首先要理解它要解決的問題。
假設我們開發(fā)了一個多用戶聊天應用。界面有用戶列表、私人聊天窗口、帶有聊天記錄的收件箱和通知欄,通知用戶當前未查看的其他用戶的未讀消息。
數(shù)以百萬計的用戶每天通過我們的應用與數(shù)以百萬計的其他用戶聊天。然而,有人抱怨一個惱人的問題:通知欄偶爾會給出錯誤的通知。用戶被通知有一條新的未讀消息,但當他們查看時,它只是一條已經被看過的消息。
該作者所描述的是幾年前 Facebook 開發(fā)人員在其聊天系統(tǒng)中遇到的真實情況。解決這一問題的過程中 開發(fā)人員創(chuàng)建名為 **"Flux"**的應用程序體系結構。Flux 構成了Vuex,Redux 和其它類似庫的基礎。
Flux
Facebook開發(fā)者為“僵尸通知”這個問題,苦苦掙扎了一段時間。他們最終意識到,它的持久性不僅僅是一個簡單的缺陷——它指出了應用程序架構中的一些潛在缺陷。
抽象中最容易理解該缺陷:當應用程序中有多個共享數(shù)據(jù)的組件時,它們互連的復雜性將增加到無法預測或理解數(shù)據(jù)狀態(tài)的地步。因此,該應用程序無法擴展或維護。
Flux 是一個模式,不是一個庫。我們不能去Github下載 Flux。它是一種類似MVC的設計模式。像Vuex和Redux這樣的庫實現(xiàn)Flux模式的方式與其他框架實現(xiàn)MVC模式的方式相同。
事實上,Vuex并沒有實現(xiàn)Flux的全部,只是一個子集。不過現(xiàn)在不要擔心這個問題,我們關注于理解它所遵循的關鍵原則。
原則1:單一來源
組件可能具有僅需要了解的本地數(shù)據(jù)。例如,滾動條在用戶列表組件中的位置可能與其他組件無關。
但是,要在組件之間共享的任何數(shù)據(jù)(即應用程序數(shù)據(jù))都必須保存在一個單獨的位置,與使用它的組件分開。
這個單一位置稱為 "store"。組件必須從該位置讀取應用程序數(shù)據(jù),并且不能保留其自己的副本以防止沖突或分歧。
- import { createStore } from "vuex";
- // Instantiate our Vuex store
- const store = createStore({
- // "State" 組件的應用程序數(shù)據(jù)
- state () {
- return {
- myValue: 0
- };
- }
- });
- // 組件從其計算的屬性訪問 state
- const MyComponent = {
- template: "
{{ myValue }}",- computed: {
- myValue () {
- return store.state.myValue;
- }
- }
- };
原則2:數(shù)據(jù)是只讀的
組件可以從store中自由讀取數(shù)據(jù)。但是不能更改 store 中的數(shù)據(jù),至少不能直接更改。
取而代之的是,它們必須告知 store 要更改數(shù)據(jù)的意圖,store由負責通過一組定義的功能(稱為mutation)進行更改。
為什么采用這種方法?如果我們集中數(shù)據(jù)更改邏輯,那么在狀態(tài)不一致的情況下,我們只需要在同一地方排查就行了,不用到具體的每個文件中。我們將某些隨機組件(可能在第三方模塊中)以意外方式更改數(shù)據(jù)的可能性降至最低。
- const store = createStore({
- state() {
- return {
- myValue: 0
- };
- },
- mutations: {
- increment (state, value) {
- state.myValue += value;
- }
- }
- });
- // 需要更新值嗎?
- // 錯誤的,不要直接更改 store 值
- store.myValue += 10;
- // 正確的,調用正確的 mutations。
- store.commit('increment', 10);
原則3:mutation 是同步的
如果應用程序在其體系結構中實現(xiàn)了上述兩個原則,那么調試數(shù)據(jù)不一致就容易得多??梢杂涗浱峤徊⒂^察狀態(tài)如何變化(在使用Vue Devtools 時確實可以這樣做)。
但如果我們的mutation被異步調用,這種能力就會被削弱。我們知道提交的順序,但我們不知道組件提交它們的順序。
同步mutation可確保狀態(tài)不取決于不可預測事件的順序和時間。
太酷了,那么 Vuex 到底是什么?
有了所有這些背景知識,我們終于可以解決這個問題-Vuex 是一個庫,可幫助我們在Vue應用程序中實現(xiàn)Flux架構。通過執(zhí)行上述原則,即使在多個組件之間共享數(shù)據(jù)時,Vuex 仍可將我們的應用程序數(shù)據(jù)保持在透明且可預測的狀態(tài)。
現(xiàn)在,我們已經對Vuex有了一個高級的了解,我們看看如何在實際項目創(chuàng)建基于Vuex的應用程序。
做一個使用 Vuex to-do-list
為了演示Vuex的用法,我們設置一個簡單的待辦應用程序。大家可以在此處訪問代碼的有效示例。
示例地址:https://codesandbox.io/s/happy-williams-rdni7
如果大家自己的電腦嘗試一波,那么可以使用下面的命令:
- vue create vuex-example
安裝 Vuex
- cd vuex-example
- npm i -S vuex@4
- npm run serve
創(chuàng)建一個 Vuex store
現(xiàn)在,創(chuàng)建 Vuex store,在項目中創(chuàng)建 src/store/index.js:
- mkdir src/store
- touch src/store/index.js
打開文件并導入createStore方法。此方法用于定義store及其特性?,F(xiàn)在,我們導出該store ,以便在Vue應用中能訪問它。
- // src/store/index.js
- import { createStore } from "vuex";
- export default createStore({});
將 store 添加到 Vue 實例
為了可以從任何組件中訪問 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");
創(chuàng)建一個簡單的應用程序
如上所述,Vuex 的重點是通常在大型應用程序中創(chuàng)建可擴展的全局狀態(tài)。但是,我們可以在一個簡單的待辦應用程序中演示其功能。
完成后效果如下所示:
現(xiàn)在,刪除 HelloWorld 文件:
- rm src/components/HelloWorld.vue
TodoNew.vue
現(xiàn)在,添加一個新組件 TodoNew,它負責創(chuàng)建新的待辦事項。
- touch src/components/TodoNew.vue
打開 TodoNew.vue 并輸入以下內容:
- // src/components/TodoNew.vue
- type="text"
- placeholder="Enter a new task"
- v-model="task"
- />
現(xiàn)在轉到組件定義,有兩個局部狀態(tài)屬性-task和給新待辦事項提供唯一標識符的id。
- // src/components/TodoNew.vue
- ...
定義 store 狀態(tài)
過會,我們會創(chuàng)建一個顯示待辦事項的組件。由于它和TodoNew組件都需要訪問相同的數(shù)據(jù),因此這是我們在 Vuex 存儲中保存的全局state 的理想選擇。
現(xiàn)在,回到state并定義屬性狀態(tài)。這里使用 Vux4 提供的 createStore 函數(shù),該函數(shù)返回一個對象。該對象具有一個屬性 todos,它是一個空數(shù)組。
- // src/store/index.js
- import { createStore } from "vuex";
- export default createStore({
- state () {
- return {
- todos: []
- }
- }
- });
定義 mutation
從原則2可以知道,Vuex state 不能直接更改,需要定義mutator函數(shù)。
現(xiàn)在,我們向store添加一個mutation屬性,并添加一個函數(shù)屬性addTodo。所有mutator方法第一個參數(shù)。第二個可選參數(shù)是 store,第二個是傳遞的數(shù)據(jù)。
- // src/store/index.js
- import { createStore } from "vuex";
- export default createStore({
- state () {
- return {
- todos: []
- }
- },
- mutations: {
- addTodo (state, item) {
- state.todos.unshift(item);
- }
- }
- });
使用 commit 調用 mutation
現(xiàn)在,可以在TodoNew組件中使用它,在 TodoNew組件定義一個addTodo方法。
要訪問store ,我們可以使用全局屬性this.$store。使用commit方法創(chuàng)建一個新的mutation。需要傳遞了兩個參數(shù)-首先是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方法
- 創(chuàng)建一個待辦事項對象并將其“提交”到store中。
- // src/components/TodoNew.vue
- type="text"
- placeholder="Enter a new task"
- v-model="task"
- />
讀取 store 數(shù)據(jù)
現(xiàn)在,我們已經創(chuàng)建了用于添加待辦事項的功能。接下來,就是把它們顯示出來。
創(chuàng)建一個新組件TodoList.vue 文件。
- touch src/components/TodoList.vue
內容如下:
- // src/components/TodoList.vue
- v-for="todo in todos"
- :key="todo.id"
- >
- {{ todo.description }}
todos是一個計算屬性,我們在其中返回Vuex store 的內容。
- // src/components/TodoList.vue
定義 getters
與直接訪問store 內容不同,getter是類似于存儲的計算屬性的函數(shù)。在將數(shù)據(jù)返回到應用程序之前,這些工具非常適合過濾或轉換數(shù)據(jù)。
例如,下面有getTodos,它返回未過濾的狀態(tài)。在許多情況下,可以使用filter或map來轉換此內容。
todoCount返回todo數(shù)組的長度。
通過確保組件愿意保留數(shù)據(jù)的本地副本,getter有助于實現(xiàn)原則1,即單一數(shù)據(jù)來源。
- // 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
App.vue
要完成此應用程序,現(xiàn)在要做的就是導入并在App.vue中聲明我們的組件。
- // src/App.vue
To-Do List
你真的需要Vuex嗎?
顯然,在大型應用程序中,擁有全局狀態(tài)管理解決方案將有助于讓我們的應用程序可預測和可維護。
但對于比較小的項目,有時候覺得使用 Vuex 太大材小用了,還這個還是大家跟著實際需求走比較合理。
Vuex的優(yōu)點:
- 易于管理全局狀態(tài)
- 強大的調試全局狀態(tài)
Vuex的缺點:
- 額外的項目依賴
- 繁瑣的模板
~ 完, 我是刷碗智,刷碗去咯,下期見!
作者:Anthony Gore 譯者:前端小智 來源:vuejsdevelopers
原文:https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/
分享標題:Vuex 4 指南,使用 Vue3 的需要看看!
文章網址:http://fisionsoft.com.cn/article/djjggjj.html


咨詢
建站咨詢
