Vuex原理:通过Vuex实现TodoList

开发 前端
「Vuex」 是一个专为 Vue.js 应用程序开发的状态管理模式。它可以集中管理应用中的组件共享状态,并提供一些工具来保持状态的一致性。

什么是Vuex

「Vuex」 是一个专为 Vue.js 应用程序开发的状态管理模式。它可以集中管理应用中的组件共享状态,并提供一些工具来保持状态的一致性。Vuex 主要用于解决以下问题:

  • 「组件通信」:在大型的 Vue.js 应用中,多个组件可能需要共享一些状态(数据)。而通过简单的组件通信方式(props、自定义事件)在复杂的组件关系中可能会变得不够灵活或繁琐。
  • 「状态管理」:Vue.js 的单向数据流通过 props 将数据从父组件传递给子组件,但对于多层嵌套的组件结构,数据流管理可能变得复杂。Vuex 提供了一种集中式管理状态的方式,使得状态的变更变得可预测且易于调试。

以下是 Vuex 的核心概念:

1. 「State(状态)」

Vuex 使用一个包含应用层级状态的对象,即 State。这个状态是响应式的,当状态发生变化时,相关组件将自动更新。

const store = new Vuex.Store({
  state: {
    count: 0
  }
});

2. 「Mutations(变更)」

状态的变更必须通过 Mutations 来进行。Mutations 是同步函数,用于修改状态。通过这种方式,可以追踪状态的变更,并且可以实现一些限制条件,确保状态的可控性。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

3. 「Actions(动作)」

Actions 是用于提交 Mutations 的函数,可以包含异步操作。通过 Actions,可以更灵活地处理业务逻辑,例如异步请求或条件判断。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  }
});

4. 「Getters(获取器)」

Getters 允许组件在访问状态时进行计算,类似于 Vue 组件中的计算属性。Getters 的结果会被缓存,只有依赖的状态发生变化时才会重新计算。

const store = new Vuex.Store({
  state: {
    count: 0
  },
  getters: {
    doubleCount: state => state.count * 2
  }
});

5. 「Modules(模块)」

Vuex 允许将 Store 分割成模块,每个模块拥有自己的 state、mutations、actions、getters。这样可以更好地组织大型的 Store。

const moduleA = {
  state: { /* ... */ },
  mutations: { /* ... */ },
  actions: { /* ... */ },
  getters: { /* ... */ }
};


const store = new Vuex.Store({
  modules: {
    a: moduleA
  }
});

6. 单一状态树

Vuex 使用一个单一的状态树来管理应用中的所有状态。这使得整个应用的状态变化可追踪和调试。

7. Plugin(插件)

Vuex 允许通过插件扩展其功能。插件是一个函数,可以在每次 mutation 发生时执行一些自定义的逻辑,例如记录日志或持久化存储。

// Vuex 插件示例
const myPlugin = store => {
  // 每次 mutation 时调用
  store.subscribe((mutation, state) => {
    console.log('mutation type:', mutation.type);
  });
};

8. 严格模式

Vuex 提供了严格模式,用于检测 State 的变更是否是通过 Mutations 进行的。在开发环境中启用严格模式可以帮助捕获不合规的状态变更。

const store = new Vuex.Store({
  // ...
  strict: process.env.NODE_ENV !== 'production'
});

通过这些概念,Vuex 提供了一种集中式状态管理的解决方案,使得状态在应用中的传递和管理更为清晰和可维护。Vuex 不是必需的,尤其对于小型应用可能会显得繁琐,但在大型、复杂的应用中,它提供了一种有组织的方法来管理状态。

利用Vuex实现一个tudoList

简单了解一下Vuex之后呢,实现一个小案例。下面是一个使用 Vue 3 和 Vuex 的简单的 Todo List 示例。使用前需要先下载依赖。这个应该都会吧。创建一个 store 文件夹,并在其中创建 index.js 文件来定义 Vuex 的 store:

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


