测试中
使用mobx的响应函数autorun监听状态变化进行赋值和运行函数,页面onLoad时执行所有autorun,页面onUnload时销毁所有autorun
observer.ts
import {autorun, IReactionDisposer, IReactionPublic, reaction, toJS} from 'mobx'
// 响应 Mobx ,对 Observables 作出响应
export const Observer = <T extends { new(...args: any[]): any }>(constructor: T) => {
return class ObserverClass extends constructor {
disposer: IReactionDisposer[] = []
reaction: string[] = []
autorun: string[] = []
onLoad(evt: any) {
super.onLoad && super.onLoad(evt)
if (super.autorun) {
this.disposer = this.disposer || []
this.disposer.push(...super.autorun.map((x) => autorun((this as any)[x].bind(this))))
}
if (super.reaction) {
this.disposer.push(...super.reaction.map((x) => {
return (this as any)[x]()
}))
}
}
onUnload() {
super.onUnload && super.onUnload()
if (this.disposer) {
this.disposer.forEach(x => x())
this.disposer.length = 0
}
}
}
}
// autorun操作
export const Render = (target: any, key: string, descriptor: TypedPropertyDescriptor<() => void>) => {
target.autorun = target.autorun || []
target.autorun.push(key)
}
// autorun操作
export const Autorun = (target: any, key: string, descriptor: TypedPropertyDescriptor<() => any>) => {
target.autorun = target.autorun || []
target.autorun.push(key)
}
// Reactor操作
export const Reactor = (target: any, key: string, descriptor: TypedPropertyDescriptor<() => IReactionDisposer>) => {
target.reaction = target.reaction || []
target.reaction.push(key)
}
// 和Reactor搭配进行副作用操作
export const React = <T>(expression: (r: IReactionPublic) => T, effect: (arg: T, r: IReactionPublic) => void) => {
return reaction(expression, effect, {fireImmediately: true})
}
// 状态转属性
export function State(value: any) {
return function (target: any, key: string): any {
let funcKey = 'store_to_' + key
target[funcKey] = function () {
this[key] = toJS(this.store[value])
}
target.autorun = target.autorun || []
target.autorun.push(funcKey)
}
}
index.vue
<template>
<div class="index">
<h1>store.step: {{store.step}}</h1>
<h1>step: {{step}}</h1>
<h1>step2: {{step2}}</h1>
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from "vue-property-decorator";
import {Autorun, Observer, State} from '@/utils/observer';
import {store} from '@/utils/store'
@Component
@Observer //必须紧贴index组件
export default class index extends Vue {
//名称必须为store
store = store
//单向 state.tep -> this.step ,修改 this.step 不影响 state.step
@State('step')
step: string = ''
step2: string = ''
//mobx 的监听函数 autorun
@Autorun
autorun_step() {
this.step2 = store.step
}
onLoad(evt?: any) {
console.log('onLoad.evt', evt)
store.step = 'aaa'
setTimeout(() => {
store.step = 'bbb'
}, 1000)
}
}
</script>
<style scoped lang="stylus">
.index
padding 0
</style>
本文地址: