vue本身這套框架提供了完整的responsive資料即時連動更新機制。
什麼是響應式?
響應式白話來說就是當某變數在其它地方修改之後,任何在修改之前引用到此變數的地方都會隨之改變。
寫過jquery或用純javascript寫過事件的就知道,預設純js/jquery是不支援即時連動更新機制。你需要寫很多dom操作的行為。
Vue 有提供這麼一個方法叫做 watchEffect()方法,幫助我們實踐響應式更新 DOM元素。
新增一個Responsive.vue 組件檔案
只先寫以下程式
<!-- eslint-disable -->
<script setup>
import { ref, watchEffect } from 'vue'
const count = ref(0)
//監聽count值的改變
watchEffect(() => {
document.body.innerHTML = `累計計數:${count.value}`;
})
count.value = 2; //更新count的值,來間接觸發重新運算連動回饋到DOM。
</script>
在此一開始先將ref跟watchEffect兩個模組引入進來。
使用 const count = ref(0)定義 count 常數,並使用 ref 表示這是一個響應式變數,並初始為 0。
watchEffect後面補上一個call back函數,即時監聽和更新DOM。
count.value = 2;則代表之後的任意地方只要有修改值,就會通知給 body 上的HTML template,從而更新 count 變數值,藉此達到更新 DOM 的目的。
將Responsive.vue 組件import到 App.vue 裏頭渲染。
<template>
<main>
<Responsive/>
</main>
</template>
<script setup>
import Responsive from './components/Responsive.vue';
</script>
如上圖結果已經將變更為2的結果更新到 DOM 上了,
若使用事件更新 count 變數的值,就會即時的同步更新到 body 元素上。
在此我們來修改程式變更Responsive.vue來模擬事件更新DOM行為
<!-- eslint-disable -->
<template>
<div>
<span>{{count}}</span>
</div>
<div>
<input type="button" @click="editCount()" value="累加1" />
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
count.value = 2; //更新count的值,來間接觸發重新運算連動回饋到DOM。
function editCount(){
//更新count的值,來間接觸發重新運算連動回饋到DOM。
count.value++;
}
</script>
可以看到從一開始初始的2被我連按累加到12...
小叮嚀:在js中所謂const修飾代表常數後期不允許被修改,但在此使用的是響應式變數,是能夠藉由.value來做值變更的,這邊你也可以將const更改為let也一樣效果。這邊的ref十分重要若省略沒有將變數標記為響應式就不能連動更新。
前面篇章也提及到雙花括號 {{}} 是支援響應式的,因此可以即時反饋出 count 變數的值。
<!-- eslint-disable -->
<template>
<div>
<span>{{count}}</span>
</div>
<div>
<input type="button" @click="editCount()" value="累加1" />
</div>
</template>
<script setup>
//import { ref } from 'vue'
let count = 0;
//count.value = 2; //更新count的值,來間接觸發重新運算連動回饋到DOM。
function editCount(){
//更新count的值,來間接觸發重新運算連動回饋到DOM。
//count.value++;
count++;
}
</script>
這邊可看到連按都不會有效果,此時的count就不屬於響應式了,DOM始終如一是預設的0。
而若變數沒用ref()來定義,變數存取不需要用.value屬性做值的存取。
主要是ref底層是把變數封裝成一個引用的物件,而物件中的值存取是需要透過value的。
小叮嚀:ref()的底層原理是把傳入的參數值包裝為一個帶有.value 屬性的ref物件。
換言之,將值型別透過 ref()包裝成參考型別,如此一來值型別就會具有響應特性,相應的值都必須透過.value 做寫入及讀取。
還有一個和ref()有點像的叫做reactive()
相較於ref()方法可使用任何值型別,reactive()只能使用參考型別。
JS 中的參考型別,大都可以使用 reactive()函數定義,可以創建一個響應式的物件或陣列、Map、Set等等集合型別。
因此若是像number,boolean,string這類的型別是無效的。
我們微調程式來測試後
<!-- eslint-disable -->
<template>
<input type="button" @click="getData" value="獲取" />
<span>{{student.name}}</span>
</template>
<script setup>
import { reactive } from 'vue'
const student = reactive({ name: 'Mike', age: 25, sex: '男' });
const getData = () => {
student.name = 'Jackson';
};
</script>
基本上就是從一開始Mike點按後更新此student物件中的name屬性
以上就是ref跟reactive兩者差異。
本篇已同步發表至個人部落格
https://coolmandiary.blogspot.com/2023/09/2023day-13-vuerefreactive.html