Vue详细讲解Vuex状态管理的实现

yizhihongxing

Vue详细讲解Vuex状态管理的实现

什么是Vuex

Vuex是Vue.js的官方状态管理插件,它将组件之间共享的状态抽取出来,以一个全局单例模式管理,实现了在共享状态时一些问题的规避,使代码更容易理解和维护。

Vuex的状态管理机制

Vuex的状态管理机制可以从以下三个方面来解释:

State

状态是存储在Vuex store上的单一状态树,相当于Vue模板上的data。每一个Vuex应用的中央唯一数据存储中都有一个store实例,包含了所有的状态。可以通过store.state来访问。

// store.js
import Vuex from 'vuex'
import Vue from 'vue'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  }
})

上面的代码实现了一个简单的store,包含了一个数值型state变量count,初始值为0。

可以在组件中通过this.$store.state.count来访问该状态。

Getter

Getter就是store的计算属性,相当于Vue模板上的computed。Vuex的store中,Getter相当于从store中派生方法的概念,在通过computed派生出新的属性时,Getter也可以根据需要派生出新的状态。

Getter接受state作为其第一个参数,可以定义计算属性,Getter会缓存计算结果并告诉你何时重新计算(当依赖的状态发生变化时)。

// store.js
export default new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'todo1', done: true },
      { id: 2, text: 'todo2', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  }
})

在上面的代码中,我们新定义了一个Getter,返回已完成的列表。可以在组件中通过this.$store.getters.doneTodos来访问。这样,无论todos状态如何改变,只有当done属性变化时,该Getter才会被重新计算。

Mutation

Mutation是用于修改状态的唯一方法,相当于Vue模板上的methods。Mutation改变store中的状态的唯一方法是提交mutation,mutation就像事件一样来描述发生了什么,每个mutation都有一个字符串类型的操作命名,一个回调函数和一个payload,payload是通常会被作为回调函数的入参传进来。

Mutation必须是同步的,一旦提交了mutation,我们就可以确保state已经同步完成了更新。

// store.js
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment: (state, payload) => {
      state.count += payload.amount
    }
  },
  actions: {
    increment: ({commit}, payload) => {
      commit('increment', payload)
    }
  }
})

在上面的代码中,我们新定义了一个mutation,名为increment,可接受一些额外的参数amount,以更新count变量。

我们可以在组件中派发一个mutation,来实现该操作(假设没有开启严格模式):

// MyComponent.vue
methods: {
    increment () {
      this.$store.commit('increment', { amount: 10 })
    }
}

Action

Action是异步操作,而且可以包含任意异步操作。Action提供给你一个使用异步请求更新状态的方法,并且可以保证该过程是同步的。

Action利用mutation中commit的概念。Action通过store.dispatch方法异步的提交mutation,最终改变state状态。通常Action将服务端请求得到的数据提交给Mutation,成功处理一些业务逻辑后通过Mutation更新State中的状态。

// store.js
export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment: (state, payload) => {
      state.count += payload.amount
    }
  },
  actions: {
    incrementAsync ({commit}, payload) {
      setTimeout(() => {
        commit('increment', payload)
      }, 1000)
    }
  }
})

在上面的代码中,我们新定义了一个Action,名为incrementAsync,受到payload的委托,在1秒钟后再提交该mutation。

我们可以在组件中派发一个Action,来实现该操作(假设没有开启严格模式):

// MyComponent.vue
methods: {
    incrementAsync () {
      this.$store.dispatch('incrementAsync', { amount: 10 })
    }
}

Vuex的核心概念

Store

Store是一个容器,它包含着应用中的所有状态。一个Vuex的Store是由唯一的一个store实例来管理的。

State

State就是存储在Store中的状态数据,State机制遵循源流驱动所提出的思想——即State可以作为源流数据,而对该数据的更新只能通过Action来派发Mutation,进而同步改变State的状态。

Getter

Getter是对State的派生数据,类似于Vue模板中的computed计算属性。Getter常作为模板中computed属性的依赖源。

Mutation

Mutation是同步的改变State中数据的唯一方法。在Mutation中建议只处理简单的动作,这种处理方式可以更容易地跟踪代码的变化。Mutation通过一系列类型名来更新State中的数据。

Action

Action允许更改State的异步数据或更复杂的逻辑,使Action中包含的异步操作可以访问到State并且可以派发Mutation。同时Action的Promise也可以在组件内使用。

Module

Module允许我们将一些较大状态的数据重构为一些具有独立功能的小模块,每个Module具有自己的State、Getter、Mutation和Action。这样,即使应用的状态不断变化或者持续增加,整个代码库也能保持整洁和可维护性。

Vuex实现示例

在Vue项目中使用Vuex非常方便,以下是其中两个示例。

示例一:计数器

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment: state => state.count++,
    decrement: state => state.count--
  },
  actions: {
    increment: ({ commit }) => commit('increment'),
    decrement: ({ commit }) => commit('decrement')
  }
})
<!-- Counter.vue -->
<template>
  <div>
    <h1>Count: {{$store.state.count}}</h1>
    <button @click="$store.dispatch('increment')">+1</button>
    <button @click="$store.dispatch('decrement')">-1</button>
  </div>
</template>

<script>
export default {
  name: 'Counter'
}
</script>

