Vue3響應式

HuangBingQuan發表於2024-09-03

使用ref

可以使用 ref 建立一個響應式的資料:

  <template>
    <div>{{ name }}</div>
  </template>

  <script setup>
    import { ref } from 'vue'
    // 現在的 name 就是一個響應式資料
    let name = ref('HuangBingQuan')
    console.log(name)
    console.log(name.value)
    setTimeout(() => {
      name.value = 'BingQuanHuang'
    }, 2000)
  </script>

  <style lang="scss" scoped></style>

ref 返回的響應式資料是一個物件,我們需要透過 .value 訪問到內部具體的值。模板中之所以不需要 .value,是因為在模板會對 ref 型別的響應式資料自動解包。
ref 可以持有任意的型別,可以是物件、陣列、普通型別的值、Map、Set...

物件的例子:

  <template>
    <div>{{ Person.name }}</div>
    <div>{{ Person.age }}</div>
  </template>

  <script setup>
  import { ref } from 'vue'
  // 現在的 Person 就是一個響應式資料
  let Person = ref({
    name: 'HuangBingQuan',
    age: 18
  })
  setTimeout(() => {
    Person.value.name = 'BingQuanHuang'
    Person.value.age = 20
  }, 2000)
  </script>

  <style lang="scss" scoped></style>

陣列的例子

  <template>
    <div>{{ arr }}</div>
  </template>

  <script setup>
  import { ref } from 'vue'
  // 現在的 arr 就是一個響應式資料
  let arr = ref([1, 2, 3])
  setTimeout(() => {
    arr.value.push(4, 5, 6)
  }, 2000)
  </script>

  <style lang="scss" scoped></style>

第二個點,ref 所建立的響應式資料是具備深層響應式,這一點主要體現在值是物件,物件裡面又有巢狀的物件:

  <template>
    <div>{{ Person.name }}</div>
    <div>{{ Person.age }}</div>
    <div>{{ Person.nested.count }}</div>
  </template>

  <script setup>
  import { ref } from 'vue'
  // 現在的 Person 就是一個響應式資料
  let Person = ref({
    name: 'Biil',
    age: 18,
    nested: {
      count: 1
    }
  })
  setTimeout(() => {
    Person.value.name = 'Biil2'
    Person.value.age = 20
    Person.value.nested.count += 2
  }, 2000)
  </script>

  <style lang="scss" scoped></style>

如果想要放棄深層次的響應式,可以使用 shallowRef,透過 shallowRef 所建立的響應式,不會深層地遞迴將物件每一層轉為響應式,而只會將 .value 的訪問轉為響應式:

  const state = shallowRef({ count: 1});
  // 這個操作不會觸發響應式更新
  state.value.count += 2;
  // 只針對 .value 值的更改會觸發響應式更新
  state.value = { count: 2}

具體示例:

  <template>
    <div>{{ Person.name }}</div>
    <div>{{ Person.age }}</div>
    <div>{{ Person.nested.count }}</div>
  </template>

  <script setup>
  import { shallowRef } from 'vue'
  let Person = shallowRef({
    name: 'HuangBingQuan',
    age: 18,
    nested: {
      count: 1
    }
  })
  // 下面的更新不會觸發檢視更新
  setTimeout(() => {
    Person.value.name = 'HuangBingQuan'
    Person.value.age = 20
    Person.value.nested.count += 2
  }, 2000)
  // 下面的更新會觸發檢視更新
  setTimeout(() => {
    Person.value = {
      name: 'HuangBingQuan',
      age: 30,
      nested: {
        count: 3
      }
    }
  }, 4000)
  </script>

  <style lang="scss" scoped></style>

相關文章