状态管理
//定义组合api事件流
const $emitter = mitt()
/**
* @name: useOnChange
* @msg: 监听事件emit
*/
export function useOnChange<T extends Function>(fun: T) {
$emitter.on(EventsEnum.CHANGE, itemMessage => {
fun(itemMessage)
})
}
/**
* @name: useChange
* @msg: 触发事件emit
* @param {*}
*/
export function useChange(itemMessage: number) {
$emitter.emit(EventsEnum.CHANGE, itemMessage)
}
// A组件中触发事件发送数据
export default defineComponent({
name: 'A',
setup() {
//组件A中发送数据
const handlerClick = (item)=>{
//使用组合api发送数据
useChange(1)
}
}
})
// B组件中监听事件获取数据
export default defineComponent({
name: 'B',
setup() {
//回调中获取数据
useOnChange((mes)=>{
console.log(mes)
})
}
})
// C 组件中监听事件获取数据
export default defineComponent({
name: 'C',
setup() {
//回调中获取数据
useOnChange((mes)=>{
console.log(mes)
})
}
})
const store = {
debug: true,
state: Vue.reactive({
message: 'Hello!'
}),
setMessageAction(newValue) {
if (this.debug) {
console.log('setMessageAction triggered with', newValue)
}
this.state.message = newValue
},
clearMessageAction() {
if (this.debug) {
console.log('clearMessageAction triggered')
}
this.state.message = ''
}
}
const appA = Vue.createApp({
data() {
return {
privateState: {},
sharedState: store.state
}
},
mounted() {
store.setMessageAction('Goodbye!')
}
}).mount('#app-a')
const appB = Vue.createApp({
data() {
return {
privateState: {},
sharedState: store.state
}
}
}).mount('#app-b')
/*
* @Description:Reducer
* @version: 1.0.0
* @Author: 吴文周
* @Date: 2021-02-26 13:45:46
* @LastEditors: 吴文周
* @LastEditTime: 2021-03-02 14:52:33
*/
import { readonly, ref } from 'vue'
// 全局缓存
const map = new WeakMap()
export function useModel(hook: Function) {
if (!map.get(hook)) {
const ans = hook()
map.set(hook, ans)
}
return map.get(hook)
}
export function useReducer(reducer: Function, initialState = {}) {
const state = ref(initialState)
const dispatch = <T>(action: T) => {
state.value = reducer(action, state.value)
}
return {
state: readonly(state),
dispatch,
}
}
export function useStore(reducer: Function, initialState?: any) {
return useReducer(reducer, initialState)
}
2.实现小型reduer
/*
* @Description:xxx全局状态
* @version: 1.0.0
* @Author: 吴文周
* @Date: 2021-02-26 13:53:09
* @LastEditors: 吴文周
* @LastEditTime: 2021-03-20 16:10:59
*/
import { Ref } from 'vue'
import { useModel, useReducer } from './reducer'
// 状态接口
export interface State {
oo: string,
xx: string,
cc: string,
}
// 行为接口
export interface Action {
type: 'changeOO' | 'changeXX' | 'changeCC'//指定action
payload: State
}
// 组合函数使用是 状态接口
export type StateType = Readonly<Ref<State>>
// 使用实例接口
interface Redux {
state: StateType
// 这里不是注释,只是这样的语法mark当不识别,保证优雅性,实际使用时放开注释
//dispatch: <T extends Action>(action: T) => void
}
// 状态变更
function reducer(action: Action, state: State) {
switch (action.type) {
case 'changeOO':
state.oo = action.payload.oo
break
case 'changeXX':
state.xx = action.payload.xx
break
case 'changeCC':
state.cc = action.payload.cc
break
}
return { ...state }
}
// 初始化状态
function useStore() {
const initialState = {
oo: 'oo',
xx: 'xx',
cc: 'cc',
}
return useReducer(reducer, initialState)
}
// 组合api 函数可以被任意组件 在任意地方调用
export function useXXXRedux() {
const redux: Redux = useModel(useStore)
return redux
}
3.调用实现,在任意组件内,或者任何组合api内部,在哪里调用都行
export default defineComponent({
name: 'D',
setup() {
//回调中获取数据
const { state:xxState,dispatch } = useXXXRedux()
//监听state变化
watch(xxState, state => {
})
//触发状态改变
dispatch({type:"changeOO",{payload:{oo:"iii"}}})
})