Vue常見問題匯總


Vue2

這篇文章是我在工作中使用 vue 遇到的問題做的簡單匯總,希望能對看到這篇文章的你有所幫助

對象數組 響應式所引發的問題

對於對象

官方文檔

Vue 無法檢測 property 的添加或移除。由於 Vue 會在初始化實例時對 property 執行 getter/setter (defineProperty)轉化,所以 property 必須在 data 對象上存在才能讓 Vue 將它轉換為響應式的

解決
vm.$set(obj,"key",value)
// 或者
vm.obj = {...vm.obj,key:value}
// 或者
vm.obj = Object.assgin({},vm.obj,{key:value})

對於數組

Vue 將被偵聽的數組的變更方法進行了包裹,所以它們也將會觸發視圖更新。這些被包裹過的方法包括:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

Vue 不能檢測以下數組的變動:

當你利用索引直接設置一個數組項時,例如:vm.items[indexOfItem] = newValue
當你修改數組的長度時,例如:vm.items.length = newLength

解決

修改數組某一項

vm.$set(vm.items, indexOfItem, newValue)
// 或者
vm.items.splice(indexOfItem, 1, newValue)

修改數組長度

vm.items.splice(newLength)
// 或者
vm.items = vm.items.slice(0,newLength)

vue 中給數組中的對象,添加新屬性屬性

不能使用直接遍歷設置的方法

this.items.forEach((item) => {
  item.key = value;
});
解決
this.items.forEach((item, index) => {
  this.$set(this.items, index, { ...item, ...{ key:value } });
  //或者
  this.items.splice(index, 1, { ...item, ...{ key:value } });
});

// 或者
this.items = this.items.map( item =>{
  return { ...item, ...{ key:value } }
})

tip 修改數組中的屬性 直接修改即可 數組中的對象同外層對象的響應方式

v-if 使用時注意 vue 會將一樣的元素復用 需要加 key 解決

在下面的案例中 即使渲染出返回按鈕 因為下面的每個 else 元素都一樣 但是返回依然不現實 因為復用了下面的元素樣式 display: none; 需要在不需要復用的元素上加 key 解決

vue 原文鏈接

   <div class="top-button" v-if="isView">
    <el-button type="primary" plain @click="isView = false" icon="iconfont iconfont-hcm-back">返回</el-button>
   </div>
   <div class="top-button" v-else-if="isEdit === false">
    <el-button type="primary" plain @click="onNewPayment" icon="iconfont iconfont-hcm-add" v-btn:edit="$route.query"
     >新建</el-button
    >
    <el-button
     type="primary"
     icon="iconfont iconfont-xinchou-fabu"
     plain
     @click="onPublish(true)"
     v-btn:edit="$route.query"
     >發布</el-button
    >
    <el-button
     type="primary"
     icon="iconfont iconfont-xinchou-quxiaofabu"
     plain
     @click="onPublish(false)"
     v-btn:edit="$route.query"
     >取消發布</el-button
    >
    <el-button type="primary" plain @click="onClickCancelPublish" v-btn:edit="$route.query">設置啟動時間</el-button>
    <el-button
     type="primary"
     plain
     @click="$refs.changeLogDialog.open(currentNode.data.id, false)"
     v-btn:view="$route.query"
     >查看變更記錄</el-button
    >
   </div>

   <div class="top-button" v-else-if="isEdit">
    <el-button type="primary" plain @click="onEditSave" icon="iconfont iconfont-hcm-save">保存</el-button>
    <el-button type="primary" plain @click="onEditCancel" icon="iconfont iconfont-hcm-delete">取消</el-button>
   </div>
  </el-header>

vue 樣式:scoped 使用

深度作用選擇器

如果你希望 scoped 樣式中的一個選擇器能夠作用得“更深”,例如影響子組件,你可以使用 >>> 操作符:

<style scoped>
  .a >>> .b {
    /* ... */
  }
</style>

上述代碼將會編譯成:

.a[data-v-f3f3eg9] .b {
  /* ... */
}

注意點

注意點:如果子組件dom不在父組件內部 例如:dialog組件, 通過深度作用選擇器也不會生效
這時需要通過 全局樣式即去除 scoped + 子組件calss + 選擇器 來實現

