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 解決
<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 中的 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中的屬性和class和style除外)
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>標簽位置不對

