{%hackmd BJrTq20hE %} ###### tags: `Vue` `composition API` # 從composition API 開始VUE的生活-ref、reactive、computed的差別 ## ref 具有響應式的資料儲存方式會回傳promise物件,ref()可以存入任何型別的資料。 但是讀取與寫入的時候需要.value。例如 ```javascript= const myName = ref('Jack') console.log(myName.value) // 'Jack' myName.value = 'Jay' console.log(myName.value) // 'Jay' ``` ## reactive 具有響應式的資料儲存方式,reactive()內只能放入物件或陣列,如果放入這兩個以外的資料形式則會報錯。 在reactive內的的資料屬性一樣具有響應式的特性每個屬性都可以看做是一個ref,在呼叫reactive會進行"解包",所以不用像ref要加上.value。 ```javascript= const myData = reactive({ name:'Jack', age:25 }) console.log(myData.name) // 'Jack' myData.age = 30 console.log(myData.age) // 30 ``` reactive的"解包"特性範例 ```javascript= const num = ref(0) const data = reactive({ num:num }) // 請問要取出num的數值需要加value嗎? console.log(data.num) //0 ``` ## 對於ref與ractive的watch watch的作用是用來監測資料有沒又變化,有變化則做出動作,使用watch不能改變所監測的資料。 watch(所監測的資料,()=>{}//所執行的動作,{deep=true}//需要深度監測才加入) ```javascript= const data = ref(0) const data2 = reactive({num:0}) setTimeout(()=>{ data.value = 1 data2.num = 1 },2000) watch(data, ()=>{ console.log(`data被改變成${data.value}`) }) watch(data2, ()=>{ console.log(`data2.num被改變成${data2.num}`) }) ``` 如果ref內是物件的話則會監控不到 ```javascript= const data = ref({name:'Jay', age:25 }) setTimeout(()=>{ data.value.name = 'May' console.log(data.value.name) },2000) watch(data,()=>{ console.log(`data.value.name被改變成${data.value.name}`) }) ``` ## deep:true的使用 同上一個範例只是增加了deep:true ```javascript= const data = ref({name:'Jay', age:25 }) setTimeout(()=>{ data.value.name = 'May' console.log(data.value.name) },2000) watch( data, ()=>{console.log(`data.value.name被改變成${data.value.name}`)} ,{deep:true} ) ``` 只要watch增加了deep:true,無論是ref()或是reactive()的深層物件內容都可以被監測。 ## computed computed是一個定義資料的方法,本身是一個函式無法傳入參數,所以只能透過return的方式把資料傳出,computed最主要的功能是重組與計算資料。 只在computed內部的響應式資料發生改變,computed就會重新渲染畫面 以下的範例畫面剛開始是"我是Jack",兩秒之後就會面成"我是"Jay" ```javascript= const data = ref({name:'Jack'}) const dataComputed =computed(()=>{ return `我是${data.value.name}` }) setTimeout(()=>{ data.value.name = 'Jay' },2000) ``` ```htmlembedded= <h2> {{dataComputed}} </h2> ``` ## computed的getter、setter功能 coumputed所return的資料本身就是個ref 沿用上述的範例並在最後加上console.log(dataComputed.value) ```javascript= const data = ref({name:'Jack'}) const dataComputed =computed(()=>{ return `我是${data.value.name}` }) setTimeout(()=>{ data.value.name = 'Jay' },2000) console.log(dataComputed.value)// 我是Jay ``` computed本身預設就是get功能 ## get與set的寫法 ```javascript= const num = ref(1) const numComputed = computed({ get:()=>{return num.value}, set:(val)=>{num.value = val} //get(){return num.value}, //set(){num.value = val} }) console.log('num',num.value) // 1 console.log('numComputed', numComputed.value) // 100 // 寫入資料 numComputed.value = 100 console.log('numComputed after set', numComputed.value) // 100 console.log('num after set',num.value) //100 ``` 可以看到原本的ref的資料被些改了 參考資料 --- [Vue3 + Vite 快速上手 Get Startrd EP2 - 定義資料 ref、reactive、computed 深度探討](https://www.youtube.com/watch?v=gJF5Cf2fz1A)