示例二:待办事项

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    todos: [
      { id: 1, text: 'todo1', done: true },
      { id: 2, text: 'todo2', done: false }
    ]
  },
  getters: {
    doneTodos: state => {
      return state.todos.filter(todo => todo.done)
    }
  },
  mutations: {
    toggle: (state, id) => {
      const todo = state.todos.find(todo => todo.id === id)
      todo.done = !todo.done
    },
    add: (state, todo) => {
      state.todos.push(todo)
    }
  },
  actions: {
    toggle: ({commit}, id) => {
      commit('toggle', id)
    },
    add: ({commit}, text) => {
      const todo = {
        id: Date.now(),
        text,
        done: false
      }
      commit('add', todo)
    }
  }
})
<!-- TodoList.vue -->
<template>
  <div>
    <ul>
      <li v-for="todo in $store.state.todos" :key="todo.id">
        <span :class="{ done: todo.done }">{{ todo.text }}</span>
        <button @click="$store.dispatch('toggle', todo.id)">Toggle</button>
      </li>
    </ul>
    <input type="text" v-model="text">
    <button @click="$store.dispatch('add', text)">Add</button>
  </div>
</template>

<script>
export default {
  name: 'TodoList',
  data() {
    return {
      text: ''
    }
  },
  mounted() {
    console.log(this.$store.getters.doneTodos)
  }
}
</script>

<style>
  .done { text-decoration: line-through; }
</style>

结论

Vuex是Vue.js的状态管理插件,可以有效地帮助我们管理应用程序的状态,在使用中体现了源流驱动的思想、模块化的技术手段、设计模式上的优化,其实现机制基于State、Getter、Mutation和Action四个核心概念,可以帮助前端工程师更加规范化、系统化地管理自己的前端代码,提高工作效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue详细讲解Vuex状态管理的实现 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • 解决vue初始化项目一直停在downloading template的问题

    解决Vue初始化项目一直停在downloading template的问题 当我们在使用Vue CLI 3初始化项目时,有时会遇到这样的问题:在命令行中输入vue create project-name后,一直停留在downloading template这一步,无法继续下去,这说明我们无法下载Vue的模板文件导致项目初始化失败。此时我们需要进行以下步骤,以…

    Vue 2023年5月27日
    00
  • 解决vue elementUI中table里数字、字母、中文混合排序问题

    想要解决Vue ElementUI中的Table里数字、字母、中文混合排序问题,我们需要引入一个第三方库:pinyin。pinyin可以将汉字转换成拼音,这可以帮助我们对含有中文的字符串进行排序。 下面是解决这一问题的完整攻略: 安装pinyin 在终端中输入以下命令进行pinyin的安装: npm install pinyin –save 对Table数…

    Vue 2023年5月27日
    00
  • vue2.0 watch里面的 deep和immediate用法说明

    下面我来详细讲解一下 “vue2.0 watch里面的 deep和immediate用法说明”, 希望对你有所帮助。 watch 在Vue.js中,我们可以使用 watch 来监听数据的改变,从而执行对应的操作。 Watch 是 Vue 实例的一个选项属性,用于监听 Vue 实例上的数据变化。当数据发生改变时,会执行 watch 选项的对应方法。 deep …

    Vue 2023年5月29日
    00
  • vue3 element的Form表单用法实例

    我来为你详细讲解“Vue3 Element的Form表单用法实例”的完整攻略: 1. 背景介绍 首先我们来了解一下Vue3 Element,它是一个基于Vue.js框架开发的UI组件库,包含一系列常用的UI组件,非常易于使用和定制。 其中最常用的组件之一就是Form表单,它为我们提供了各种输入控件和验证方法,可以非常方便地构建表单界面,下面就和大家分享一下F…

    Vue 2023年5月28日
    00
  • 解决router.beforeEach()动态加载路由出现死循环问题

    当使用 Vue Router 动态加载路由时,可能会遇到一个循环加载的问题,具体表现为 beforeach 全部被拦截,因此会出现死循环。这个问题的根本原因是路由对象在创建并注册路由前会被复制,因此在路由注册前执行一个 beforeEach 全局钩子,将会陷入死循环。为了解决这个问题,我们可以采用以下方案: 步骤 步骤一 在路由配置文件中为动态路由添加一个命…

    Vue 2023年5月28日
    00
  • vue中jsonp的使用方法

    当前主流的前端框架之一就是Vue.js。在使用Vue.js时,有时我们需要使用JSONP(JSON with Padding)来解决跨域请求的问题。以下是关于Vue中JSONP的使用方法的完整攻略。 什么是JSONP? JSONP是一种跨域的请求方式。它通过动态添加<script>标签来实现跨域请求数据的方法。JSONP的实现过程如下: 在客户端…

    Vue 2023年5月28日
    00
  • Vue3搭建组件库开发环境的示例详解

    为了搭建Vue3组件库开发环境,我们可以按照以下步骤进行: 安装vue-cli并初始化项目 首先我们需要在本地安装vue-cli,使用npm安装即可: npm install -g @vue/cli 安装完成后,我们可以使用下面的命令初始化一个新的vue项目: vue create my-project 安装必要依赖 在项目根目录下执行以下命令安装必要的依赖…

    Vue 2023年5月27日
    00
  • Vue前端判断数据对象是否为空的实例

    当我们在Vue前端开发中需要判断数据对象是否为空时,可以使用以下方法: 使用Object.keys()方法判断 我们可以使用Object.keys()方法获取一个对象中所有的属性,然后再判断属性的数量是否为0来判断对象是否为空。示例代码如下: <template> <div> <button @click="testE…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部