浅聊一下
最近看了一下vuex的源码,来和大家一起分享一下
VUEX
什么是vuex?其实vuex就是一个状态管理的设计模式。先来看看如何使用...
安装
安装 | Vuex (vuejs.org),安装教程双手奉上...
引入
- 首先在main.js中引入并且use掉
js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import store from './store/index'
createApp(App)
.use(store)
.mount('#app')
vuex是vue生态的一个插件,所以我们需要使用安装并且use的一个操作让他生效,这意味着vuex中存在一个接口可以和vue连接,待会我们将来手写...
使用
- 来到index.js
js
import {createStore} from 'vuex'
const store = createStore({
state(){
return {
count:1
}
},
getters:{
double(state){
return state.count * 2
}
},
mutations:{
add(state){
state.count++
}
},
actions:{
asyncAdd({ commit }){
setTimeout(()=>{
commit('add')
},1000)
}
}
})
export default store
createStore接收一个对象,里面有state()、getters、mutations、actions。在state()中储存数据,getter中储存一些有返回值的方法或者计算属性,mutation中存放同步方法,actions中放异步方法...最后将store对象抛出
- 来到APP.vue
js
<template>
<div>
{{count}}*2 = {{double}}
<br>
<button @click="add">add</button>
<button @click="asyncAdd">asyncAdd</button>
</div>
</template>
<script setup>
import { computed } from 'vue';
//hooks编程
import { useStore } from 'vuex';
let store = useStore();
let count = computed(() => store.state.count);
let double = computed(() => store.getters.double);
function add(){
store.commit('add')
}
function asyncAdd(){
store.dispatch('asyncAdd')
}
</script>
<style lang="css" scoped>
</style>
先创建store实例,通过mutation中的方法通过commit引入,actions里的方法通过dispatch引入...
源码实现
主要实现store类,dispatch、commit、createStore、useStore
store
store是一个类
js
class Store {
constructor(options) {
this.$options = options
// 私有的
// store.state. proxy
this._state = reactive({
data:options.state()
})
this._mutations = options.mutations
this._actions = options.actions
this.getters = {}
Object.keys(options.getters).forEach(name=>{
const fn = options.getters[name]
this.getters[name] = computed(()=>fn(this.state))
})
}
get state() {
//get
return this._state.data
}
commit = (type,payload)=>{
const entry = this._mutations[type]
entry && entry(this.state,payload)
}
dispatch(type,payload) {
const entry = this._actions[type]
return entry && entry(this,payload)
}
install(app) {
// 电台 发布者
app.provide(STORE_KEY, this)// provide vue内置方法
}
}
constructor(options)
: 构造函数接收一个options
对象,该对象包含有关状态管理器的配置信息。this._state
: 使用Vue 3的reactive
函数创建了一个响应式状态对象,它包含了应用的状态数据。状态数据初始化为options.state()
的返回值。this._mutations
和this._actions
: 分别存储变更和异步操作的处理函数。this.getters
: 存储获取器(类似于计算属性)的对象。get state()
: 这是一个getter方法,用于获取状态数据。它简单地返回this._state.data
。commit(type, payload)
:通过commit()来获取mutations中的方法,在mutations中查找以type为键名的方法,然后返回dispatch(type, payload)
: 这是一个用于分发异步操作的方法。它会查找给定type
的异步操作处理函数,并执行它。
你可以看到其实commit
和dispatch
的代码是一样的,所以为什么说mutation处理同步,而actions处理异步呢?我了解到其实他们设计的初衷就是将同步和异步操作分开来,其实并没有什么大的区别...
install(app)
: 这个方法用于安装状态管理器到Vue应用中。它使用Vue 3的provide
方法将STORE_KEY
关联的值设置为当前Store
实例,使得在应用的任何地方都可以通过依赖注入来访问该实例。这就是vuex和vue相连接的关键...
useStore && createStore
- useStore
js
const STORE_KEY = '__store__'
function useStore() {
return inject(STORE_KEY)
}
在Vue 3中,为了在组件中使用全局状态管理器,需要使用一个名为inject
的函数来访问它。但是每次在组件中都调用inject
函数来获取全局状态管理器会显得有些繁琐。
为了简化这个过程,可以创建一个自定义的函数(例如useStore
),该函数封装了inject
函数的调用,使得在组件中获取全局状态管理器更加简单。
- createStore
js
function createStore(options) {
return new Store(options)
}
效果
结尾
最近在学习vue的源码系列...之后会一直更新vue源码,从template到虚拟DOM等等...