详解Vue中状态管理Vuex

yizhihongxing

详解Vue中状态管理Vuex

在Vue的大型应用中,数据状态的管理变得异常重要。Vuex是Vue中一个集中式的状态管理器,可以帮助我们方便地管理不同组件之间共享的数据。

Vuex核心概念

State

Vuex使用单一状态树,即用一个对象来包含全部应用层级的状态。所有组件的状态存储在一个对象中,这个对象我们称之为state。Vuex的state是响应式的,当state中的数据发生改变时,对应的组件会自动重新渲染。

// 定义一个state
const state = {
  count: 0
}

Mutations

进行状态的改变可以使用mutations。每个mutation都有一个字符串的事件类型和一个回调函数。我们需要改变store的状态,唯一的方法就是明确地提交mutation。

// 定义一个mutation
const mutations = {
  increment(state) {
    state.count++
  }
}

Actions

Actions类似于Mutations,不同之处在于Actions提交mutation而不是直接变更状态。Actions可以包含任意异步操作。

// 定义一个action
const actions = {
  increment(context) {  // context是一个对象,包含state、commit、dispatch等属性
    context.commit('increment')
  }
}

Getters

Vuex的getters用于从store中的state中派生出一些状态,例如我们需要对state中的数据进行一些操作再返回。Getters接受state作为其第一个参数。

// 定义一个getter
const getters = {
  doubleCount(state) {
    return state.count * 2
  }
}

使用Vuex

安装Vuex:

npm install vuex --save

在main.js中引入Vuex并注册:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

创建Vuex实例:

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++
    }
  },
  actions: {
    increment(context) {
      context.commit('increment')
    }
  },
  getters: {
    doubleCount(state) {
      return state.count * 2
    }
  }
})

在组件中使用Vuex:

<template>
  <div>
    <p>{{count}}</p>
    <button @click="increment">Increment</button>
    <p>{{doubleCount}}</p>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count
    },
    doubleCount() {
      return this.$store.getters.doubleCount
    }
  },
  methods: {
    increment() {
      this.$store.dispatch('increment')
    }
  }
}
</script>

我们可以看到,在组件中使用不同的方式来获取state、commit mutation、dispatch action和获取getter。

示例1

现在我们有一个需要展示的列表数据,可以进行筛选、排序和分页等操作。我们使用Vuex来存储和管理这个数据列表,同时处理筛选、排序和分页等状态。

我们的state需要包含:

  • 列表数据
  • 当前页码
  • 每页展示数量
  • 筛选条件
  • 排序方式

我们定义一个mutations,用来改变列表数据:

const mutations = {
  setList(state, list) {
    state.list = list
  }
}

我们定义一个actions,获取列表数据并提交mutation:

const actions = {
  getList(context) {
    // 这里是异步操作获取数据
    const list = [...]
    context.commit('setList', list)
  }
}

我们定义一些getters,用于获取当前页数据、当前页总数、筛选后的数据等:

const getters = {
  currentPageData(state) {
    const begin = (state.currentPage - 1) * state.pageSize
    const end = begin + state.pageSize - 1
    return state.list.slice(begin, end + 1)
  },
  currentPageTotal(state, getters) {
    return Math.ceil(getters.filteredList.length / state.pageSize)
  },
  filteredList(state) {
    let list = [...state.list]
    if (state.filter) {
      list = list.filter(item => item.name === state.filter)
    }
    if (state.sort) {
      const sortBy = state.sort.split('_')[0]
      const sortDir = state.sort.split('_')[1]
      list = list.sort((a, b) => {
        if (sortDir === 'asc') {
          return a[sortBy] - b[sortBy]
        } else {
          return b[sortBy] - a[sortBy]
        }
      })
    }
    return list
  }
}

在组件中使用Vuex:

<template>
  <div>
    <table>
      <thead>
        <tr>
          <th>
            <button @click="sort('id')">ID</button>
          </th>
          <th>
            <button @click="sort('name')">Name</button>
          </th>
          <th>
            <button @click="sort('age')">Age</button>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in list" :key="item.id">
          <td>{{item.id}}</td>
          <td>{{item.name}}</td>
          <td>{{item.age}}</td>
        </tr>
      </tbody>
    </table>
    <div>
      <button :disabled="currentPage === 1" @click="setCurrentPage(currentPage - 1)">Prev</button>
      <button v-for="page in currentPageTotal" :key="page" :class="{ active: page === currentPage }" @click="setCurrentPage(page)">{{page}}</button>
      <button :disabled="currentPage === currentPageTotal" @click="setCurrentPage(currentPage + 1)">Next</button>
    </div>
  </div>
</template>

<script>
export default {
  computed: {
    list() {
      return this.$store.getters.currentPageData
    },
    currentPage() {
      return this.$store.state.currentPage
    },
    currentPageTotal() {
      return this.$store.getters.currentPageTotal
    }
  },
  methods: {
    getList() {
      this.$store.dispatch('getList')
    },
    setCurrentPage(page) {
      this.$store.state.currentPage = page
    },
    sort(sortBy) {
      if (this.$store.state.sort === sortBy + '_asc') {
        this.$store.state.sort = sortBy + '_desc'
      } else {
        this.$store.state.sort = sortBy + '_asc'
      }
    }
  },
  created() {
    this.getList()
  }
}
</script>

示例2

现在我们有一个需要在线编辑的用户信息表单,表单中包含了用户名、性别和年龄等信息。我们使用Vuex来存储和管理这个表单数据。

我们的state需要包含:

  • 用户名
  • 性别
  • 年龄

我们定义一个mutations,用来改变表单数据:

const mutations = {
  setUsername(state, username) {
    state.username = username
  },
  setGender(state, gender) {
    state.gender = gender
  },
  setAge(state, age) {
    state.age = age
  }
}

我们定义一些getters,用于获取表单数据:

const getters = {
  formData(state) {
    return {
      username: state.username,
      gender: state.gender,
      age: state.age
    }
  }
}

在组件中使用Vuex:

<template>
  <div>
    <input type="text" v-model="username">
    <input type="radio" name="gender" value="M" v-model="gender"> Male
    <input type="radio" name="gender" value="F" v-model="gender"> Female
    <input type="number" v-model="age">
  </div>
</template>

<script>
export default {
  computed: {
    username: {
      get() {
        return this.$store.state.username
      },
      set(newValue) {
        this.$store.commit('setUsername', newValue)
      }
    },
    gender: {
      get() {
        return this.$store.state.gender
      },
      set(newValue) {
        this.$store.commit('setGender', newValue)
      }
    },
    age: {
      get() {
        return this.$store.state.age
      },
      set(newValue) {
        this.$store.commit('setAge', newValue)
      }
    },
    formData() {
      return this.$store.getters.formData
    }
  }
}
</script>

我们可以看到,在组件中使用了computed属性来获取state和提交mutation。

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

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

相关文章

  • Vue使用video标签实现视频播放

    下面我将详细讲解“Vue使用video标签实现视频播放”的完整攻略。 概述 想要在 Vue 中使用 video 标签实现视频播放,需要用到 Vue 的指令和事件等相关知识,以下是实现过程的具体步骤。 步骤 1. 安装和引入 video.js video.js 是一个现代化的视频播放器,它可以帮助我们轻松地实现视频播放功能。我们需要安装它并在 Vue 中引入:…

    Vue 2023年5月28日
    00
  • Vue自定义指令封装节流函数的方法示例

    下面就给您详细讲解一下Vue自定义指令封装节流函数的方法。 简介 在Vue中,自定义指令可以让我们以指令的形式扩展Vue的功能。而节流函数则可以控制高频触发的事件在一定时间内只执行最后一次,避免过度频繁的操作,从而提升性能。在Vue中,我们封装一个自定义指令来使用节流函数可以很方便地实现这一功能。 自定义指令 为了实现自定义指令,我们需要使用Vue的dire…

    Vue 2023年5月28日
    00
  • vue插件vue-resource的使用笔记(小结)

    vue插件vue-resource的使用笔记 什么是vue-resource vue-resource是一个Vue.js的插件,它为我们提供了一个服务,用于在Vue.js应用程序中轻松地处理Web API请求和响应。它和jQuery的Ajax非常类似,不过它更适合Vue.js。 安装 npm install vue-resource –save 使用 在V…

    Vue 2023年5月28日
    00
  • vue项目打包发布上线的方法步骤

    以下是“Vue项目打包发布上线的方法步骤”的完整攻略,包括示例说明。 环境准备 需要Node.js环境、Vue CLI脚手架工具以及nginx服务器等。 在本地电脑上安装Vue CLI脚手架工具:npm install -g @vue/cli 创建Vue项目:vue create <project-name> 打包 进入项目所在目录:cd &lt…

    Vue 2023年5月28日
    00
  • vue+element-ui JYAdmin后台管理系统模板解析

    下面我将为您详细讲解“vue+element-ui JYAdmin后台管理系统模板解析”的完整攻略。 什么是JYAdmin后台管理系统模板? JYAdmin是一款基于Vue.js和Element UI的开源后台模板,提供标准的后台管理系统开发框架,使开发者能够快速搭建出一套完整的后台管理系统。 该模板提供了多个功能模块,如登录、用户管理、数据管理等,丰富的U…

    Vue 2023年5月28日
    00
  • jsp提交到Servlet报404错误问题解决(webroot下子目录)

    问题描述: 当我们在网站中使用JSP表单提交数据到Servlet时,如果Servlet所在的位置是在webroot下的子目录中,可能会出现404错误,无法正常访问Servlet的情况。这是因为JSP默认使用相对路径来访问Servlet,在webroot下的子目录中,相对路径并不能正确地指向Servlet。 解决方案: 我们可以通过以下两个步骤来解决这个问题:…

    Vue 2023年5月28日
    00
  • vue 实现模糊检索并根据其他字符的首字母顺序排列

    实现模糊检索并根据其他字符的首字母顺序排列是前端开发中比较常见的需求之一,在 Vue 中也有很好的实现方式。 1.实现模糊检索功能 实现模糊检索的核心点是在数据源上进行筛选。假设我们有一个表格数据源: [ { name: ‘张三’, age: 21 }, { name: ‘李四’, age: 22 }, { name: ‘王五’, age: 23 }, { …

    Vue 2023年5月27日
    00
  • Vue 搭建Vuex环境详解

    Vue 搭建Vuex环境详解 简介 Vuex是Vue.js的官方状态管理库,它可以更好的管理Vue.js应用中的数据流,包括数据的状态、存储和同步。社区中已经有很多文章介绍Vuex的基础使用,本文将详细讲解如何在Vue.js中搭建Vuex环境,并提供两个示例说明。 搭建Vuex环境 安装Vuex 在Vue.js项目中使用Vuex,需要先安装它。 npm in…

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