目录
[十七、 Vuex【重点】](#十七、 Vuex【重点】)
[17.1 什么是Vuex](#17.1 什么是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 是一个专为 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)