Vuex详解

目录

[十七、 Vuex【重点】](#十七、 Vuex【重点】)

[17.1 什么是Vuex](#17.1 什么是Vuex)

Vuex五大核心要素

[17.2 安装](#17.2 安装)

[17.3 配置 vuex](#17.3 配置 vuex)

[17.4 演示](#17.4 演示)

[17.4.1 存&取](#17.4.1 存&取)

[17.4.2 计算属性使用state[熟悉]](#17.4.2 计算属性使用state[熟悉])

[17.4.3 mapState[熟悉]](#17.4.3 mapState[熟悉])

[17.4.4 修改数据](#17.4.4 修改数据)

[17.5.解决浏览器刷新后 Vuex 数据消失问题](#17.5.解决浏览器刷新后 Vuex 数据消失问题)

[17.6 其他Vuex知识](#17.6 其他Vuex知识)


十七、 Vuex【重点】


17.1 什么是Vuex

Vuex 是什么? | Vuex (vuejs.org)

Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

说人话: 实现多个组件的数据共享,即一个数据需要在多个组件中使用,那么就需要把这个数据存储在VueX中

Vuex五大核心要素

  • state:存放状态,比如需要全局共享的数据

  • getters:可以对state中的数据进行额外处理,类似计算属性的作用

  • mutations:通过提交mutations来改变state的状态

  • actions:异步的mutations,可以通过dispatch调用mutaitons,从而改变state

  • modules:模块化状态管理,每个模块拥有自己的 state、mutation、action、getter

Vue组件通过dispatch调用Vuex中actions的方法,进行异步操作。

actions中的方法中,通过commit,调用mutations中方法,以保证state中数据的同步。

如果不需要异步操作,可以直接在组件通过commit调用mutations中的方法对state中共享的数据进行操作。

17.2 安装

在项目根目录执行如下命令来安装 Vuex

若失败,可使用cnpm

复制代码
# 本例使用的vue2,所以安装vuex装的是vuex3!!! vue3对应的Vuex4
npm install vuex@3

17.3 配置 vuex

在 src 目录下创建一个名为 store 的目录并新建一个名为 index.js 文件用来配置 Vuex,代码如下:

复制代码
import Vue from 'vue'
import Vuex from 'vuex'
​
Vue.use(Vuex)
​
export default new Vuex.Store({
  state: {
  },
  mutations: {
  }
})

修改 main.js 增加刚才配置的 store/index.js,关键代码如下:

复制代码
import Vue from 'vue'
import App from './App.vue'
// 引入路由模块
import router from './router'
// 引入Vuex模块
import store from './store'
​
Vue.config.productionTip = false
// vue2 创建方式
new Vue({
  render: h => h(App),
  router,
  store  // 使用Vuex
}).$mount('#app')
​

17.2 17.3小节中的[安装|配置]也可以不做,因为后续再创建项目时直接选以下依赖,创建好项目直接就配置好了

  • 一个是路由Router,一个是状态管理Vuex

17.4 演示

17.4.1 存&取

  • 在Vuex中设置数据,在任何组件取出
复制代码
// store/index.js文件的state中定义数据
export default new Vuex.Store({
    state: {
        username:"无名",
        count:443,
        tga:"tga"
    },
    mutations: {
    }
})

在任何组件中使用 以下命令取值

复制代码
this.$store.state.username
// username是state中定义的key

17.4.2 计算属性使用state[熟悉]

复制代码
<template>
<div>
  计算属性取值:{{num}}
</div>
</template>
​
<script>
export default {
  name: "TestVueX",
  computed:{  // 【注意: 计算属性的写法】
    num() { 
      return this.$store.state.count
    }
  }
}
</script>

重要用法: state中的数据要放在组件的computed中而不是data中!

为什么?

这是因为data 中的内容只会在 created 钩子触发前初始化一次,具体来说就是data中设置count: this.store.state.count则count的值是created钩子执行前this.store.state.count的值,赋值之后属性的值就是纯粹的字面量,之后this.$store.state.count 如何变化均影响不到count的取值。而 computed 则是通过依赖追踪实现的,计算属性在它的相关依赖发生改变时会重新求值。

简而言之就是说,Vuex存储的数据如果有变化,computed中的数据就会变化,但是data中的不会变化

17.4.3 mapState[熟悉]

当一个组件需要获取多个 状态的时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性

复制代码
<template>
<div>
  计算属性取值:{{count}}|
  计算属性取值:{{tga}}|
  计算属性取值:{{username}}|
</div>
</template>
​
<script>
// 【注意】 是 {} 引入
// 使用 import mapState from 'vuex' 的方式会将整个 vuex 模块导入,并将其中的 mapState 函数赋值给 mapState 变量。
// 而使用 import { mapState } from 'vuex' 的方式则是只导入 vuex 模块中的 mapState 函数
import {mapState} from 'vuex'
export default {
  name: "TestVueX",
  // computed:mapState({
  //   count: function (state) {
  //       return state.count
  //     }
  // }),
​
  // 如果使用和状态名一样的计算属性名,还可以这样写
  // 映射 this.count 为 store.state.count
  // computed: mapState(['count','tga','username']),
​
  // 如果有其他的计算属性,并且需要将vuex的state与其混合使用
  // 可以使用对象展开运算符'...'
      computed: {
    // 使用对象展开运算符将此对象混入到外部对象中
    // 映射为当前组件的计算属性
    ...mapState(['count','tga','username']),
  },
​
}
</script>
​
<style scoped>
​
</style>

17.4.4 修改数据

  • 在任何组件中修改Vuex中的数据
复制代码
// store/index.js文件的mutations中定义方法修改数据
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
    state: {
        username:"无名"
    },
    mutations: {
        // 参数1 是Vuex-state对象
        // 参数2 是其他组件使用时传过来的值,这个参数叫做payload
        updateName(state,v){
            state.username = v  // 修改Vuex中的值
        }
    }
})

在其他组件中通过事件触发函数,在其中使用Vuex的方法修改数据

复制代码
<template>
  <div id="app">
    <!--  演示Vuex取值  -->
    <h1>Vuex --> {{ username }}</h1>
    <input v-model="username">
    <button @click="editName">修改vuex中的值</button>
​
  </div>
</template>
​
<script>
import {mapState} from 'vuex'
export default {
  name: 'App',
  methods: {
    editName(){
      // 修改Vuex数据
      // updateName是 src/store/index.js中mutations中定义的函数名
      this.$store.commit('updateName', this.username)
    }
  },
  data: function () {
    return {
      // 从Vuex中取出数据 , 这里数据是不会根据变化而变化,要使用计算属性取值 
      username1: this.$store.state.username
    }
  },
    // 这里可以追踪到最新的变化
  computed:mapState(['username'])  
}
</script>

17.5.解决浏览器刷新后 Vuex 数据消失问题

  • 问题描述

Vuex 的状态存储是响应式的,当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。但是有一个问题就是:vuex 的存储的数据只是在页面的中,相当于我们定义的全局变量,刷新之后,里边的数据就会恢复到初始化状态。但是这个情况有时候并不是我们所希望的。

  • 解决方案

采用持久化,VueX整合插件实现持久化:vuex-persistedstate

  • 安装插件

    复制代码
        npm install vuex-persistedstate
  • 配置

    在/src/store/index.js中实现配置

    复制代码
    import Vue from 'vue'
    import Vuex from 'vuex'
    // 1引入持久化插件
    import vuexPersistedstate from "vuex-persistedstate";
    ​
    Vue.use(Vuex)
    export default new Vuex.Store({
        state: {
            username:"无名66"
        },
        mutations: {
            updateName(state,v){
                state.username = v
            }
        },
        plugins:[vuexPersistedstate()] // 2加入插件
    })
  • 测试

    浏览器刷新测试效果

17.6 其他Vuex知识

参考官网学习后续Vuex (vuejs.org)

相关推荐
Jiaberrr1 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy1 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白1 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、1 小时前
Web Worker 简单使用
前端
web_learning_3211 小时前
信息收集常用指令
前端·搜索引擎
Ylucius2 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
tabzzz2 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
LvManBa2 小时前
Vue学习记录之六(组件实战及BEM框架了解)
vue.js·学习·rust
滔滔不绝tao2 小时前
自动化测试常用函数
前端·css·html5