watch.uvue 5.0 KB
Newer Older
DCloud-WZF's avatar
DCloud-WZF 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
<template>
  <!-- #ifdef APP -->
  <scroll-view style="flex: 1; padding-bottom: 20px">
  <!-- #endif -->
    <view class="page">
      <text id="count" ref="countRef" class="uni-common-mb">count: {{ count }}</text>
      <text id="watch-count-res" class="uni-common-mb">watch count result: {{ watchCountRes }}</text>
      <text id="watch-count-track-num" class="uni-common-mb">watch count track number: {{ watchCountTrackNum }}</text>
      <text id="watch-count-trigger-num" class="uni-common-mb">watch count trigger number:
        {{ watchCountTriggerNum }}</text>
      <text id="watch-count-cleanup-res" class="uni-common-mb">watch count cleanup result:
        {{ watchCountCleanupRes }}</text>
      <button id="increment-btn" class="uni-common-mb" @click="increment">
        increment
      </button>
      <button id="stop-watch-count-btn" class="uni-common-mb" @click="triggerStopWatchCount">
        stop watch count
      </button>
      <text id="obj-str" ref="objStrRef" class="uni-common-mb">obj.str: {{ obj.str }}</text>
      <text id="obj-num" class="uni-common-mb">obj.num: {{ obj.num }}</text>
      <text id="obj-bool" ref="objBoolRef" class="uni-common-mb">obj.bool: {{ obj.bool }}</text>
      <text id="obj-arr" ref="objArrRef" class="uni-common-mb">obj.arr: {{ obj.arr }}</text>
      <text id="watch-obj-res" class="uni-common-mb">watch obj result: {{ watchObjRes }}</text>
      <text id="watch-obj-str-res" class="uni-common-mb">watch obj.str result: {{ watchObjStrRes }}</text>
      <text id="watch-obj-bool-res" class="uni-common-mb">watch obj.bool result: {{ watchObjBoolRes }}</text>
      <text id="watch-obj-arr-res" class="uni-common-mb">watch obj.arr result: {{ watchObjArrRes }}</text>
      <button id="update-obj-btn" class="uni-common-mb" @click="updateObj">
        update obj
      </button>
      <text id="watch-count-obj-num-res" class="uni-common-mb">watch count and obj.num result:
        {{ watchCountAndObjNumRes }}</text>
    </view>
  <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>

<script setup>
  type Obj = {
    num : number,
    str : string,
    bool : boolean,
    arr : number[]
  }

  const countRef = ref(null)
  const count = ref(0)
  const watchCountRes = ref('')
  const watchCountCleanupRes = ref('')
  const watchCountTrackNum = ref(0)
  const watchCountTriggerNum = ref(0)

  const stopWatchCount = watch(count, (count : number, prevCount : number, onCleanup : OnCleanup) => {
    watchCountRes.value = `count: ${count}, prevCount: ${prevCount}, count ref text (flush sync): ${(countRef.value as Element).getAttribute('value')}`
    const cancel = () => {
      watchCountCleanupRes.value = `watch count cleanup: ${count}`
    }
    onCleanup(cancel)
  }, {
    // 侦听器在响应式依赖改变时立即触发
    flush: 'sync',
    // 响应属性或引用作为依赖项被跟踪时调用
    onTrack(event : DebuggerEvent) {
      if (event.type === 'get') {
        watchCountTrackNum.value++
      }
    },
    // 侦听器回调被依赖项的变更触发时调用
    onTrigger(event : DebuggerEvent) {
      if (event.type === 'set') {
        watchCountTriggerNum.value++
      }
    }
  })

  const triggerStopWatchCount = () => stopWatchCount()

  const increment = () => {
    count.value++
  }

  const obj = reactive({
    num: 0,
    str: 'num: 0',
    bool: false,
    arr: [0]
  } as Obj)

  // immediate: true 第一次触发, 旧值应该是 undefined, 现在 app 是初始值
  const watchObjRes = ref('')
  watch(obj, (obj : Obj, prevObj : Obj) => {
    watchObjRes.value = `obj: ${JSON.stringify(obj)}, prevObj: ${JSON.stringify(prevObj)}`
  }, { immediate: true })

  const objStrRef = ref(null)
  const watchObjStrRes = ref('')
  watch(() : string => obj.str, (str : string, prevStr : string) => {
    watchObjStrRes.value = `str: ${str}, prevStr: ${prevStr}, obj.str ref text (flush pre): ${(objStrRef.value as Element).getAttribute('value')}`
  }, {
    // 侦听器在组件渲染之前触发
    flush: 'pre',
  })

  const objBoolRef = ref(null)
  const watchObjBoolRes = ref('')
  watch(() : boolean => obj.bool, (bool : boolean, prevBool : boolean) => {
    watchObjBoolRes.value = `bool: ${bool}, prevBool: ${prevBool}, obj.bool ref text (flush post): ${(objBoolRef.value as Element).getAttribute('value')}`
  }, {
    // 侦听器延迟到组件渲染之后触发
    flush: 'post'
  })


  const watchObjArrRes = ref('')
  watch(() : number[] => obj.arr, (arr : number[], prevArr : number[]) => {
    watchObjArrRes.value = `arr: ${JSON.stringify(arr)}, prevArr: ${JSON.stringify(prevArr)}`
  }, { deep: true })

  const watchCountAndObjNumRes = ref('')
  watch([count, () : number => obj.num], (state : number[], preState : number[]) => {
    watchCountAndObjNumRes.value = `state: ${JSON.stringify(state)}, preState: ${JSON.stringify(preState)}`
  })

  const updateObj = () => {
    obj.num++
    obj.str = `num: ${obj.num}`
    obj.bool = !obj.bool
    obj.arr.push(obj.num)
  }
</script>