Реактивный API: ядро

Реактивный API: ядро

1. ссылка()

Принимает внутреннее значение и возвращает реактивный, изменяемый объект ref только с одним свойством, указывающим на его внутреннее значение .value.

  • тип

    function ref<T>(value: T): Ref<UnwrapRef<T>>
    
    interface Ref<T> {
          
          
      value: T
    }
    
  • подробности

    Объект ref является изменяемым, что означает, что вы можете .valueприсваивать ему новые значения. Он также является реактивным, т.е. все .valueоперации будут отслеживаться, а записи будут вызывать связанные с ними побочные эффекты.

    Если объект назначен ref, то этот объект будет преобразован в объект с глубоким откликом через reactive() . Это также означает, что если объект содержит вложенные ссылки, они будут глубоко развернуты.

    Чтобы избежать этого глубокого преобразования, используйте shallowRef()вместо этого.

  • пример

    const count = ref(0)
    console.log(count.value) // 0
    
    count.value++
    console.log(count.value) // 1
    

Два, реактивный ()

Возвращает реактивный прокси для объекта .

  • тип

    function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
    
  • подробности

    Реактивное преобразование является «глубоким»: оно влияет на все вложенные свойства. Реактивный объект также глубоко разворачивает любые свойства ref , оставаясь при этом отзывчивым.

    Стоит отметить, что при доступе к элементу ref в реактивном массиве или Mapтаком родном типе коллекции не будет выполняться развертывание ref.

    Чтобы избежать глубоких реактивных переходов и сохранить реакцию только на доступ верхнего уровня к этому объекту, вместо этого используйте мелководную реактивную() .

    Возвращаемый объект и его вложенные объекты будут обернуты ES Proxy , поэтому он не равен исходному объекту.Рекомендуется использовать только отзывчивые прокси и избегать использования оригинальных объектов.

  • пример

    Создайте реактивный объект:

    const obj = reactive({
          
           count: 0 })
    obj.count++
    

    Распаковка реф:

    const count = ref(1)
    const obj = reactive({
          
           count })
    
    // ref 会被解包
    console.log(obj.count === count.value) // true
    
    // 会更新 `obj.count`
    count.value++
    console.log(count.value) // 2
    console.log(obj.count) // 2
    
    // 也会更新 `count` ref
    obj.count++
    console.log(obj.count) // 3
    console.log(count.value) // 3
    

    Обратите внимание, что при доступе к элементу ref в реактивном массиве или Mapтаком родном типе коллекции развертывание ref не выполняется:

    const books = reactive([ref('Vue 3 Guide')])
    // 这里需要 .value
    console.log(books[0].value)
    
    const map = reactive(new Map([['count', ref(0)]]))
    // 这里需要 .value
    console.log(map.get('count').value)
    

    При назначении ссылки свойству ссылка reactiveбудет автоматически развернута:

    const count = ref(1)
    const obj = reactive({
          
          })
    
    obj.count = count
    
    console.log(obj.count) // 1
    console.log(obj.count === count.value) // true
    

Три, вычислено ()

Принимает функцию получения и возвращает реактивный объект ссылки только для чтения . Ссылка .valueпредоставляет возвращаемое значение функции-получателя через . Он также может принимать объект с функциями getи setдля создания доступного для записи объекта ссылки.

  • тип

    // 只读
    function computed<T>(
      getter: () => T,
      // 查看下方的 "计算属性调试" 链接
      debuggerOptions?: DebuggerOptions
    ): Readonly<Ref<Readonly<T>>>
    
    // 可写的
    function computed<T>(
      options: {
          
          
        get: () => T
        set: (value: T) => void
      },
      debuggerOptions?: DebuggerOptions
    ): Ref<T>
    
  • пример

    Создайте ссылку на вычисляемое свойство только для чтения:

    const count = ref(1)
    const plusOne = computed(() => count.value + 1)
    
    console.log(plusOne.value) // 2
    
    plusOne.value++ // 错误
    

    Создайте доступную для записи вычисляемую ссылку на свойство:

    const count = ref(1)
    const plusOne = computed({
          
          
      get: () => count.value + 1,
      set: (val) => {
          
          
        count.value = val - 1
      }
    })
    
    plusOne.value = 1
    console.log(count.value) // 0
    

    отладка:

    const plusOne = computed(() => count.value + 1, {
      onTrack(e) {
        debugger
      },
      onTrigger(e) {
        debugger
      }
    })
    

