2023年度鐵人_[Day 13] vue的響應式介紹_ref()及reactive()
vue本身這套框架提供了完整的responsive資料即時連動更新機制。
什麼是響應式?
響應式白話來說就是當某變數在其它地方修改之後,任何在修改之前引用到此變數的地方都會隨之改變。
寫過jquery或用純javascript寫過事件的就知道,預設純js/jquery是不支援即時連動更新機制。你需要寫很多dom操作的行為。
Vue 有提供這麼一個方法叫做 watchEffect()方法,幫助我們實踐響應式更新 DOM元素。
新增一個Responsive.vue 組件檔案
只先寫以下程式
1 2 3 4 5 6 7 8 9 10 11 | <!-- 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 裏頭渲染。
1 2 3 4 5 6 7 8 9 10 | <template> <main> <Responsive/> </main> </template> <script setup> import Responsive from './components/Responsive.vue'; </script> |
如上圖結果已經將變更為2的結果更新到 DOM 上了,
若使用事件更新 count 變數的值,就會即時的同步更新到 body 元素上。
在此我們來修改程式變更Responsive.vue來模擬事件更新DOM行為
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <!-- 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 變數的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!-- 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> |
而若變數沒用ref()來定義,變數存取不需要用.value屬性做值的存取。
主要是ref底層是把變數封裝成一個引用的物件,而物件中的值存取是需要透過value的。
小叮嚀:ref()的底層原理是把傳入的參數值包裝為一個帶有.value 屬性的ref物件。
換言之,將值型別透過 ref()包裝成參考型別,如此一來值型別就會具有響應特性,相應的值都必須透過.value 做寫入及讀取。
還有一個和ref()有點像的叫做reactive()
相較於ref()方法可使用任何值型別,reactive()只能使用參考型別。
JS 中的參考型別,大都可以使用 reactive()函數定義,可以創建一個響應式的物件或陣列、Map、Set等等集合型別。
因此若是像number,boolean,string這類的型別是無效的。
我們微調程式來測試後
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!-- 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兩者差異。
留言
張貼留言