Vue 項目中常遇到的問題

刷新頁面,傳的參數類型變了

問題描述

vue-router通過query傳參,比如:?fromWork=true&extraType=1,傳過去的fromWorkboolean型,extraTypenumber型,但是當刷新頁面時,拿到的參數都變成了字元串。

解決方式

  • 拿到參數後進行類型轉換

  • 用boolean型用0/1代替,如果需要number型,則在頁面轉換


頁面合併時,各個組件樣式衝突

問題描述

比如兩個組件都設有background-color,一個為red,另一個為green,都在App頁面中引入使用了。頁面渲染時會發生合併,樣式衝突。後引入的組件樣式會覆蓋先引入的組件樣式。

解決方式

  • css中引入scoped


v-if 與 v-for 同時使用會報錯

問題描述

在進行項目開發的時候因為在一個標籤上同時使用了v-for和v-if兩個指令導致的報錯。

提示錯誤:The ‘undefined’ variable inside ‘v-for’ directive should be replaced with a computed property that returns filtered array instead. You should not mix ‘v-for’ with ‘v-if’

v-for 的優先順序比 v-if 的高,所以每次渲染時都會先循環再進條件判斷,而又因為 v-if 會根據條件為 true 或 false來決定渲染與否的,所以如果將 v-if 和 v-for一起使用時會特別消耗性能,如果有語法檢查,則會報語法的錯誤。

解決方式

  • 將 v-for 放在外層嵌套 template (頁面渲染不生成 DOM節點) ,然後在內部進行 v-if 判斷

<template v-for="Oitem in Object.keys(cItem)">
  <el-input 
    type="textarea"
    :autosize="{ minRows: 2, maxRows: 8}"
    :key="Oitem"          // 注意點:key值寫在包裹的元素中
    v-if="Oitem !== 'title'"
    v-model="cItem[Oitem]">
  </el-input>
</template>
  • 如果條件出現在循環內部,不得不放在一起,可通過計算屬性computed 提前過濾掉那些不需要顯示的項


key屬性值要唯一,且不是index

問題描述

vue中使用 v-ifv-for 要加上key屬性,否則在高版本的vue中控制台會報錯。這個Key是一個唯一值,不能是index。key一般應用在v-ifv-for中更新渲染時,它們都是默認「就地復用」 的策略。

解決方案

使用index 作為 key和沒寫基本上沒區別,因為不管數組的順序怎麼顛倒,index 都是 0, 1, 2…這樣排列,導致 Vue 會復用錯誤的舊子節點,做很多額外的工作。


需要深拷貝數組或對象

問題描述

對象或數組的簡單賦值,修改新值也會改變原值。這時我們需要獲取原值的深拷貝對象。

解決方案

  • 對於對象,可以通過newObj = JSON.parse(JSON.stringfy(obj))實現。

  • 對於數組,可以通過 newArr = […arr]或者newArr = arr.slice(0)來實現。


vue 2.0 修改對象屬性

問題描述

在vue 2.0 中,由於Object.defineproperty() 的弊端,給對象新增屬性,刪除屬性,或者對象屬性又是一個對象的時候,無法被監聽到,頁面不會被更新。

解決方案

  • vue 3.0 中使用Proxy 解決了這個問題。

  • 使用Vue.$set() 進行修改。


對數組對象,進行深度監聽

問題描述

後端傳過來的數組每一項都是對象,當對象的屬性變化時調用某個函數,自然想到就是watch方法。但如何watch數組對象中某一個具體的屬性,顯然不可能一個個屬性寫watch

解決方案

  • watch整個數組,設置deeptrue,當該對象發生改變時,調用處理函數。

  • 將頁面中綁定的屬性寫在computed函數中,watch這個computed中的函數,當對象值改變時會進入computed函數中,進而進入watch函數中,再調用處理函數。


樣式切換時,動態增加class

問題描述

當樣式需要切換的時候,盡量不要寫兩個 v-ifv-show 來切換樣式。v-show 不是惰性的,在沒有必要的時候,還是插入在DOM中;然後v-if 又有一個明顯的創建和刪除過程。可以通過動態添加class 的方法切換樣式。

解決方案

給元素動態增加class時,可以在模板中通過:class={『hasClass』: ifHasClass}來實現,當ifHasClasstrue時,該元素會自動加上hasClass的樣式。 如果在一個元素中使用了兩個class則會報錯,動態綁定的class可以與正常寫的一起使用。


父子組件通訊,props單向綁定

問題描述

vue中的props是單向綁定的,父組件的屬性變化時會傳遞給子組件,子組件內部不應改變props的值,否則控制台會給出警告。雖然當 props的類型為數組或者對象時,在子組件內部改變props的值 vue 檢測不到。但官方不建議在子組件內改變父組件的值,因為這違反了vue中props單向綁定的思想。

解決方案

  • eventBus事件匯流排適用於父子組件非父子組件等之間的通訊。

  • 依賴注入(provide / inject)用於父子組件祖孫組件之間的通訊。

    provide(發送) / inject(接收)是Vue提供的兩個鉤子,和datamethods是同級的。


vue中函數的this指向問題

問題描述

箭頭函數中的this指向定義後就固定不變; 普通函數中的this指向是變誰調用的指向誰。

created () {    
    // 箭頭函數中this指向vue
    setInterval(() => { console.log(this) }, 1000)  
    // 普通函數中this指向window,因為setInterval()函數是window對象的函數
    setInteval(function () { console.log(this) }, 1000) 
}

解決方案

如果要使用普通函數,要使用了一個變數來當中間值

function(){
    let temp = this;
    setInvertal(function(){....}, 1000)
}