有些像 Sass 之類的預處理器無法正確解析 >>>。這種情況下你可以使用 /deep/::v-deep 操作符取而代之——兩者都是 >>> 的別名,同樣可以正常工作。

參考: vue-loader 官方文檔-深度作用選擇器

Vue 中的 v-bind 使用問題

在 vue 中使用 v-bind 綁定對象時 需要注意 :v-bind 綁定值不會覆蓋之前的屬性

<input
  type="text"
  class="test"
  :disabled="false"
  v-bind="{ disabled: true, class: 'test3' }"
/>
<!-- 上面的代碼disabled顯示的還是false 但是class可以進行合並 顯示:class="test test3" -->
<input
  type="text"
  class="test"
  :class="'test2'"
  :disabled="false"
  v-bind="{ disabled: true, class: 'test3' }"
/>
<!--注意: class 只能合並一次  最后顯示 class="test test2"-->

模板 v-bind 綁定值的變量名為 class 報 'v-bind' directives require an attribute value.eslint

在模板中綁定的名稱不要用 class 作為命名 否則 eslint 會報'v-bind' directives require an attribute value.eslint

$attrs 可以獲取任何綁定在組件上的屬性 但( porp中的屬性和 classstyle 除外)

vue-property-decorator 注意事項(ts 項目中)

介紹鏈接[https://segmentfault.com/a/1190000019906321]

1.新建組件必須加@Component 否則組件會怎樣都不現實

router 傳參 注意事項

路由傳參 query 和 params 顯示到地址欄形式的 注意 不要超長 ,否則瀏覽器會報 413 錯誤 , 傳參需要按需傳送

prop 中默認值返回空對象

prop 中 default 默認值 返回對象或數組需要使用工廠函數 ,一般我們都會用箭頭函數簡寫

  props: {
    defaultText: {
      type: Array,
      default: ()=> []    // 工廠函數返回空數組
    },
    // 錯誤寫法
    defaultAttrs: {
      type: Object,
      default: ()=> {}    // 但是返回空對象就不能直接=>{} 這樣就代表函數的塊級作用域了 會報錯
    },
    // 正確寫法
     defaultAttrs: {
      type: Object,
      default: ()=> ({})    // 在{}外面包一層()即可
    },
  },

使用 v-on="$listeners" 的注意事項

問題

內部使用了 v-on="$listeners" 的組件事件被重復調用

案例

這里有個 Father 組件

 <Child v-on="$listeners" @click="$emit('click')" />

Child組件上用$listeners接收外部傳入的所有事件 同時有獨立 click 綁定

<Father @click="onClick" ></Father>

Father 組件上 綁定 onClick

行為

此時觸發 Child組件的 click 事件

結果

onClick事件被觸發 2 次

原因

$listeners 中 click 和 單獨綁定的 click 都被掉用了
我們在 Father 的 created中看一下 $listeners

this.$listeners  // { click: ƒ, input: ƒ}
過程

Father.\(listeners.click 直接被綁到了 Child 上 @click 也被綁定到到了 Child 上 Child click 被觸發 1 調用 Father.\)listeners.click (也就是onClick)
2 調用 @click -> 觸發 $emit('click') -> 調用 onClick

解決

v-on="$listeners" 同時又想自己綁定一些事件的情況 防止重復調用 可以使用合並事件的方式

 <Child v-on="listeners" />
export default {
  name: "Father",
  components: {
    Child,
  },
  computed: {
    listeners() {
      return {
        ...this.$listeners,
        // 用下面 click 覆蓋  this.$listeners.click
        click: () => this.$emit("click"),
      };
    },
  },
};

注意點 $attrs 不會出現這種情況

$attrs 包含了父作用域中不作為 prop 被識別 (且獲取) 的 attribute 綁定 (class 和 style 除外)

意味着 prop中的屬性 就不會出現在 $attrs 中 ,導致重復出現

Vue3 去除了$listeners

vue3 中去除了 $listeners 統一在 $attrs 中

並且 添加了 emits ,同 props 用法類似, 是用於定義需要觸發的事件的

在 emits 和 props 定義的屬性 都不會在 $attrs 中出現 ,這意味的不會出現多次調用的可能 ! vue3是挺好!

Vetur 在vue文件中 script 不高亮

不高亮

在 vue 文件中不高量

原因

</template>標簽位置不對

解決


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM