Vue学习笔记(四)基于Vue2的学生信息增删查案例 | Vuex组件简介、工作原理 | Vuex的三层结构——store负责响应组件、mutations负责操作数据、state负责存储数据

一、参考资料


视频资料

二、运行环境


  • Windows11
  • Visual Studio Code v2022
  • Node.js v16.5.01
  • Vue/cli v5.0.6
  • Bootstrap 5.1.3

三、Vuex@3插件


注意:这里的Vuex知识是基于Vuex版本3的。

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。对 vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

Vuex插件的GitHub地址:点击查看

适用场景:

  1. 多个Vue组件依赖于同一状态
  2. 来自不同Vue组件的行为需要变更同一状态

3.1 状态管理模式

Vue官方提供的案例:计数

new Vue({
   
  // state 驱动应用的数据源
  data () {
   
    return {
   
      count: 0
    }
  },
  // view 以声明方式将 state 映射到视图
  template: `
    <div>{
    { count }}</div>
  `,
  // actions 响应在 view 上的用户输入导致的状态变化
  methods: {
   
    increment () {
   
      this.count++
    }
  }
})

这个状态自管理应用包含以下三个部分:state、view、actions

以下是一个表示“单向数据流”理念的简单示意:
在这里插入图片描述
当应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏。

Vuex设计思路:

将Vue组件的共享状态抽取出来,以一个全局 单例模式 管理。

在这种模式下,组件树就构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为。

据官方说明, Vuex的设计借鉴了 FluxReduxThe Elm Architecture

Vuex结构图:
在这里插入图片描述
如果拿SpringMVC架构和这张图做对比,那么会发现它们有类似的地方,如下图:

在这里插入图片描述

  • A c t i o n s Actions Actions层负责响应请求,同时执行一些业务逻辑,类似于后端的 C o n t r o l l e r + S e r v i c e Controller+Service Controller+Service ,在 A c t i o n s Actions Actions 层通常会适用 axios 发送请求到后端获取数据,同时可以调用 API 获取数据。
  • M u t a t i o n s Mutations Mutations层负责进行数据的处理,类似于后端的 D A O DAO DAO 层,它会根据 A c t i o n s Actions Actions 层传来的数据对存储在 s t a t e state state层的数据进行增删改查之类的操作。
  • S t a t e State State 层负责存储数据,在Vue中通常用于渲染页面。

因为Vuex插件支持所有组件共享$store这个对象,所以每个组件都可以通过$sotre获取到 s t a t e state state 层里的数据。

而组件可以直接获取数据,另外还可以通过 计算属性 获取到state层的数据,例如:

computed: {
   
  studentList(){
   
    return this.$store.state.student.studentList || []
  },
},

在使用Vuex3 时,我们需要按照其设计的流程来执行,其中 M u t a t i o n s Mutations Mutations层是必须要经过的,因为Devtools调试工具会监听这一层的变化而不会监听Actions的变化。

除此之外,适用Vuex3的调用流程通常有两种:

  • a c t i o n s − > m u t a t i o n s − > s t a t e actions -> mutations -> state actions>mutations>state
  • m u t a t i o n s − > s t a t e mutations -> state mutations>state

我们可以忽略actions,这个就和后端的Controller和Service不同了,区别在于前端的actions层主要是负责请求获取数据的,如果无需请求数据,比如:根据当前state里的数据进行筛选查询,此时就不需要请求获取数据,那么Vuex支持直接执行mutations层的代码,直接处理state的数据即可。

3.2 Vuex 核心概念和API

3.2.1 state

概念与特点:

  1. vuex 管理的状态对象
  2. 唯一,不可重复

例如:

state: {
   
        // 若有本地缓存就读缓存,否则设置为空
        studentList: JSON.parse(localStorage.getItem('studentList')) || []
}

3.2.3 actions

注: Action是Vuex运行原理图中Vue组件使用Vuex的入口,Mutation也可以是入口。

概念与特点:

  1. 值为一个对象,包含多个响应用户动作的回调函数
  2. 通过 commit() 来触发 mutation 中函数的调用, 间接更新 state
  3. action 提交的是 mutation,而不是直接变更状态。
  4. action 可以包含任意异步操作。支持AJAX、定时器等异步操作。

重点:触发 actions 中的回调函数

在组件中使用:$store.dispatch('对应的 action 回调名') 触发,例如(查询学生信息):

// search.js
actions: {
   
    searchStuById(context, info){
   
    // 业务逻辑比较简单,这里可以发送axios请求获取数据
        context.commit('getStuById',info)
    },
    ...
}
// Search.Vue
this.$store.dispatch('search/searchStuById', [this.searchInfo, this.allStudent])

注意:actions中的回调函数第一个参数默认为应用上下文对象,第二个参数才是通过dispatch传递的值,应用上下文对象内容如下:
在这里插入图片描述
这表示我们可以通过这个应用上下文对象继续 dispatch 分发,也可以commit提交到mutation等。

3.2.4 mutations

概念与特点:

  1. 值是一个对象,包含多个直接更新 state 的方法
  2. 每个 mutation 都有一个字符串事件类型 (type) 和 一个 回调函数 (handler)
  3. 有两种调用方式:1)在 action 中(由第一个参数)使用:commit(‘对应的 mutations 方法名’) 触发
  4. mutations 中方法的特点:1) 不能写异步代码;2) 只能单纯的操作 state

