Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 2(Vuex)

Vuex 状态管理

  Vuex 是一种集中管理所有组件中数据的机制。它和Pinia一样都是解决使用 props 和 $emit 事件在组件之间传递数据时,当组件之间频繁传递,层级增加时管理数据就变得困难。Vue 的官方状态管理库已更改为Pinia,Pinia 具有与 Vue 几乎完全相同它还增强的很多API的功能。Vuex 虽然仍在维护中,但是它不会在添加的新功能了,Vuex 应用程序迁移到 Pinia它可能会是一个更好的选择。在这里我们还会讲解一下Vuex 的使用方法,以方便大家在迁移Vuex的时候更加方便。Vuex官网https://vuex.vuejs.org/

创建项目后,进入项目文件夹,执行npm install命令安装vuex

第一章 Vue3项目创建 1 Vue CLI 创建vue项目
第一章 Vue3项目创建 2 使用 Webpack 5 搭建 vue项目
第一章 Vue3项目创建 3 Vite 创建 vue项目
第二章 Vue3 基础语法指令
第三章 Vue Router路由器的使用
第四章 VUE常用 UI 库 1 ( element-plus,Ant ,naiveui,ArcoDesign)
第四章 VUE常用 UI 库 2 ( ailwind 后台框架)
第五章 Vue 组件应用 1( Props )
第五章 Vue 组件应用 2 ( Emit )
第五章 Vue 组件应用 3( Slots )
第五章 Vue 组件应用 4 ( provide 和 inject )
第五章 Vue 组件应用 5 (Vue 插件)
第六章 Pinia,Vuex与axios,VueUse 1(Pinia)
第六章 Pinia,Vuex与axios,VueUse 2(Vuex)
第六章 Pinia,Vuex与axios,VueUse 3(VueUse)
第六章 Pinia,Vuex与axios,VueUse 4(axios)

npm install vuex@next --save

安装完vuex后,可以通过查看package.json来查看安装的vuex版本。

  "dependencies": {
    "pinia": "^2.0.28",
    "vue": "^3.2.45",
    "vuex": "^4.0.2"
  },

在创建main.js中创建一个vuex对象作为全局的数据管理器,将这个vuex对象app.use到Vue项目中。

import { createApp } from 'vue'
import App from './App.vue'
import { createStore } from "vuex";
//vuex中的数据保存环境
const store = createStore({
    state: {
        message: '我是你第条Vuex数据'
    },
    mutations: {
    },
    actions: {
    },
    modules: {
    }
});
const app = createApp(App)
app.use(store)
app.mount('#app')

Vuex中的这三个属性state,Getters,Actions在Pinia中都有了解过,Mutations,Modules在后边会有所介绍。

1Vuex 使用

  我们在App.vue中模板中使用** s t o r e . s t a t e . m e s s a g e ∗ ∗ 可以获得 V u e x 中保存的共享数据 m e s s a g e 值。项目中所有的其他组件都可以使用 store.state.message **可以获得Vuex中保存的共享数据message值。项目中所有的其他组件都可以使用 store.state.message可以获得Vuex中保存的共享数据message值。项目中所有的其他组件都可以使用store共享数据中的值。

<script setup>
import VuexIndex from "./components/VuexIndex.vue"
script>
<template>
   <div id="app">
    <h1>学习与使用Vuex h1>
    <h4>{{ $store.state.message }}h4>
   div>
   <VuexIndex>VuexIndex>
template>

在components文件夹中创建一个VuexIndex.vue组件,在组件中使用useStore 解构方法获得Vuex中的数据内容。

<script setup>
 import { useStore } from 'vuex';
 const store = useStore();
script>
<template>
    <h1>VuexIndex子组件h1>
{{store}}
template>

  在浏览器上显示学习与“使用Vuex 的内容”和store对象中的内容,说明我们保存在Vuex中的共享数据生效了。

Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 2(Vuex)_第1张图片

Vuex 共享和管理数据,因此可以从任何组件以相同的方式访问它

方法与对象 说明 使用方法
createStore 创建数据共享器 import { createStore } from “vuex”
useStore 获得数据共享器 import { useStore } from ‘vuex’
$store 模板中获得数据共享对象 $store.state.属性