4. только чтение()

Принимает объект (реактивный или простой) или ссылку и возвращает доступный только для чтения прокси исходного значения.

  • тип

    function readonly<T extends object>(
      target: T
    ): DeepReadonly<UnwrapNestedRefs<T>>
    
  • подробности

    Прокси только для чтения являются глубокими: доступ к любым вложенным свойствам будет только для чтения. Его поведение при развертывании ссылки reactive()такое же, как и у , но развернутое значение доступно только для чтения.

    Чтобы избежать поведения глубокого преобразования, используйте вместо этого функцию smallReadonly() .

  • пример

    const original = reactive({
          
           count: 0 })
    
    const copy = readonly(original)
    
    watchEffect(() => {
          
          
      // 用来做响应性追踪
      console.log(copy.count)
    })
    
    // 更改源属性会触发其依赖的侦听器
    original.count++
    
    // 更改该只读副本将会失败,并会得到一个警告
    copy.count++ // warning!
    

Пять, смотретьЭффект ()

Немедленно запускайте функцию, реактивно отслеживая ее зависимости и повторно выполняя их при изменении зависимостей.

  • тип

    function watchEffect(
      effect: (onCleanup: OnCleanup) => void,
      options?: WatchEffectOptions
    ): StopHandle
    
    type OnCleanup = (cleanupFn: () => void) => void
    
    interface WatchEffectOptions {
          
          
      flush?: 'pre' | 'post' | 'sync' // default: 'pre'
      onTrack?: (event: DebuggerEvent) => void
      onTrigger?: (event: DebuggerEvent) => void
    }
    
    type StopHandle = () => void
    
  • подробности

    Первый аргумент — это запускаемая функция побочного эффекта. Параметр этой функции побочного эффекта также является функцией, которая используется для регистрации обратного вызова очистки. Обратный вызов очистки будет вызываться перед следующим выполнением побочного эффекта и может использоваться для очистки недопустимых побочных эффектов, таких как ожидающие асинхронные запросы (см. пример ниже).

    Второй параметр является необязательным параметром, который можно использовать для настройки времени сброса побочного эффекта или отладки зависимости побочного эффекта.

    Возвращаемое значение — это функция, используемая для остановки побочного эффекта.

  • пример

    const count = ref(0)
    
    watchEffect(() => console.log(count.value))
    // -> 输出 0
    
    count.value++
    // -> 输出 1
    

    Устранены побочные эффекты:

    watchEffect(async (onCleanup) => {
          
          
      const {
          
           response, cancel } = doAsyncWork(id.value)
      // `cancel` 会在 `id` 更改时调用
      // 以便取消之前
      // 未完成的请求
      onCleanup(cancel)
      data.value = await response
    })
    

    Остановите слушателя:

    const stop = watchEffect(() => {
          
          })
    
    // 当不再需要此侦听器时:
    stop()
    

    параметры:

    watchEffect(() => {
          
          }, {
          
          
      flush: 'post',
      onTrack(e) {
          
          
        debugger
      },
      onTrigger(e) {
          
          
        debugger
      }
    })
    

6. смотретьПостЭффект()

watchEffect()flush: 'post'Псевдоним при использовании опции.

七、watchSyncEffect()

watchEffect()flush: 'sync'Псевдоним при использовании опции.

Восемь, смотреть ()

