vue3 | isRef、unref、toRef、toRefs

楊芋可可發表於2023-02-07

isRef

檢查某個值是否是ref。是返回true,否則返回false

const num = ref(10);
const num1 = 20;
const num2 = reactive({ data: 30 });

console.log(isRef(num)); //true
console.log(isRef(num1)); //false
console.log(isRef(num2)); //false

unref()

如果引數是ref,則返回內部值,否則返回引數本身。
這是  val = isRef(val) ? val.value : val  計算的一個語法糖。

console.log(unref(num));
console.log(unref(num1));
console.log(unref(num2));

toRef

介紹

基於響應式物件上的某個屬性,建立一個對應的 ref。建立出來的 ref 會跟源屬性保持同步:更改了 ref 的值就會更改源屬性的值,反之亦然。

  • 引數一:操作物件
  • 引數二:物件屬性
const val = reactive({
  num: 1,
});

const numRef = toRef(val, "num");

// 更改該 ref 會更新源屬性
numRef.value++;
console.log(val.num); // 2

// 更改源屬性也會更新該 ref
val.num++;
console.log(numRef.value); // 3

使用場景

toRef()  這個函式在你想把一個 prop 的 ref 傳遞給一個組合式函式時會很有用當我們向元件傳遞 props 資料時,如果想要某個資料同父元件同步更新。當  toRef  與元件 props 結合使用時,關於禁止對 props 做出更改的限制依然有效。嘗試將新的值傳遞給 ref 等效於嘗試直接更改 props,這是不允許的。在這種場景下,可以使用watch去監聽我們定義ref()物件。

<template>
  <n-modal :show="props.visible">
    <n-card
      style="width: 600px"
      title="編輯"
      :bordered="false"
      size="huge"
      role="dialog"
      aria-modal="true"
    >
      <n-input v-model:value="inputValue"></n-input>
      <template #footer>
        <n-el class="flex justify-end">
          <n-space>
            <n-button @click="emits('cancel')">取消</n-button>
            <n-button @click="emits('save', inputValue)">確定</n-button>
          </n-space>
        </n-el>
      </template>
    </n-card>
  </n-modal>
</template>

<script lang="ts" setup>
  import { toRef, watch, ref } from 'vue'
  const props = defineProps<{
    visible: boolean
    value: string
  }>()

  const emits = defineEmits<{
    (e: 'save', data: string): void
    (e: 'cancel'): void
  }>()

  const valueToRef = toRef(props, 'value')
  const inputValue = ref(props.value)

  watch(
    () => valueToRef.value,
    (v) => (inputValue.value = v)
  )
</script>
<style></style>
  const visible = ref(true)
  const inputValue = ref('哈哈哈哈')
  const handleSave = (v: string) => {
    console.log('v', v)
  }
  const handleCancel = () => {
    visible.value = false
  }

  <Demo :value="inputValue" :visible="visible" @save="handleSave" @cancel="handleCancel" />

注:檢視更新的問題

參考: https://www.cnblogs.com/web-learn/p/16725393.html

toRefs()

將一個響應式物件轉換為一個普通物件,這個普通物件的每個屬性都指向源物件相應的屬性的ref。每個單獨的ref都是使用toRef()建立的。

const val = reactive({
  num: 1,
});

const numRef = toRefs(val);

// 更改該 ref 會更新源屬性
numRef.num.value++;
console.log(val.num); // 2

// 更改源屬性也會更新該 ref
val.num++;
console.log(numRef.num.value); // 3

toRefs()解構出來的物件不會失去響應性。

如下:

const obj = reactive({
  num: 10,
  num2: 20,
});

const { num1, num2 } = toRefs(obj);

toRefs  在呼叫時只會為源物件上可以列舉的屬性建立 ref。如果要為可能還不存在的屬性建立 ref,請改用  toRef

相關文章