Vue 3 響應式基礎

響應式基礎

聲明響應式狀態

reactive 至關於 Vue 2.x 中的 Vue.observable() API ,爲避免與 RxJS 中的 observables 混淆所以對其重命名。該 API 返回一個響應式的對象狀態。該響應式轉換是「深度轉換」——它會影響嵌套對象傳遞的全部 property。vue

Vue 中響應式狀態的基本用例是咱們能夠在渲染期間使用它。由於依賴跟蹤的關係,當響應式狀態改變時視圖會自動更新。react

這就是 Vue 響應性系統的本質。當從組件中的 data() 返回一個對象時,它在內部交由 reactive() 使其成爲響應式對象。模板會被編譯成可以使用這些響應式 property 的渲染函數ide

咱們一樣按照以前的項目,在 src/TemplateM.vue 寫下以下代碼:函數

書寫一個計數器,經過在 vue 中導出 reactivedefineComponent兩個方法,ui

defineComponent 用於定義組件,reactive 用於建立響應式數據。this

最後在 setup 函數中返回一個對象,對象中有 add 方法,state 響應式數據。url

<template>
  <div class="template-m-wrap">
    <button @click="add">{{state.count}}</button>
  </div>

</template>
<script>
import { defineComponent, reactive } from "vue";
export default defineComponent({
  name: 'TemplateM',
  setup() {
    const state = reactive({
      count: 0
    })

    const add = () => {
      state.count++
      console.log("state.count", state.count)
    }

    return {
      state,
      add
    }
  }
})
</
script>

建立獨立的響應式值做爲 refs

想象一下,咱們有一個獨立的原始值 (例如,一個字符串),咱們想讓它變成響應式的。固然,咱們能夠建立一個擁有相同字符串 property 的對象,並將其傳遞給 reactive。Vue 爲咱們提供了一個能夠作相同事情的方法 ——refspa

ref 會返回一個可變的響應式對象,該對象做爲它的內部值——一個響應式的引用,這就是名稱的來源。此對象只包含一個名爲 value 的 property :code

一樣咱們在上面的代碼中,加下以下代碼:orm

<template>
  <div class="template-m-wrap">
    singleCount - {{singleCount}}
    <button @click="add">{{state.count}}</button>
  </div>

</template>
<script>
import { ref, defineComponent, reactive } from "vue";
export default defineComponent({
  name: 'TemplateM',
  setup() {
    const state = reactive({
      count: 0
    })

    let singleCount = ref(0)

    const add = () => {
      state.count++
      singleCount++
      console.log("state.count", state.count, singleCount)
    }

    return {
      state,
      singleCount,
      add
    }
  }
})
</
script>

圖片

其實咱們注意到,在模板中,當 ref 做爲渲染上下文 (從 setup() 中返回的對象) 上的 property 返回並能夠在模板中被訪問時,它將自動展開爲內部值。不須要在模板中追加 .value

訪問響應式對象

Ref 展開僅發生在被響應式 Object 嵌套的時候。當從 Array 或原生集合類型如 Map訪問 ref 時,不會進行展開:

下面代碼咱們能夠看到,將一個 reactive([ref('Vue 3 Guide')]),而後根據 books[0].value 進行訪問:

<template>
  <div class="template-m-wrap">
    singleCount - {{singleCount}}
    <button @click="add">{{state.count}}</button>
    books {{books[0].value}}
  </div>

</template>
<script>
import { ref, defineComponent, reactive } from "vue";
export default defineComponent({
  name: 'TemplateM',
  setup() {
    const state = reactive({
      count: 0
    })

    let singleCount = ref(0)

    const books = reactive([ref('Vue 3 Guide')])


    const add = () => {
      state.count++
      singleCount.value++
      console.log("state.count", state.count, singleCount)
    }

    return {
      state,
      singleCount,
      books,
      add
    }
  }
})
</
script>

圖片

const map = reactive(new Map([['count', ref(0)]]))
console.log(map.get('count').value)

響應式狀態解構

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

<template>
  <div class="template-m-wrap">
    singleCount - {{singleCount}}
    <button @click="add">{{state.count}}</button>
    books {{books[0].value}}
    <br>
    {{author}} - {{title}} - from - {{book}}
  </div>
</template>

<script>
import { ref, defineComponent, reactive } from "vue";
export default defineComponent({
  name'TemplateM',
  setup() {
    const state = reactive({
      count0
    })

    let singleCount = ref(0)

    const books = reactive([ref('Vue 3 Guide')])

    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
    const add = () => {
      state.count++
      singleCount.value++
      console.log("state.count", state.count, singleCount)
    }

    return {
      state,
      singleCount,
      books,
      add,
      author,
      title,
      book
    }
  }
})
</script>

圖片

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

有時咱們想跟蹤響應式對象 (ref 或 reactive) 的變化,但咱們也但願防止在應用程序的某個位置更改它。例如,當咱們有一個被 provide 的響應式對象時,咱們不想讓它在注入的時候被改變。爲此,咱們能夠基於原始對象建立一個只讀的 Proxy 對象:

import { reactive, readonly } from 'vue'

const original = reactive({ count0 })

const copy = readonly(original)

// 在copy上轉換original 會觸發偵聽器依賴

original.count++

// 轉換copy 將導失敗並致使警告
copy.count++ // 警告: "Set operation on key 'count' failed: target is rea
相關文章
相關標籤/搜索