VueX快速上手
VueX 是Vue的数据管理框架
背景:在传统的数据传递过程中,父子组件通过属性或者事件传值,多层组件通过provide/inject传值。但是存在一种需求,就是页面级别的数据传递。
基础用法
数据定义:
vueX 创建了一个全局唯一的仓库,用来存放全局的数据,
数据在state中定义
数据调用:this.$store.state.xx
数据修改:
不可以直接修改全局数据
具体流程:
- 在组件上绑定一个事件函数,在该事件函数中调用 this.$store.state.dispatch('actionName')方法 "发送急件",派发一个action
- 在store仓库的actions中,为该action 定义一个commit(提交),去触发一个mutation(突变)
点击查看代码
//store
actions : {
actionName(){
this.commit('mutationName')
}
}
- 在store仓库的mutations中,定义具体的数据改变操作。
点击查看代码
//store
mutations : {
mutationName(){
//this.state.xx = xx
}
}
例子
在about页面中,展示 vuex中定义的数据hello。并为其所在的元素绑定事件以改变hello的值。
点击查看代码
//about.vue
<template>
<div class="about">
<h1>This is an about page</h1>
//1.调用vuex中定义的全局数据 hello,并绑定事件改变其值
<h1 @click="handleClick">{{this.$store.state.hello}}</h1>
</div>
</template>
<script>
export default {
methods :{
handleClick(){
//2.调用dispatch方法,给store发送改变数据的请求
this.$store.dispatch('change')
}
}
}
</script>
在store中,定义actions 和 mutations函数
点击查看代码
import { createStore } from 'vuex'
export default createStore({
state: {
//0.定义全局
hello:'hello'
},
mutations: {
//为该mutation函数写具体的数据改变操作,不限于改变数据
changeHello(){
this.state.hello = 'hi'
console.log('hi')
}
},
actions: {
//3.为dispatch的action写一个commit,去触发具体的mutation函数
change(){
this.commit('changeHello')
}
},
modules: {
}
})
传参
如果在组件中想要给vuex传递参数。
语法:
- 写在dispatch中
- this.$store.dispatch('actionName', params)
- actions中接收参数,并传给mutations
- actionName(state, params){
- 注意 第一个参数是state, 第二个参数才是被传递的参数
- this.commit('mutationName', params)
- }
- 在mutations中接收参数
- mutationName(store, params){
- 注意 第一个参数是store,第二个参数才是被传递的参数
- this.state.xx = params
- }
在composition API中使用VueX
setup函数中 无法直接使用this.$store,因为this是undefined
- 需要从vuex中引入 useStore方法
- import { useStore } from 'vuex'
- 在setup函数中,将useStore()存为 store常量
点击查看代码
//组件
//template中展示hello
//先引入useStore方法
import { useStore } from 'vuex'
import { toRefs } from 'vue'
export default {
//在composition API中使用vuex
setup(){
//使用store替换传统方法中的 this.$store
const store = useStore()
//技巧:使用toRefs将store.state中的数据解构
let {hello} = toRefs(store.state)
const handleClick = () => {
store.dispatch('change')
}
return {hello, handleClick}
}
}
点击查看代码
//VueX store
import { createStore } from 'vuex'
export default createStore({
state: {
hello:'hello'
},
mutations: {
changeHello(){
this.state.hello = 'hi'
}
},
actions: {
change(){
this.commit('changeHello')
}
},
modules: {
}
})
注意
- 修改数据如果跳过dispatch步骤,甚至commit步骤,也能直接修改数据,但是不推荐这样的写法。
- vuex中约定,在mutations中只写“同步代码”,不写异步代码(但是写了不会报错)。
- 约定 异步代码在actions中写
- 在F5刷新页面后,vuex会重新更新state,所以,存储的数据会丢失。
可以通过 vuex-persistedstate 解决
思考
- 为什么在vuex中要将 actions 和 mutations分开来写?
因为vuex约定,在数据同步修改的代码封装在mutations中,将数据异步修改的代码封装在actions中。 - 尝试在组件的setup函数中,调用 this.$store.dispatch(),但是失败。
- 错误原因是这里的 this.$store 是undefined
- this.$store 是undefined原因是setup函数是在created生命周期前执行的,此时this就是空的。
- 那么就不能在setup函数中,调用vuex中定义的数据了吗?
可以 只需从VueX中引入 useStore()