Vue3 - 關於響應式資料
tags: Vue
category: Front-End
description: Vue3 - 關於響應式資料
created_at: 2022/07/16 11:30:00
回到 手把手開始寫 Vue3
前言
還是假設你已經做好了第一篇做的事 開新專案與環境設定
在這邊就和 Vue2
差滿多了。
先講講 Vue2 怎麼定義
這邊一樣不負責任的憑感覺打,所以可能不能跑XD
const app = new Vue({
data: {
count: 0
}
})
// or
export default {
data() {
return {
count: 0
}
}
}
上面這種方式建立資料的話,Vue
會幫你包裝,如果我沒記錯的話,你把他 console.log
印出來看,他會是一個被 Observe
物件包住的資料,代表那個資料是有被觀測的(或是說具有響應式(Reactivity
)的)
而在前端框架,其中一點就是想讓你不要一直頻繁自己操作 DOM
,又麻煩(?)又慢,希望你只要好好注重這些資料的邏輯,當資料變動,畫面就立刻更新。
所以有時候新手亂在 methods
之類的地方自己亂新增資料,就會導致那些新新增的資料並不具有響應式,導致畫面上用到卻不會即時更新。
不過還是有新增的方式,印象中是 $set
? (不管 反正現在用不到了(?))
而在 vue3
還是支援上面那樣的定義方式,不過前面文章也提到了,建議使用新的 API
寫法
看看 Vue3 怎麼定義
這邊我就確定可以跑了XD,畢竟主題的品質還是要顧(?)
<script setup>
import { reactive, ref } from "vue";
const count = ref(0);
const data = reactive({ count: 0 });
</script>
<template>
{{ count }}
{{ data }}
</template>
這邊你會看到畫面上印出
0 { "count": 0 }
而要怎麼去驗證他是響應式(Reactivity
)資料呢?
基本上你隨便寫個方式在事後改變資料,看畫面有沒有更改就知道了,所以寫一段計時器
setTimeout(() => {
count.value = 100;
data.count = 100;
}, 1000);
你會發現畫面上的東西在一秒後變成這樣
100 { "count": 100 }
當然也有對應的輔助函數可以判斷
<script setup>
import { isReactive, isRef, reactive, ref } from "vue";
const count = ref(0);
const num = 100;
const data = reactive({ count: 0 });
const obj = { count: 100 };
console.log("count is Ref? ", isRef(count));
console.log("num is Ref? ", isRef(num));
console.log("data is Reactive? ", isReactive(data));
console.log("obj is Reactive? ", isReactive(obj));
</script>
你會看到這樣的輸出
count is Ref? true
num is Ref? false
data is Reactive? true
obj is Reactive? false
ref
VS reactive
這兩個都是宣告出有響應式的資料,那這兩個到底有什麼差別?
我這邊就直接跳過講古那一段了,就是關於 Vue2
使用 Object.defineProperty()
而 Vue3
使用 Proxy()
,這個有興趣的自己去爬文(網路上應該有很多)
所以就只單就這兩個語法的差異來說
-
reactive
: 只能存物件類型、集合,例如Array
、Object
、Map
、Set
,不能存一般型態,例如String
、Number
、Boolean
-
ref
: 什麼都可以存,但是通常如果是上面提到reactive
可以存的就會使用reactive
,而只有一般型態會使用ref
如果只看上面這兩段,你可能會覺得那就統一 ref
就好了啊,幹嘛這麼麻煩?
因為他們的實作方式不太一樣,而 reactive
又有再做一點點的語法糖
從上面計時器那段應該也可以稍微看出兩者使用方式的差異,在 ref
宣告的需要使用 .value
來設定值,而 reactive
宣告的則直接設定即可。
意思就是說,如果你拿 ref
來宣告一個物件,那寫起來會有稍微一點點麻煩
const data = ref({ count: 0 });
setTimeout(() => {
data.value.count = 100; // <-- 這行是對的
data.count.value = 100; // <-- 這行是錯的
}, 1000);
可以看到說因為他是一個 ref
物件,他必須先以 .value
拿到值,也就是拿到 { count: 0 }
之後在更改。
所以 ref
一般通常拿來宣告一般型態,而 reactive
為什麼不用下 .value
呢?
因為它會自動幫你解開(也就是幫你加的感覺),怎麼做實驗呢?
const data = reactive({ count: ref(0) });
setTimeout(() => {
data.count = 100;
}, 1000);
看看上面這一段,因為他有幫忙解開 .value
,否則應該要寫 data.count.value
才會有作用。
總結
所以如果是一般的型態,就使用 ref
,否則就使用 reactive
然後也不要覺得,那到底什麼時候要用物件什麼時候要用一般型態,這就看你的規劃了,例如一個使用者,你可以
const name = '小明'
const username = 'user01'
const email = '[email protected]'
也可以
const user = {
name: '小明',
username: 'user01',
email: '[email protected]'
}
所以我是覺得不用想太多,你喜歡哪個就用哪個,滿直覺的。