2 Vuex 基础属性

Vuex 中主要是操作States,Actions、Mutations和getters属性的。

Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 2(Vuex)_第2张图片

  在项目中的store文件夹中下创建vuexIndex.js文件,我们将main.js文件中创建createStore部分的代码移植到vuexIndex.js文件中,在vuexIndex.js文件中来实现store数据共享器的功能。

import { createStore } from "vuex";
//vuex中的数据环境
export const store = createStore({
    state: {
        message: '我是你第一个Vuex数据'
    },
    mutations: {
    },
    actions: {
    },
    modules: {
    }
});

  修改main.js中的代码使用引入的方法引入store对象,使用vue组件use方法加入store数据共享器到整个项目环境中。

import { createApp } from 'vue'
import App from './App.vue'
import {store} from './stores/vuexIndex'
const app = createApp(App)
app.use(store)
app.mount('#app')

1 state值设置

  现在让我们使用 Vuex来 装入一个用户列表集合,在 store\vuexIndex.js 文件中store对象中的state加入用户列表信息。

import { createStore } from "vuex";
//vuex中的数据环境
export const store = createStore({
    state: {
        message: '我是你第一个Vuex数据',
        users:[
            {name: 'zhtbs', dept:'部门一', post:"经理",id:1},
            {name: 'kimy', dept: '部门一',post:"工人",id:2},
            {name: 'linda', dept: '部门二',post:"工人",id:3}
          ]
    }
});

  在子组件中VuexIndex.vue中使用store.state属性将它内面的users集合绑定都模板中v-for指令,将用户内容循环遍历出来。

<script setup>
 import { useStore } from 'vuex';
 const store = useStore();
script>
<template>
    <h1>VuexIndex子组件h1>
 <ul>
 <li v-for="user in store.state.users">
     名称:{{ user.name }} 
     部门:{{ user.dept }} 
     职务:{{ user.post }}
  li>
  ul>
template>

2 getters设置

import { createStore } from "vuex";
//vuex中的数据环境
export const store = createStore({
    ......
    getters: {
        //统计
        Countusers : function(state){
            return state.users.length;
        }
    }
});
<script setup>
 import { useStore } from 'vuex';
 const store = useStore();
  // 获得用户列表数量
 let count=store.getters.Countusers;
script>
<template>
    <h1>VuexIndex子组件h1>
 <ul>
  	<li v-for="user in store.state.users">
        名称:{{ user.name }} 
        部门:{{ user.dept }} 
        职务:{{ user.post }}
    li>
  ul>
  <h3>列表数量:{{count}}h3>
template>

  它只能在被描述为计算属性的组件中使用。如果你想在其他组件中做同样的处理,你需要为每个组件编写相同的代码。但是,如果您使用 Getters,它们将存储在 Vuex 存储中,因此您可以以相同的方式从其他组件使用它们。

3 mutations动作

​ Vuex 中的mutations属性中是定义修改state 值的方法。在Vue 组件中引入store对象,通过执行store对象中mutations方法来修改store对象中state的值。

mutations 方法默认第一参数是state

mutations: {
increment : function(state) {
}
}

  修改vuexIndex.js代码在store对象中的mutations属性下创建方法increment,在这个方法中使用方法参数state,这个参数state就是整个store中的state,将state中count值进行累加。

import { createStore } from "vuex";
//vuex中的数据环境
export const store = createStore({
    state: {
        count: 0,
    },
    //更新动作
    mutations: {
        increment : function(state) {
          state.count++
        }
      },
      actions: {
      }
});

  Vuex 存储状态的改变方法是定义在mutations属性中动作,在组件中useStore对象使用commit函数触发mutations动作事件。大家都能理解state中的数据更新都是通过mutations属性中的动作来完成的。
  在App.vue中代码中按钮中绑定increment事件,在increment事件中使用commit方法执行store中的increment方法,increment方法功能是store对象state值count累计加1。

<script setup>
import VuexIndex from './components/VuexIndex.vue'
import { useStore } from 'vuex';
 const store = useStore();