export default createStore({
  state: {
    todos: []
  },
  mutations: {
    addTodo(state, todo) {
      state.todos.push(todo);
    },
    toggleTodo(state, index) {
      state.todos[index].completed = !state.todos[index].completed;
    },
    removeTodo(state, index) {
      state.todos.splice(index, 1);
    }
  },
  actions: {
    addTodoAsync({ commit }, todo) {
      setTimeout(() => {
        commit('addTodo', todo);
      }, 1000);
    }
  },
  getters: {
    completedTodos: state => state.todos.filter(todo => todo.completed),
    remainingTodos: state => state.todos.filter(todo => !todo.completed)
  }
});

然后在 App.vue 文件中使用这个 store:

// App.vue
<template>
  <div id="app">
    <h1>Todo List</h1>
    <form @submit.prevent="addTodo">
      <input v-model="newTodo" placeholder="Add a new todo" />
      <button type="submit">Add</button>
    </form>


    <div>
      <h2>Todo Items</h2>
      <ul>
        <li v-for="(todo, index) in todos" :key="index">
          <input type="checkbox" v-model="todo.completed" />
          {{ todo.text }}
          <button @click="removeTodo(index)">Remove</button>
        </li>
      </ul>
    </div>


    <div>
      <h2>Completed Todos</h2>
      <ul>
        <li v-for="(todo, index) in completedTodos" :key="index">
          {{ todo.text }}
        </li>
      </ul>
    </div>


    <div>
      <h2>Remaining Todos</h2>
      <ul>
        <li v-for="(todo, index) in remainingTodos" :key="index">
          {{ todo.text }}
        </li>
      </ul>
    </div>
  </div>
</template>


<script>
import { computed } from 'vue';
import { useStore } from 'vuex';


export default {
  name: 'App',
  data() {
    return {
      newTodo: ''
    };
  },
  methods: {
    addTodo() {
      this.$store.commit('addTodo', { text: this.newTodo, completed: false });
      this.newTodo = '';
    },
    removeTodo(index) {
      this.$store.commit('removeTodo', index);
    }
  },
  computed: {
    todos() {
      return this.$store.state.todos;
    },
    completedTodos: computed(() => useStore().getters.completedTodos),
    remainingTodos: computed(() => useStore().getters.remainingTodos)
  }
};
</script>


<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}


form {
  margin-bottom: 20px;
}


ul {
  list-style-type: none;
  padding: 0;
}


li {
  margin-bottom: 5px;
}
</style>

这个示例中,我们使用 Vuex 来管理 todo 列表的状态,包括添加新 todo、切换 todo 状态、删除 todo 等功能。在模板中,我们使用了 v-for 指令来渲染 todo 列表,并通过 Vuex 的 getters 计算属性显示已完成和未完成的 todo 列表。

小结

使用vuex能够实现组件之间的通信,它是一个状态管理机制,集中管理组件共享状态。

责任编辑:武晓燕 来源: 海燕技术栈
相关推荐

2021-08-03 08:35:36

Vuex数据热更新

2021-07-16 22:49:50

PiniaVuex替代品

2021-11-15 08:16:05

Vue 技巧 开发工具

2021-07-26 23:57:48

Vuex模块项目

2019-08-09 10:33:36

开发技能代码

2022-03-27 09:06:25

vuexActionsMutations

2022-02-08 11:45:03

PiniaVuex前端

2024-12-20 09:12:00

Vue项目Pinia

2020-07-29 19:40:36

Vue 3.0Vue前端

2022-06-29 10:04:01

PiniaVuex

2021-05-20 07:26:21

工具Vuex Vue.js

2021-06-01 20:38:04

Vuex对象import

2022-02-09 23:02:53

Vuex开发管理模式

2021-10-20 08:49:30

Vuexvue.js状态管理模式

2024-06-07 09:30:22

vue2Vuex存储

2024-01-15 06:51:18

字典前端开发

2021-06-01 07:55:43

Vuex使用流程

2022-05-31 09:09:10

vuex技巧前端

2020-02-25 17:18:13

vuexvue前端

2017-07-07 16:07:41

点赞
收藏

51CTO技术栈公众号