首頁 > web前端 > Vue.js > 主體

什麼是Vuex? Vuex 4初學者指南

青灯夜游
發布: 2021-07-06 19:21:13
轉載
2806 人瀏覽過

這篇文章帶大家了解Vuex,介紹如何在應用程式中使用 Vuex。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

什麼是Vuex? Vuex 4初學者指南

Vuex 是 Vue.js 生態系統中不可或缺的工具。但是新接觸 Vuex 的開發人員可能會被諸如「狀態管理模式」這樣的術語所排斥,並且對他們實際需要Vuex的目的感到困惑。 【相關推薦:《vue.js教學》】

本文算是 Vuex的入門,當然也會 Vuex 的高階概念,並向大家展示如何在應用程式中使用 Vuex。

Vuex 解決的問題

要理解Vuex,首先要理解它要解決的問題。

假設我們開發了一個多用戶聊天應用程式。介面有使用者清單、私人聊天視窗、帶有聊天記錄的收件匣和通知欄,通知使用者目前未查看的其他使用者的未讀訊息。

數以百萬計的用戶每天透過我們的應用程式與數以百萬計的其他用戶聊天。然而,有人抱怨一個惱人的問題:通知欄偶爾會給予錯誤的通知。用戶被通知有一條新的未讀訊息,但當他們查看時,它只是一條已經被看過的訊息。

該作者所描述的是幾年前 Facebook 開發人員在其聊天系統中遇到的真實情況。解決這一問題的過程中 開發人員建立名為 "Flux"的應用程式體系結構。 Flux 構成了Vuex,Redux 和其它類似函式庫的基礎。

Flux

Facebook開發者為「殭屍通知」這個問題,苦苦掙扎了一段時間。他們最終意識到,它的持久性不僅僅是一個簡單的缺陷——它指出了應用程式架構中的一些潛在缺陷。

抽像中最容易理解該缺陷:當應用程式中有多個共享資料的元件時,它們互連的複雜性將增加到無法預測或理解資料狀態的地步。因此,該應用程式無法擴展或維護。

Flux 是一個模式,不是一個函式庫。我們不能去Github下載 Flux。它是一種類似MVC的設計模式。像Vuex和Redux這樣的函式庫實作Flux模式的方式與其他框架實作MVC模式的方式相同。

事實上,Vuex並沒有實作Flux的全部,只是子集。不過現在不要擔心這個問題,我們要專注於理解它所遵循的關鍵原則。

原則1:單一來源

元件可能具有隻需要了解的本機資料。例如,捲軸在使用者清單元件中的位置可能與其他元件無關。

但是,要在元件之間共享的任何資料(即應用程式資料)都必須保存在一個單獨的位置,與使用它的元件分開。

這個單一位置稱為 "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;
    }   
  } 
};
登入後複製

原則2:資料是唯讀的

元件可以從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(&#39;increment&#39;, 10);
登入後複製

原則3:mutation 是同步的

如果應用程式在其體系結構中實現了上述兩個原則,那麼調試資料不一致就容易得多。可以記錄提交並觀察狀態如何變化(在使用Vue Devtools 時確實可以這樣做)。

但如果我們的mutation被非同步調用,這種能力就會被削弱。我們知道提交的順序,但我們不知道組件提交它們的順序。

同步mutation可確保狀態不取決於不可預測事件的順序和時間。

太酷了,那 Vuex 到底是什麼?

有了所有這些背景知識,我們終於可以解決這個問題-Vuex 是一個函式庫,可幫助我們在Vue應用程式中實作Flux架構。透過執行上述原則,即使在多個元件之間共用資料時,Vuex 仍可將我們的應用程式資料保持在透明且可預測的狀態。

現在,我們已經對Vuex有了一個高級的了解,我們看看如何在實際專案中建立基於Vuex的應用程式。

做一個使用 Vuex to-do-list

為了示範Vuex的用法,我們設定一個簡單的待辦應用程式。大家可以在此處存取程式碼的有效範例。

示例地址:https://codesandbox.io/s/happ...

如果大家自己的电脑尝试一波,那么可以使用下面的命令:

vue create vuex-example
登入後複製

安装 Vuex

cd vuex-example
npm i -S vuex@4
npm run serve
登入後複製

创建一个 Vuex store

现在,创建 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({});
登入後複製

将 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");
登入後複製

创建一个简单的应用程序

如上所述,Vuex 的重点是通常在大型应用程序中创建可扩展的全局状态。 但是,我们可以在一个简单的待办应用程序中演示其功能。

完成后效果如下所示:

什麼是Vuex? Vuex 4初學者指南

现在,删除 HelloWorld 文件:

rm src/components/HelloWorld.vue
登入後複製

TodoNew.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>
登入後複製

定义 store 状态

过会,我们会创建一个显示待办事项的组件。 由于它和TodoNew组件都需要访问相同的数据,因此这是我们在 Vuex 存储中保存的全局state 的理想选择。

现在,回到state并定义属性状态。 这里使用 Vux4 提供的 createStore 函数,该函数返回一个对象。 该对象具有一个属性 todos,它是一个空数组。

// src/store/index.js
import { createStore } from "vuex";

export default createStore({
  state () {
    return {
      todos: []
    }
  }
});
登入後複製

定义 mutation

从原则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);
    }
  }
});
登入後複製

使用 commit 调用 mutation

现在,可以在TodoNew组件中使用它,在 TodoNew组件定义一个addTodo方法。

要访问store ,我们可以使用全局属性this.$store。 使用commit方法创建一个新的mutation。 需要传递了两个参数-首先是mutation的名称,其次是我们要传递的对象,是一个新的待办事项(由idtask值组成)。

// 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>
登入後複製

读取 store 数据

现在,我们已经创建了用于添加待办事项的功能。 接下来,就是把它们显示出来。

创建一个新组件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>
登入後複製

定义 getters

与直接访问store 内容不同,getter是类似于存储的计算属性的函数。在将数据返回到应用程序之前,这些工具非常适合过滤或转换数据。

例如,下面有getTodos,它返回未过滤的状态。 在许多情况下,可以使用filtermap来转换此内容。

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的優點:

  • 易於管理全域狀態
  • 強大的偵錯全域狀態

Vuex的缺點:

  • 額外的項目依賴
  • 繁瑣的模板

##英文原文網址:https://vuejsdevelopers.com/2017/05/15/vue-js-what-is-vuex/

作者:Anthony Gore

#轉載位址:https ://segmentfault.com/a/1190000039872016

更多程式相關知識,請造訪:

程式設計入門! !

以上是什麼是Vuex? Vuex 4初學者指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:segmentfault.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板