Vue 3.0 響應性 基礎

2021-07-16 11:42 更新

#聲明響應式狀態(tài)

要為 JavaScript 對象創(chuàng)建響應式狀態(tài),可以使用 reactive 方法:

import { reactive } from 'vue'


// 響應式狀態(tài)
const state = reactive({
  count: 0
})

reactive 相當于 Vue 2.x 中的 Vue.observable() API ,為避免與 RxJS 中的 observables 混淆因此對其重命名。該 API 返回一個響應式的對象狀態(tài)。該響應式轉(zhuǎn)換是“深度轉(zhuǎn)換”——它會影響嵌套對象傳遞的所有 property。

Vue 中響應式狀態(tài)的基本用例是我們可以在渲染期間使用它。因為依賴跟蹤的關系,當響應式狀態(tài)改變時視圖會自動更新。

這就是 Vue 響應性系統(tǒng)的本質(zhì)。當從組件中的 data() 返回一個對象時,它在內(nèi)部交由 reactive() 使其成為響應式對象。模板會被編譯成能夠使用這些響應式 property 的渲染函數(shù)

響應性基礎 API 章節(jié)你可以學習更多關于 reactive 的內(nèi)容。

#創(chuàng)建獨立的響應式值作為 refs

想象一下,我們有一個獨立的原始值 (例如,一個字符串),我們想讓它變成響應式的。當然,我們可以創(chuàng)建一個擁有相同字符串 property 的對象,并將其傳遞給 reactive。Vue 為我們提供了一個可以做相同事情的方法 ——ref

import { ref } from 'vue'


const count = ref(0)

ref 會返回一個可變的響應式對象,該對象作為它的內(nèi)部值——一個響應式的引用,這就是名稱的來源。此對象只包含一個名為 value 的 property :

import { ref } from 'vue'


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


count.value++
console.log(count.value) // 1

#Ref 展開

當 ref 作為渲染上下文 (從 setup() 中返回的對象) 上的 property 返回并可以在模板中被訪問時,它將自動展開為內(nèi)部值。不需要在模板中追加 .value

<template>
  <div>
    <span>{{ count }}</span>
    <button @click="count ++">Increment count</button>
  </div>
</template>


<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const count = ref(0)
      return {
        count
      }
    }
  }
</script>

#訪問響應式對象

ref 作為響應式對象的 property 被訪問或更改時,為使其行為類似于普通 property,它會自動展開內(nèi)部值:

const count = ref(0)
const state = reactive({
  count
})


console.log(state.count) // 0


state.count = 1
console.log(count.value) // 1

如果將新的 ref 賦值給現(xiàn)有 ref 的 property,將會替換舊的 ref:

const otherCount = ref(2)


state.count = otherCount
console.log(state.count) // 2
console.log(count.value) // 1

Ref 展開僅發(fā)生在被響應式 Object 嵌套的時候。當從 Array 或原生集合類型如 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)

#響應式狀態(tài)解構(gòu)

當我們想使用大型響應式對象的一些 property 時,可能很想使用 ES6 解構(gòu)來獲取我們想要的 property:

import { reactive } from 'vue'


const book = reactive({
  author: 'Vue Team',
  year: '2020',
  title: 'Vue 3 Guide',
  description: 'You are reading this book right now ;)',
  price: 'free'
})


let { author, title } = book

遺憾的是,使用解構(gòu)的兩個 property 的響應性都會丟失。對于這種情況,我們需要將我們的響應式對象轉(zhuǎn)換為一組 ref。這些 ref 將保留與源對象的響應式關聯(lián):

import { reactive, toRefs } from 'vue'


const book = reactive({
  author: 'Vue Team',
  year: '2020',
  title: 'Vue 3 Guide',
  description: 'You are reading this book right now ;)',
  price: 'free'
})


let { author, title } = toRefs(book)


title.value = 'Vue 3 Detailed Guide' // 我們需要使用 .value 作為標題,現(xiàn)在是 ref
console.log(book.title) // 'Vue 3 Detailed Guide'

你可以在 Refs API 部分中了解更多有關 refs 的信息

#使用 readonly 防止更改響應式對象

有時我們想跟蹤響應式對象 (refreactive) 的變化,但我們也希望防止在應用程序的某個位置更改它。例如,當我們有一個被 provide 的響應式對象時,我們不想讓它在注入的時候被改變。為此,我們可以基于原始對象創(chuàng)建一個只讀的 Proxy 對象:

import { reactive, readonly } from 'vue'


const original = reactive({ count: 0 })


const copy = readonly(original)


// 在copy上轉(zhuǎn)換original 會觸發(fā)偵聽器依賴


original.count++


// 轉(zhuǎn)換copy 將導失敗并導致警告
copy.count++ // 警告: "Set operation on key 'count' failed: target is readonly."
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號