const increment=()=>{
   store.commit('increment')
}
script>
<template>
 <h1>学习与使用Vuex h1>
 <button v-on:click="increment">count  累计+1button>
 <h1>Count:{{ this.$store.state.count }}h1>
template>

在浏览中看到的结果是。

在这里插入图片描述

4 Actions 更新

​  Vuex 也提供别外一种用于更新状态值的函数 Actions。Actions与 mutations 功能一样都是用于更新状态state中的值,但有这两个属性也是有所区别的。

  1. Actions是通过mutations 来更新state中的值, 而不是自己直接改变state中状态。
  2. Actions操作可以包括异步处理功能。

  在VuexIndex.js文件中创建actions属性,在actions属性中写入actionszht方法,在actionszht方法完成执行计算器累加功能。
  actionszht方法中会传入一个context参数,context参数是Store对象中的全局环境,使用这个context全局环境的commit方法将mutations属性中的increment方法加入进来。
actionszht方法就可以使用mutations中的increment方法进行计数器累加功能了。

import { createStore } from "vuex";
//vuex中的数据环境
export const store = createStore({
    state: {
        count: 0,
    }, 
    mutations: {
        increment : function(state) {
          state.count++
        }
      },
      actions: {
        actionszht: function(context){
            context.commit('increment')
        }
      }
});

  让我们在 App.vue 中加入这个的 actionszht 方法,进行计数器累加工作。Commit 用于执行 mutation,而 dispatch 方法用于执行 action。

<script setup>
import { useStore } from 'vuex';
const store = useStore();
const increment=()=>{
   store.dispatch('actionszht')
}
script>
<template>
  <button v-on:click="increment">count增加1button>
  <h1>Count:{{ this.$store.state.count }}h1>
template>

除了 state 和 commit 之外,context 还可以使用 dispatch 和 getters 方法。

Actions异步处理

  异步处理常用于使用axios从服务器获取数据等情况。如果使用setTimeout函数获取图像进行异步处理,处理过程如下。3 秒后,突变增量被执行,计数增加 1。

actions: {
	incrementOne: function(context){
	    setTimeout(() => {
	      context.commit('increment')
	    }, 3000)
	}
}

  通过到目前为止的解释,我们已经解释了下图中所有的Actions、Mutations和States。如果你能看懂下图,我想你差不多能理解 Vuex 的概念了。

  为了检查您的理解,让我们根据文档中经常出现的计数示例,按照下图中的流程进行操作。

##3 Vuex 模块化

  至此,Vuex 中存储的状态、突变、动作和 getter 都存储在 store\index.js 文件中。如果你的应用很小,你可以只用 index.js 文件来管理 Vuex 状态,但是随着应用的增长,代码量会越来越大,变得难以管理。
  Vuex 允许模块化。模块化允许您根据文件的功能分离文件。例如,如果您的应用程序具有用户身份验证功能,请创建一个名为 user.js 的单独文件。为每个函数分离文件使代码管理更容易。

在 store 文件夹下创建一个 modules 文件夹,并创建一个 user.js 文件。

export const user = {
  namespaced: true,
  state: {
    user: null,
  },
  mutations: {
    setUser(state, payload) {
      state.user = payload;
    },
  },
  actions: {
    login({ commit }) {
    //登录业务
    },
    goout({ commit }) {
    //退出业务
    },
  },
  getters:{
  },
};

创建的用户模块可以在 store\index.js 文件中设置,如下所示。

import { createStore } from "vuex";
import user from "./user";
//vuex中的数据环境
export const store = createStore({
  modules: {
    //导入模板到主模块中
    user,
  },
    state: {
    },
    getters: {
    },
    mutations: {
    },
    actions: {
    }
});

访问时为$store.state.user.user。此外,如果您想通过调度执行登录处理,它将是 dispatch(‘user/login’)。由于设置了 namespaced: true ,它变成了 user/login 而不是 login,并且可以使用命名空间设置操作。如果未设置 namespaced,它将是 dispatch(‘login’)。

你可能感兴趣的:(vue,vue.js,前端,javascript)