p in props"/> p in props">

Rumah >hujung hadapan web >View.js >Cara menggunakan jam tangan untuk memantau nilai harta objek dalam Vue3

Cara menggunakan jam tangan untuk memantau nilai harta objek dalam Vue3

WBOY
WBOYke hadapan
2023-06-03 13:09:345274semak imbas

Gunakan jam tangan dalam Vue3 untuk mendengar sifat khusus dalam objek

1 Prakata

<script lang="ts" setup>
	// 接受父组件传递的数据
    const props = defineProps({
        test: {
            type: String,
            default: &#39;&#39;
        }
    })
    
    // 使用 watch 侦听 props 中的 test 属性
    watch(
        // 这种写法不会侦听到 props 中 test 的变化
    	props.test,
        () => {
            console.log("侦听成功")
        }
    )
    
    watch(
    	// 这种写法会侦听到 props 中 test 的变化
        () => props.test,
        () => {
            console.log("侦听成功")
        }
    )
</script>

Penggunaan asas jam tangan

jam tangan. () Lalai ialah malas mendengar, iaitu, fungsi panggil balik hanya dilaksanakan apabila sumber mendengar berubah

Parameter pertama: mendengar sumber, mendengar sumber mendengar boleh menjadi mana-mana daripada berikut

Fungsi yang mengembalikan nilai, ref, objek responsif (reaktif) atau tatasusunan yang terdiri daripada jenis nilai di atas

Parameter kedua: apabila sumber mendengar menukar Fungsi panggil balik yang dicetuskan.

(newValue, oldValue) => { /* kod */}

Apabila mendengar berbilang sumber, fungsi panggil balik menerima dua tatasusunan, sepadan dengan nilai baharu ​​​​dalam tatasusunan sumber dan nilai lama

( [ newValue1, newValue2 ] , [ oldValue1 , oldValue2 ]) => {/* kod */}

Parameter ketiga: objek pilihan, boleh disokong Pilihan ini

segera: Cetuskan panggilan balik serta-merta apabila pendengar dibuat dalam: Jika sumber adalah objek, lintasan kedalaman dipaksa supaya fungsi panggil balik dicetuskan apabila tahap dalam berubah siram: Laraskan pemasaan segar semula bagi fungsi panggil balik onTrack/onTrigger: Ketergantungan pendengar penyahpepijatan

2 Sebab

Kerana sumber pendengaran watch hanya boleh menjadi 4 situasi di atas

const obj = reactive({ count: 0 })

// 错误,因为 watch() 中的侦听源是一个 number,最终 source 返回的 getter 函数是一个空,所以就得不到侦听的数据
watch(obj.count, (count) => {
  console.log(`count is: ${count}`)
})

// 正确,主要思想是,将侦听源转化为以上4种类型(转化为getter函数是最简单方便的)
watch(
  () => obj.count,
  (count) => {
    console.log(`count is: ${count}`)
  }
)

3. .menonton analisis kod sumber

export function watch<T = any, Immediate extends Readonly<boolean> = false>(
  source: T | WatchSource<T>,
  cb: any,
  options?: WatchOptions<Immediate>
): WatchStopHandle {
  if (__DEV__ && !isFunction(cb)) {
    warn(
      `\`watch(fn, options?)\` signature has been moved to a separate API. ` +
      `Use \`watchEffect(fn, options?)\` instead. \`watch\` now only ` +
      `supports \`watch(source, cb, options?) signature.`
    )
  }
  return doWatch(source as any, cb, options)
}

Seperti yang dapat dilihat daripada kod sumber, watch menerima tiga parameter: sourcesumber pendengaran, cbfungsi panggil balik, optionskonfigurasi mendengar, dan akhirnya mengembalikan doWatch

4.doWatch analisis kod sumber

function doWatch(
  source: WatchSource | WatchSource[] | WatchEffect | object,
  cb: WatchCallback | null,
  { immediate, deep, flush, onTrack, onTrigger }: WatchOptions = EMPTY_OBJ
): WatchStopHandle {
  // ...
// 当前组件实例
const instance = currentInstance
// 副作用函数,在初始化effect时使用
let getter: () => any
// 强制触发侦听
let forceTrigger = false
// 是否为多数据源。
let isMultiSource = false
}

doWatch masih menerima tiga parameter: sourcesumber mendengar, cbfungsi panggil balik, optionskonfigurasi mendengar

Di sini kami memberi tumpuan kepada menganalisis kod sumber sumber pendengaran (pestandardan sumber)

  • Jika source ialah jenis ref, getter ialah fungsi source.value pulangan, forceTrigger bergantung pada sama ada source adalah reaktif cetek.

if (isRef(source)) {
  getter = () => source.value
  forceTrigger = isShallow(source)
}
  • Jika source daripada jenis reactive, getter ialah fungsi yang mengembalikan source dan menetapkan deep kepada true . Apabila mendengar terus kepada objek reaktif, pendengar secara automatik mendayakan mod dalam

if (isReactive(source)) {
  getter = () => source
  deep = true
}

Contoh

<template>
  <div class="container">
    <h3>obj---{{ obj }}</h3>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script lang="ts" setup>
import { reactive, watch } from "vue";
const obj = reactive({
  name: "张三",
  age: 18,
});
const changeName = () => {
  obj.name += "++";
};
const changeAge = () => {
  obj.age += 1;
};
// obj 中的任一属性变化了,都会被监听到
watch(obj, () => {
  console.log("变化了");
});
</script>
  • jika source ialah Array, tetapkan isMultiSource kepada true, forceTrigger bergantung pada sama ada source mempunyai data jenis reactive, fungsi getter akan merentasi source dan mengendalikan pelbagai jenis source secara berbeza.

if (isArray(source)) {
  isMultiSource = true
  forceTrigger = source.some(isReactive)
  getter = () =>
    source.map(s => {
      if (isRef(s)) {
        return s.value
      } else if (isReactive(s)) {
        return traverse(s)
      } else if (isFunction(s)) {
        return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER)
      } else {
        __DEV__ && warnInvalidSource(s)
      }
    })
}
  • Jika source ialah function. Apabila cb wujud, getter akan dilaksanakan dalam fungsi source, di mana source akan dilaksanakan melalui fungsi callWithErrorHandling dan ralat yang berlaku semasa pelaksanaan callWithErrorHandling akan dikendalikan dalam source; tidak wujud cb, dalam getter, jika komponen telah dinyahpasang, terus return, jika tidak nilai cleanup (cleanup ialah fungsi pembersihan yang didaftarkan melalui watchEffect dalam onCleanup), jika ia wujud cleanup melaksanakan cleanup, kemudian laksanakan source, dan mengembalikan hasil pelaksanaan. source akan dibalut oleh callWithAsyncErrorHandling Fungsi ini akan mengendalikan ralat yang berlaku semasa pelaksanaan source Berbeza daripada callWithErrorHandling, callWithAsyncErrorHandling akan mengendalikan ralat tak segerak.

if (isFunction(source)) {
  if (cb) {
    getter = () =>
      callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER)
  } else {
    // watchEffect
    getter = () => {
      // 如果组件实例已经卸载,直接return
      if (instance && instance.isUnmounted) {
        return
      }
      // 如果清理函数,则执行清理函数
      if (cleanup) {
        cleanup()
      }
      // 执行source,传入onCleanup,用来注册清理函数
      return callWithAsyncErrorHandling(
        source,
        instance,
        ErrorCodes.WATCH_CALLBACK,
        [onCleanup]
      )
    }
  }
}
  • Dalam kes lain getter akan diberikan fungsi kosong

getter = NOOP
__DEV__ && warnInvalidSource(source)

Atas ialah kandungan terperinci Cara menggunakan jam tangan untuk memantau nilai harta objek dalam Vue3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Artikel sebelumnya:Apakah alat visualisasi Vue3?Artikel seterusnya:Apakah alat visualisasi Vue3?