Vue封裝組件利器之$attrs、$listeners的使用
前言
多級組件嵌套需要傳遞數(shù)據(jù)時,通常使用的方法是通過vuex。但僅僅是傳遞數(shù)據(jù),不做中間處理,使用 vuex 處理,未免有些大材小用了。所以就有了 $attrs 、 $listeners兩個屬性 ,通常配合 inheritAttrs 一起使用。
$attrs
從父組件傳給自定義子組件的屬性,如果沒有 prop 接收會自動設(shè)置到子組件內(nèi)部的最外層標(biāo)簽上,如果是 class 和 style 的話,會合并最外層標(biāo)簽的 class 和 style。
如果子組件中不想繼承父組件傳入的非 prop 屬性,可以使用 inheritAttrs 禁用繼承,然后通過 v-bind="$attrs" 把外部傳入的 非 prop 屬性設(shè)置給希望的標(biāo)簽上,但是這不會改變 class 和 style。
inheritAttrs 屬性 官網(wǎng)鏈接
2.4.0 新增
類型:boolean
默認值:true
詳細:
默認情況下父作用域的不被認作 props 的 attribute 綁定 (attribute bindings) 將會“回退”且作為普通的 HTML attribute 應(yīng)用在子組件的根元素上。當(dāng)撰寫包裹一個目標(biāo)元素或另一個組件的組件時,這可能不會總是符合預(yù)期行為。通過設(shè)置 inheritAttrs 到 false,這些默認行為將會被去掉。而通過 (同樣是 2.4 新增的) 實例 property $attrs 可以讓這些 attribute 生效,且可以通過 v-bind 顯性的綁定到非根元素上。
注意:這個選項不影響 class 和 style 綁定。
例子:
父組件
<template>
<my-input
required
placeholder="請輸入內(nèi)容"
type="text"
class="theme-dark"
/>
</template>
<script>
import MyInput from './child'
export default {
name: 'parent',
components: {
MyInput
}
}
</script>
子組件
<template>
<div>
<input
v-bind="$attrs"
class="form-control"
/>
</div>
</template>
<script>
export default {
name: 'MyInput',
inheritAttrs: false
}
</script>
子組件中沒有接受父組件中傳過來的值,也沒有綁定,但是有v-bind="$attrs"這個屬性,他會自動接受并綁定
inheritAttrs: false

inheritAttrs: true

$listeners (官網(wǎng)解釋)
listeners: 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過 v-on="$listeners" 傳入內(nèi)部組件——在創(chuàng)建更高層次的組件時非常有用。
先上代碼:這里只舉例focue、input兩個原生事件
// 父組件
<template>
<my-input
required
placeholder
class="theme-dark"
@focue="onFocus"
@input="onInput"
>
</my-input>
</template>
<script>
import MyInput from './child'
export default {
components: {
MyInput
},
methods: {
onFocus (e) {
console.log(e.target.value)
},
onInput (e) {
console.log(e.target.value)
}
}
}
</script>
// 子組件
<template>
<div>
<input
type="text"
v-bind="$attrs"
class="form-control"
@focus="$emit('focus', $event)"
@input="$emit('input', $event)"
/>
</div>
</template>
<script>
export default {
name: 'MyInput',
inheritAttrs: false
}
</script>
這樣綁定原生事件很麻煩,每一個原生事件都需要綁定,但用v-on="$listeners"就會省事很多
<input
type="text"
v-bind="$attrs"
class="form-control"
+ v-on="$listeners"
- @focus="$emit('focus', $event)"
- @input="$emit('input', $event)"
/>
這樣一行代碼就能解決綁定所有的原生事件的問題
使用場景
組件傳值時使用: 爺爺在父親組件傳遞值,父親組件會通過$attrs獲取到不在父親props里面的所有屬性,父親組件通過在孫子組件上綁定$attrs 和 $listeners 使孫組件獲取爺爺傳遞的值并且可以調(diào)用在爺爺那里定義的方法;
對一些UI庫進行二次封裝時使用:比如element-ui,里面的組件不能滿足自己的使用場景的時候,會二次封裝,但是又想保留他自己的屬性和方法,那么這個時候時候$attrs和$listners是個完美的解決方案。
總結(jié)
到此這篇關(guān)于Vue封裝組件利器之$attrs、$listeners使用的文章就介紹到這了,更多相關(guān)Vue封裝組件$attrs、$listeners使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
第一次在Vue中完整使用AJAX請求和axios.js的實戰(zhàn)記錄
AJAX是現(xiàn)代Web開發(fā)的一個關(guān)鍵部分,盡管它一開始看起來令人生畏,但在你的武庫中擁有它是必須的,下面這篇文章主要給大家介紹了關(guān)于第一次在Vue中完整使用AJAX請求和axios.js的相關(guān)資料,需要的朋友可以參考下2022-11-11
解決vue無法加載文件C:\Users\Administrator\AppData\Roaming\npm\vue.ps
這篇文章主要介紹了解決vue無法加載文件C:\Users\Administrator\AppData\Roaming\npm\vue.ps1因為在此系統(tǒng)上禁止運行腳本問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03
前端在el-dialog中嵌套多個el-dialog代碼實現(xiàn)
最近使用vue+elementUI做項目,使用過程中很多地方會用到dialog這個組件,有好幾個地方用到了dialog的嵌套,下面這篇文章主要給大家介紹了關(guān)于前端在el-dialog中嵌套多個el-dialog代碼實現(xiàn)的相關(guān)資料,需要的朋友可以參考下2024-01-01
Vue關(guān)于Element UI中的文本域換行問題
這篇文章主要介紹了Vue關(guān)于Element UI中的文本域換行問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03

