文章目录
前言
组件之间共享数据由许多种方式
父传子:v-bind属性绑定
子传父:v-on事件绑定
双向绑定:v-model事件绑定
兄弟组件之间共享数据:EventBus
vue2:
- $on 接收数据的组件
- $emit发送数据的组件
子组件从父组件获取的值是只读的,不能直接修改
一、VueX概述
描述:实现组件全局状态管理的一种机制(方案),可以方便组件之间的数据共享
左图表示不使用Vuex实现数据共享
右图为使用Vuex实现数据共享
由上图可知:
- 若不使用Vuex的话要实现不想关的两个组件数据传递是非常繁琐的
- 在未使用Vuex实现数据共享的时候,需要许多层组件进行数据传递,这就会影响到许多的组件,造成空间浪费
- 若使用了Vuex想要获取某个组件的数据的话,可以让那个组件直接传值给store,然后再从store从获取值
1.Vuex的优点
- 能够再vuex中集中管理共享的数据,易于开发和后期维护
- 能够高效的实现组件之间的数据共享,提高开发效率
- 存储再Vuex中的数据都是响应式的,能实时保持数据和页面的同步
2.适合存储到Vuex的数据
- 对于组件之间共享的数据,才有必要存储到vuex中
- 对于组件当中的私有数据,依旧再组件自身的data中即可
二、Vuex核心概念
主要核心概念有:State,Getter,Mutation,Action
1.State
描述:state提供唯一的公共数据源,所有的共享数据都要统一放到Store的State中进行存储
1.1 创建state
import {createStore} from 'vuex'// new store
export default createStore({
state:{
// 存储数据 数据是响应式的
age:23,
},
})
1.2 State的使用
<template>
<view>This index</view>
<view>{{age}}</view>
</template>
<script setup>
import {useStore} from 'vuex'
const store = useStore()
const age = store.state.age
</script>
2.Getter
描述:相当于计算属性(当我们在多个组件中需要用到某个属性或方法时,我们可以将其注册到这个位置)
PS:从 Vue 3.0 开始,getter 没有了缓存机制,官方说预计在3.2解决(我觉得3.2可能出不来了…去了解一下pinia,vuex的github上说已经迁移到pinia了)
2.1 创建Getter
接受 state 作为第一个参数,同时也可以接收其他的getter当作第二个参数:
getters: {
// 类似于计算属性,当项目有多个地方需要复用某个算法时,可以将其封装在此
// 目前没有缓存机制,预计会在3.2解决
changeAge(state,getters){
console.log('触发')
return getters.oldAge
},
oldAge(state){
return state.age+=5
}
},
2.2 注册及使用Getter
Getter 会暴露为 store.getters 对象,你可以以属性的形式访问这些值:
store.getters.changeAge
3.Mutation
描述:Mutation主要用于变更Store中的数据
注意事项:
- 只能通过mutation变更Store数据,不可直接操作Store中的数据
- 这种操作方式虽然相对繁琐,但是可以集中监控所有数据的变化
- 不能再mutation中执行异步操作。原因:
moutation中异步请求完成后不能更新State,也就没有办法知道状态是何时更新的,无法很好的进行状态跟踪,会给调试带来困难
(通常异步操作都是通过Action来提交mutation实现)
3.1 创建Mutation
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation(类似于事件)
这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,第二个参数(Payload)作为可选的额外参数:
mutations: {
// 修改数据 同步操作
addAge(state, data) {
state.age += data
console.log(state.age)
},
},
3.2 Mutation的使用
mutation处理函数不能被直接调用。要使用mutation处理函数,需要相应的type调用store.commit方法:
store.commit('addAge',2)
4.Action
描述:Action类似于mutation,不同的点在于:
- Action 提交的是mutation,而不是直接变更状态
- Action可以包含任何异步操作
4.1 创建Action
Action函数接收一个与store实例相同方法和属性的context对象(这里我是解构了commit),第二个参数(Payload)作为可选的额外参数:
actions: {
// 异步操作
incrementAsync({commit},data){
setTimeout(()=>{
commit('addAge',data)
console.log('延迟长大')
},100)
}
},
4.2 注册及使用Action
Action通过store.dispatch()方法触发
store.dispatch('incrementAsync',3)
三、使用步骤
1.安装vuex4
npm install vuex@next --save
yarn add vuex@next --save
如果是vite创建的项目需要自己配置
我的是:src/store/index.ts
import {createStore} from 'vuex'// new store
export default createStore({
state:{
// 存储数据 数据是响应式的
},
getters:{
// 当项目有多个地方需要复用某个算法时,可以将其封装在此
// 类似于计算属性
},
mutations:{
// 修改数据 同步操作
},
actions:{
// 异步操作
}
})
2.注册及使用
这里我用的是vue3,同时使用了vite-plugin-pages插件
src/main.ts:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(router).use(store).mount('#app')
src/store/index.ts:
import { createStore } from 'vuex' // new store
export default createStore({
state: {
// 存储数据 数据是响应式的
age: 23,
ageOld: 10,
},
getters: {
// 类似于计算属性,当项目有多个地方需要复用某个算法时,可以将其封装在此
// 目前没有缓存机制,预计会在3.2解决
changeAge(state,getters){
console.log('触发')
return getters.oldAge
},
oldAge(state){
return state.age+=5
}
},
mutations: {
// 修改数据 同步操作
addAge(state, data) {
state.age += data
console.log(state.age)
},
},
actions: {
// 异步操作
incrementAsync({commit},data){
setTimeout(()=>{
commit('addAge',data)
console.log('延迟长大')
},100)
}
},
})
src/pages/index.vue:
<template>
<view>This index</view>
<div>我的年龄:{{ age }}</div>
<div>我哥的年龄:{{ changeAge }}</div>
<button @click="addAge">长大</button>
<button @click="addAgeAsync">延迟长大</button>
</template>
<script setup>
import { useStore } from 'vuex'
import {computed} from 'vue'
const store = useStore()
// 当age发生变化时,会触发它的更改
const age = computed(()=>{
return store.state.age
})
const changeAge = store.getters.changeAge
const addAge = () => { return store.commit('addAge', 2)}
const addAgeAsync = () => { return store.dispatch('incrementAsync',10)}
</script>
看到这里了可以给我来个三连吗
,你的小手一点就是我更新的动力!!!
希望这篇文章对你有帮助~~