Vue 3 專業職人 筆記 === ###### tags: `Vue3` 1.v-for為何要寫key值 因為key值不帶的話,只要array裡面的值有做更動,vue會把整個array重新渲染,但加入key值後,他就知道哪一筆資料有變動進而只渲染那一筆資料。 而需要成功綁定key值,就需要獨立的值,老師在裡面也特別提到千萬別用index(也就是索引值)當作key,請看以下範例: ``` <div v-for=(item,index) in array :key="index"> array=[ {id:1,name:'William',age:18}, {id:3.name:'Cindy',age:20}, {id:6,name:'George',age:30} ] ``` 也就是說如果key是塞入index的話,假設說array的資料有做順序變動的話,index也會跟著變動,然後在渲染的時候就有機會錯誤或是渲染成別筆資料,所以建議是綁入每筆資料的唯一值會是最好。 但是在實務上,後端傳回的資料不一定都會有唯一值,所以有兩個解決方式 第一個是~~打爆後端~~和後端溝通,麻煩他在每筆資料塞入唯一值 第二個是自己在資料中增加唯一值 --- 2.Computed 跟 Methods computed 會依據計算的資料進行緩存,只要你的資料沒有重新被更改,你的 computed 不會被重新計算執行 methods 不會進行緩存,每次都會重新執行 ,但是可以傳入參數進行處理 --- 3.watch watch變數和object時,watch寫法有些許的不同,請看以下範例 ``` const num = ref(0); watch(num, (num, prevNum) => { console.log({ num }); }); ``` ``` const numData = reactive({ idx: 0 }); // newIdx:1 oldIdx:1 newIdx:2 oldIdx:2 newIdx:3 oldIdx:3 watch(numData, (idx, prevIdx) => { console.log(`newIdx:${ idx.idx } oldIdx${prevIdx.idx}`); } ); const numData2 = reactive({ idx: 0 }); // newIdx:1 oldIdx:0 newIdx:2 oldIdx:1 newIdx:3 oldIdx:2 watch(() => numData2.idx, (idx, prevIdx) => { console.log(`newIdx:${ idx } oldIdx${prevIdx}`); } ); timer = setInterval(() => { numData.idx++; numData2.idx++; if (numData2.idx > 2) { clearInterval(timer); } }) ``` 第一個範例主要是去監聽變數,跟以前vue2的時候差不多,只要寫上需要監聽的變數名稱就好 但是在第二個範例中需要監聽的是object中的變數,watch需要寫上一個箭頭函式return之後才能監聽得到 4.ref與reactive 承上所說,如果上司或是團隊規定只能用ref來做綁定,那要如何用watch來監控物件或是陣列呢?像是以下情況 ``` const array = ref({user:{}}) watch(array,(newVal)=>{ console.log(newVal.user); }) setTimeout(()=>{ array.value.user['name']="William" },1000) ``` 上面的範例本來是想使用watch去監聽user裡的name值,但是如果使用ref去定義物件或是陣列的話,是無法去做深度監聽的。 因此,如果想要ref定義物件又要在監聽物件裡的元素的話,就必須使用watch的第三個參數【deep】來解決這個難題。 ``` const array = ref({user:{}}) watch(array,(newVal)=>{ console.log(newVal.user); },{deep:true}) setTimeout(()=>{ array.value.user['name']="William" },1000) ``` Tip:使用deep的時候請注意,因為它是去針對物件的每個key去做掃描,所以會非常消耗效能。 建議使用時機:需要監聽物件裡的每個元素時才需要在watch的第一個參數放上物件,其他情況得直接寫上物件裡的元素對效能會比較好。(參考以下範例) ``` watch(array.value.user,(newVal)=>{ console.log(newVal); }) ``` 5.watchEffect 特性: #1.一開始就會執行,與watch監聽資料改變才會執行不一樣 範例: ``` const num = ref(0); const numData = reactive({ idx: 0 }); watchEffect(() => { if(num.value >= 4){ console.log(num.value); } }); setTimeout(() => { num.value++; numData.idx++; }, 1000); ``` 結果會印出 ``` 0 1 ``` #2.假設有兩個參數(number and array),number只有設定初始值,array裡的元素透過setTimeout去改變值,這樣的情況下,在watchEffect只console number會印出兩個0嗎? ``` const number = ref(0); const array = reactive({index:0}); watchEffect(()=>{ console.log(number.value) }) setTimeout(()=>{ array.index++; }) ``` 答案是不會,watchEffect只會印出一個0 ![](https://i.imgur.com/UbjVgl4.png) 原因是因為雖然array裡的資料有變化,但是因為watchEffect會去掃描他裡面的資料有沒有調用到(上方範例只有調用到number),有調用到他就會去執行,所以要讓number印出我們要的結果就得把array也寫進去watchEffect裡 ``` const number = ref(0); const array = reactive({index:0}); watchEffect(()=>{ console.log(number.value) console.log(array.index) }) setTimeout(()=>{ array.index++; }) ``` #3.和watch最大的不同是,watchEffect可以執行到一半去中斷它,參考以下範例: ``` const num = ref(0); const numData = reactive({ idx: 0 }); const stop = watchEffect(() => { console.log(num.value); if(num.value >= 4){ console.log('執行stop function'); stop() } }); setInterval(() => { num.value++; numData.idx++; }, 1000); ``` 題外話,如果需要順便把setInterval也中斷的話,可以把setInterval宣告成一個變數,然後在clearInerval裡即可中斷,以下是參考範例 ``` const timer = setInterval(() => { num.value++; numData.idx++; }, 1000); clearInterval(timer) ``` 6.事件修飾符(Event Modifiers) .prevent =>解決點選連結時原本的網址會在最後面加上"#"的問題 ``` <a href="#" @click.prevent="handleClick"></a> ``` .stop =>解決冒泡事件往上傳遞的問題,也就是解決內層a標籤點選後會同時點選外層的click事件 ``` <div @click="handleClick"> <p @click.stop="handleInfo">詳細資料</p> </div> ``` 7.v-model Modifiers #1 lazy =>在離開表單也就是移除焦點時他才會去處理邏輯 #2 number =>把字串轉型為數字然後回傳 #3 trim =>把前後的空白去掉 8.建構一個新的VUE專案 #1 安裝vue cli最新版指令 ``` npm install -g @vue/cli or yarn global add @vue/cli ``` PS:W10有時候會遇到安裝完Vue cli後要用指令去建構新專案會跑出錯誤的問題 錯誤訊息: 參考資料:因為這個系統上已停用指令碼執行,所以無法載入...的訊息 這時候解法是用系統管理員的權限開啟Windows PowerShell後在命令列輸入Set-ExecutionPolicy RemoteSigned然後再輸入A(以上皆是)即可解決 #2建構專案 ``` vue create <project-name> ``` 在裡面也能夠選擇預設安裝套件及vue版本 8.router相關配置 #1 createWebHistory #2 createWebHashHistory 使用情境:不需在意SEO 1.2020 Vue3 專業職人 | 入門篇 2.https://segmentfault.com/a/1190000019961419 3.https://hsiangfeng.github.io/other/20200510/1067127387/