天天看點

# vue3 ref 和 reactive 函數

vue3 ref 和 reactive 函數

前言

上一篇博文介紹 setup 函數的時候,最後出現一個問題,就是在 setup 函數中,編寫一個事件,直接去修改定義的變量,發現頁面上沒有更新成功,并且控制台報錯,那這篇部落格就是講解遇到的這個問題應該如何處理。

ref 函數介紹

  • ref 作用就是将基礎資料轉換為響應式資料,把資料包裝成響應式的引用資料類型的資料。
  • 通過對參數傳回值的 value 屬性擷取響應式的值,并且修改的時候也需要對 value 進行修改。
  • 在 vue2 當中,通過給元素添加 ref='xxx' ,然後使用 refs.xxx 的方式來擷取元素,vue3 也可以。
  • 當 ref 裡面的值發生變化的時候,視圖會自動更新資料。
  • ref 可以操作基本資料類型和複雜資料類型,建議使用 ref 操作隻對基本資料類型進行操作。

ref 函數使用

使用 ref 函數很簡單,首先要在頁面引用,然後就可以直接使用了,具體怎麼使用呢,下面為了友善介紹,簡單來幾個案例。

ref 函數處理基本資料類型

首先提一個需求:頁面有一個名稱需要顯示,有一個按鈕,點選按鈕的時候修改頁面展示的這個名字。

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <h1>姓名:{{name_ref}}</h1>
    <el-button type="primary" @click="btn">修改名字</el-button>
  </div>
</template>
<script>
  import { ref } from 'vue'  // 引入 ref
  export default {
    setup() {
      const name = '𝒆𝒅.'   // 建立一個變量為 𝒆𝒅.
      const name_ref = ref(name)   // ref 将參數包裹轉換成響應式資料
      const btn = () => {   // 按鈕點選修改名字
        name_ref = '我是𝒆𝒅.'   // 将名字内容改為 我是𝒆𝒅. 
      }
      return { name_ref, btn }  // 把頁面需要使用的參數和方法抛出去
    }
  }
</script>      

編寫完上面的代碼儲存重新整理,可以正常渲染資料,但是點選按鈕修改名字的時候,出現問題!

# vue3 ref 和 reactive 函數

為什麼使用過 ref 将資料映射為響應式資料還是報錯呢?我們可以先列印一下 ref 包裹後,也就是 ​

​name_ref​

​ 這個參數,看一下他的結構。

# vue3 ref 和 reactive 函數

是以說修改代碼:

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <h1>姓名:{{name_ref}}</h1>
    <el-button type="primary" @click="btn">修改名字</el-button>
  </div>
</template>
<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const name = '𝒆𝒅.'
      const name_ref = ref(name)
      console.log(name_ref)
      const btn = () => {
        name_ref.value = '我是𝒆𝒅.'  // 對響應式資料的value進行操作
      }
      return { name_ref, btn }
    }
  }
</script>      

然後在儲存代碼重新整理頁面檢視效果。

# vue3 ref 和 reactive 函數

非常棒,資料完美的修改了。

有一點需要說一下哈,就是在單檔案元件中,不必寫value,因為setup方法會自動解析,簡單的可以了解成 html 代碼不需要額外操作 value,但是邏輯層需要。

ref 函數處理複雜資料類型

首先聲明:不建議使用 ref 函數處理複雜資料類型(數組、對象等),用 ref 函數處理基本資料類型(數字、字元串等)就可以了。

例如我們寫一個案例,建立一個個人資訊,放到對象裡面展示。

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <h1>姓名:{{name_ref.name}}</h1>
    <h1>年齡:{{name_ref.age}}</h1>
  </div>
</template>
<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const boy = {
        name: '𝒆𝒅.',
        age: 10
      }
      const name_ref = ref(boy)
      console.log(name_ref)
      return { name_ref }
    }
  }
</script>      

我們先看一下對象被 ref 函數包裹後的資料結構。

# vue3 ref 和 reactive 函數

是以說,對象而言,我們修改也是通過 value 進行操作。

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <h1>姓名:{{name_ref.name}}</h1>
    <h1>年齡:{{name_ref.age}}</h1>
    <el-button type="primary" @click="btn">修改名字</el-button>
  </div>
</template>
<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const boy = {
        name: '𝒆𝒅.',
        age: 10
      }
      const name_ref = ref(boy)
      console.log(name_ref)
      const btn = () => {
        name_ref.value.name = '我是𝒆𝒅.'  // 對響應式資料的value進行操作
        name_ref.value.age = 11  // 對響應式資料的value進行操作
      }
      return { name_ref, btn }
    }
  }
</script>      

儲存代碼,重新整理頁面,檢視效果。

# vue3 ref 和 reactive 函數

看到名稱和年齡都被成功修改了。

當然了,對于數組的操作也是一樣的啦!

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <h1>姓名:{{name_ref[0]}}</h1>
    <h1>年齡:{{name_ref[1]}}</h1>
    <el-button type="primary" @click="btn">修改名字</el-button>
  </div>
