uni app使用mobx | uni app状态管理mobx

测试中

使用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>

本文地址:

https://www.cnblogs.com/stumpx/p/13408962.html

 

posted @ 2020-07-31 12:09  stumpx  阅读(744)  评论(0编辑  收藏  举报