Прослушивает один или несколько реактивных источников данных и вызывает заданную функцию обратного вызова при изменении источника данных.

  • тип

    // 侦听单个来源
    function watch<T>(
      source: WatchSource<T>,
      callback: WatchCallback<T>,
      options?: WatchOptions
    ): StopHandle
    
    // 侦听多个来源
    function watch<T>(
      sources: WatchSource<T>[],
      callback: WatchCallback<T[]>,
      options?: WatchOptions
    ): StopHandle
    
    type WatchCallback<T> = (
      value: T,
      oldValue: T,
      onCleanup: (cleanupFn: () => void) => void
    ) => void
    
    type WatchSource<T> =
      | Ref<T> // ref
      | (() => T) // getter
      | T extends object
      ? T
      : never // 响应式对象
    
    interface WatchOptions extends WatchEffectOptions {
          
          
      immediate?: boolean // 默认:false
      deep?: boolean // 默认:false
      flush?: 'pre' | 'post' | 'sync' // 默认:'pre'
      onTrack?: (event: DebuggerEvent) => void
      onTrigger?: (event: DebuggerEvent) => void
    }
    

    Типы упрощены для удобства чтения.

  • подробности

    watch()По умолчанию используется ленивое прослушивание, то есть функция обратного вызова выполняется только при изменении источника прослушивания.

    Первый параметр — это источник слушателя . Этот источник может быть любым из следующих:

    • функция, которая возвращает значение
    • рефери
    • отзывчивый объект
    • ...или массив значений вышеуказанных типов

    Второй параметр — это функция обратного вызова, которая вызывается при изменении. Эта функция обратного вызова принимает три аргумента: новое значение, старое значение и функцию обратного вызова для регистрации очистки побочных эффектов. Эта функция обратного вызова будет вызываться перед повторным выполнением побочного эффекта в следующий раз и может использоваться для очистки недопустимых побочных эффектов, таких как ожидающие обработки асинхронные запросы.

    При прослушивании нескольких источников функция обратного вызова принимает два массива: один для нового значения, а другой для старого значения в исходном массиве.

    Третий необязательный аргумент — это объект, который поддерживает следующие параметры:

    • immediate: Обратный вызов запускается сразу после создания прослушивателя. Старое значение при первом вызове undefined.
    • deep: если источником является объект, вызывает глубокий обход, чтобы обратные вызовы запускались при глубоких изменениях уровня. См. раздел Глубокие слушатели .
    • flush: настройка времени обновления функции обратного вызова. Обратитесь к разделу о времени обновления обратных вызовов .
    • onTrack / onTrigger: Зависимость прослушивателя отладки. См. раздел «Отладка прослушивателей» .

    По watchEffect()сравнению watch()с позволяет нам:

    • лениво выполнять побочные эффекты;
    • Более ясно, какое состояние должно инициировать повторное выполнение слушателя;
    • Может получить доступ к предыдущим и текущим значениям прослушиваемого состояния.
  • пример

    Прослушайте функцию получения:

    const state = reactive({ count: 0 })
    watch(
      () => state.count,
      (count, prevCount) => {
        /* ... */
      }
    )
    

    Слушайте ссылку:

    const count = ref(0)
    watch(count, (count, prevCount) => {
      /* ... */
    })
    

    При прослушивании нескольких источников функция обратного вызова принимает два массива, соответствующие новому и старому значениям в исходном массиве:

    watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
      /* ... */
    })
    

    При использовании функции-получателя в качестве источника обратный вызов будет срабатывать только при изменении возвращаемого значения функции. Если вы хотите, чтобы обратный вызов срабатывал даже при глубоких изменениях, вам нужно использовать { deep: true }принудительный прослушиватель в глубоком режиме. В глубоком режиме, если функция обратного вызова запускается из-за глубокого изменения, новое значение и старое значение будут одним и тем же объектом.

    const state = reactive({ count: 0 })
    watch(
      () => state,
      (newValue, oldValue) => {
        // newValue === oldValue
      },
      { deep: true }
    )
    

    При непосредственном прослушивании реактивного объекта слушатель автоматически включает глубокий режим:

    const state = reactive({ count: 0 })
    watch(state, () => {
      /* 深层级变更状态所触发的回调 */
    })
    

    watch()watchEffect()Имеет те же параметры времени обновления и отладки, что и :

    watch(source, callback, {
      flush: 'post',
      onTrack(e) {
        debugger
      }
    })
    

рекомендация

отblog.csdn.net/klylove/article/details/126602261