例如(根据ID查询学生信息):

 mutations: {
   
     // 根据ID查询学生
     getStuById(state, info){
   
         let id = info[0]
         let studentList = info[1]
         state.searchStudentList = studentList.filter((stu) =>  stu.id === id)
     },
     ...
}

这里提一句,在mutation修改完数据后,state里的数据就发生改变了,那么页面里的数据是如何受到影响的呢?

因为Vuex支持所有组件共享同一个 $store ,所以最简单的做法就是可以写一个计算属性,去获取 $store 里state层的数据。例如:

computed: {
   
  searchStudentList(){
   
    return this.$store.state.search.searchStudentList || []
  },
  ...
}

前端页面渲染只需要遍历计算属性的名称即可:

<ul>
  <li v-for="(stu) in searchStudentList" :key="stu.id">
    {
  {stu.id}}, {
  {stu.name}}
  </li>
</ul>

3.2.5 getters

概念与特点:

  1. 值为一个对象,包含多个用于返回数据的函数
  2. 调用方式 —— $store.getters.xxx
  3. 可以认为是 store 的计算属性
  4. 类似于计算属性,getter 的返回值会根据其依赖被 缓存 起来,且只有当其依赖值 发生了改变 才会被重新计算。
  5. 跟之前的state、action和mutation一样,可以在任意组件中访问,例如:
// student.js
getters: {
   
	studentCount (state){
   
		return state.studentList.lenth
	}
}
// Student.vue
computed: {
   
  studentCount () {
   
    return this.$store.getters.studentCount 
  }
}

3.3 Vuex 模块化开发

modules

概念与特点:

  1. Vuex支持在modules里设置多个 module
  2. 一个 module 是一个 store 的配置对象
  3. 与每个组件(包含有共享数据)对应

如下图所示,Vuex通常可以分为不同的模块,比如这里比较简单的分为了学生模块和查询模块。

在这里插入图片描述
index.js

// 该文件用于创建 VueX 中最为核心的 Store
// 引入 Vue
import Vue from 'vue'
// 安装vuex@3 npm i vuex@3
import Vuex from 'vuex'
import search from './search'
import student from './student'
Vue.use(Vuex)

// 创建 Store并导出
export default new Vuex.Store({
   
    modules: {
   search, student}
})

search.js

export default {
   
    namespaced: true,
    // Actions —— 用于响应组件中的动作
    actions: {
    ... },
    // Mutations —— 用于操作数据(state)
    mutations: {
    ... },
    
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为你提供一个简单的示例代码,用于展示如何使用Vue组件化、Vue路由、Vuex和Axios来实现增删改查功能。 首先,我们需要安装VueVue Router、Vuex和Axios,你可以使用npm或yarn来安装它们。 接下来,我们创建一个Vue组件,用于显示数据列表和执行增删改查操作。在这个组件中,我们将使用Vuex来管理数据状态和执行异步操作,使用Axios来进行HTTP请求。 ```html <template> <div> <h1>Todo List</h1> <form @submit.prevent="addTodo"> <input v-model="newTodo" placeholder="Add new todo" /> <button type="submit">Add</button> </form> <ul> <li v-for="(todo, index) in todos" :key="todo.id"> <input type="checkbox" :checked="todo.completed" @change="toggleTodo(todo)" /> <span>{{ todo.text }}</span> <button @click="removeTodo(index)">Remove</button> </li> </ul> </div> </template> <script> import { mapGetters, mapActions } from 'vuex'; export default { computed: { ...mapGetters(['todos']), }, methods: { ...mapActions(['addTodo', 'removeTodo', 'toggleTodo']), }, data() { return { newTodo: '', }; }, }; </script> ``` 接下来,我们使用Vue Router来创建路由和路由组件,用于在不同的URL路径下显示不同的组件。在这个例子中,我们将创建一个路由,用于显示TodoList组件。 ```javascript import Vue from 'vue'; import VueRouter from 'vue-router'; import TodoList from './components/TodoList.vue'; Vue.use(VueRouter); const routes = [ { path: '/', component: TodoList, }, ]; const router = new VueRouter({ mode: 'history', routes, }); export default router; ``` 最后,我们使用Vuex来管理TodoList组件的状态和操作。我们将创建一个store对象,包含statemutations、actions和getters。 ```javascript import Vue from 'vue'; import Vuex from 'vuex'; import axios from 'axios'; Vue.use(Vuex); const store = new Vuex.Store({ state: { todos: [], }, mutations: { SET_TODOS(state, todos) { state.todos = todos; }, ADD_TODO(state, todo) { state.todos.push(todo); }, REMOVE_TODO(state, index) { state.todos.splice(index, 1); }, TOGGLE_TODO(state, todo) { todo.completed = !todo.completed; }, }, actions: { async fetchTodos({ commit }) { const response = await axios.get('/api/todos'); commit('SET_TODOS', response.data); }, async addTodo({ commit }, text) { const response = await axios.post('/api/todos', { text, completed: false }); commit('ADD_TODO', response.data); }, async removeTodo({ commit }, index) { await axios.delete(`/api/todos/${state.todos[index].id}`); commit('REMOVE_TODO', index); }, async toggleTodo({ commit }, todo) { await axios.patch(`/api/todos/${todo.id}`, { completed: !todo.completed }); commit('TOGGLE_TODO', todo); }, }, getters: { todos: state => state.todos, }, }); export default store; ``` 现在我们已经完成了使用Vue组件化、Vue路由、Vuex和Axios实现增删改查功能的示例代码。当然,这只是一个简单的示例,你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值