</template>
<script>
  import { ref } from 'vue'
  export default {
    setup() {
      const boy = ['𝒆𝒅.', 10]
      const name_ref = ref(boy)
      const btn = () => {
        name_ref.value[0] = '我是𝒆𝒅.'  // 對響應式資料的value進行操作
        name_ref.value[1] = 11  // 對響應式資料的value進行操作
      }
      return { name_ref, btn }
    }
  }
</script>      

儲存檢視,一樣的效果。

# vue3 ref 和 reactive 函數

ref 函數擷取單個DOM元素

和 vue2 一樣,可以使用 ref 擷取元素,用法和操作資料類型相似。

頁面上有一個标簽,點選按鈕,擷取标簽的相關資料。

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <p style="color: blue;" ref="boy">我是𝒆𝒅.</p>
    <el-button type="primary" @click="btn">擷取元素</el-button>
  </div>
</template>
<script>
  import { ref, onMounted } from 'vue'
  export default {
    setup() {
      let boy = ref();
      const btn = () => {
        console.log(boy)
        console.log(boy.value)
        console.log(boy.value.innerText)
        console.log(boy.value.style.color)
      }
      return {boy, btn }
    }
  }
</script>      

重新整理檢視運作效果。

# vue3 ref 和 reactive 函數

其他相關方法

isRef

判斷是否為 ref 對象。

<script>
  import { ref, isRef } from 'vue'
  export default {
    setup() {
      const a = ref('a')
      const b = 'b' 
      console.log(isRef(a))   // true
      console.log(isRef(b))   // false
    }
  }
</script>      
# vue3 ref 和 reactive 函數

unref

如果參數為 ref,則傳回内部值,否則傳回參數本身。

val = isRef(val) ? val.value : val      

上邊代碼可以看懂吧?

<script>
  import { ref, unref } from 'vue'
  export default {
    setup() {
      const temp = ref(3)
      const newTemp = unref(temp) // newTemp 確定現在是數字類型 3
      const a = unref(1) // a 確定現在是數字類型 1
      console.log(newTemp, a)
    }
  }
</script>      
# vue3 ref 和 reactive 函數

好了,這是 ref 函數和與其常見的相關的其他函數相關的知識點内容,到此為止吧,有其他的可以自己在研究一下。

reactive 函數介紹

上面說了 ref 函數的基本用法,接下來是 reactive 函數,它的用法與 ref 函數的用法相似,也是将資料變成響應式資料,當資料發生變化時UI也會自動更新。不同的是 ref 用于基本資料類型,而 reactive 是用于複雜資料類型,是以說,不建議用 ref 函數來處理複雜資料類型的原因就是,有 reactive 來處理複雜類型資料。

reactive 函數使用

用完了 ref 函數,那 reactive 函數就很好了解了哈。

reactive 函數處理對象

還是, reactive 函數用來處理數組或者是對象,我們還是寫一個案例,操作人的基本資訊。

我們還是先列印一下用 reactive 函數包裹後的資料結構。

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <p>姓名:{{boy_reactive.name}}</p>
    <p>年齡:{{boy_reactive.age}}</p>
  </div>
</template>
<script>
  import { reactive } from 'vue'
  export default {
    setup() {
      const boy = {
        name: '我是𝒆𝒅.',
        age: 10
      }
      const boy_reactive = reactive(boy)
      console.log(boy_reactive)
      return { boy_reactive }
    }
  }
</script>      
# vue3 ref 和 reactive 函數

有列印的結果我們可以看見,這時候的資料就不是被包裹在 value 下面了,是以說我們可以直接擷取到。

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <p>姓名:{{boy_reactive.name}}</p>
    <p>年齡:{{boy_reactive.age}}</p>
    <el-button type="primary" @click="btn">修改資訊</el-button>
  </div>
</template>
<script>
  import { reactive } from 'vue'
  export default {
    setup() {
      const boy = {
        name: '我是𝒆𝒅.',
        age: 10
      }
      const boy_reactive = reactive(boy)
      const btn = () => {
        boy_reactive.name = '𝒆𝒅.'
        boy_reactive.age = 11
      }
      return { boy_reactive, btn }
    }
  }
</script>      

儲存重新整理,檢視效果。

# vue3 ref 和 reactive 函數

reactive 函數處理數組

處理數組的方式和處理對象的方式是一樣一樣的。

直接上代碼:

<template>
  <div>
    <h1>ref reactive 函數</h1>
    <p>姓名:{{boy_reactive[0]}}</p>
    <p>年齡:{{boy_reactive[1]}}</p>
    <el-button type="primary" @click="btn">修改資訊</el-button>
  </div>
</template>
<script>
  import { reactive } from 'vue'
  export default {
    setup() {
      const boy = ['我是𝒆𝒅.', 10]
      const boy_reactive = reactive(boy)
      const btn = () => {
        boy_reactive[0] = '𝒆𝒅.'
        boy_reactive[1] = 11
      }
      return { boy_reactive, btn }
    }
  }
</script>      
# vue3 ref 和 reactive 函數

我們可以看到效果是一樣的。

好了,今天内容就到這裡吧,該休息了,下篇部落客要說一下 toRef 和 toRefs 函數的使用。