vue $attrs的使用全面解析
$attrs的使用vue
$attrs
是在vue的2.40版本以上添加的。- 項(xiàng)目中有多層組件傳參可以使用$attrs,可以使代碼更加美觀,更加簡(jiǎn)潔,維護(hù)代碼的時(shí)候更方便。如果使用普通的父子組件傳參prop和$emit,$on會(huì)很繁瑣;如果使用vuex會(huì)大材小用,只是在這幾個(gè)組件中使用,沒(méi)必要使用vuex;使用事件總線eventBus,使用不恰當(dāng)?shù)脑挘锌赡軙?huì)出現(xiàn)事件多次執(zhí)行。
- 如果給組件傳遞的數(shù)據(jù),組件不使用props接收,那么這些數(shù)據(jù)將作為組件的HTML元素的特性,這些特性綁定在組件的HTML根元素上
inheritAttrs
: false的含義是不希望本組件的根元素繼承父組件的attribute,同時(shí)父組件傳過(guò)來(lái)的屬性(沒(méi)有被子組件的props接收的屬性),也不會(huì)顯示在子組件的dom元素上,但是在組件里可以通過(guò)其$attrs可以獲取到?jīng)]有使用的注冊(cè)屬性, ``inheritAttrs: false`是不會(huì)影響 style 和 class 的綁定
以下是$attrs的使用示例
父組件的列表行數(shù)據(jù)傳遞給孫子組件展示
1.父組件(Father.vue)
給子組件關(guān)聯(lián)數(shù)據(jù),子組件如果不用props接收,那么這些數(shù)據(jù)就作為普通的HTML特性應(yīng)用在子組件的根元素上
<template> ? <div> ? ? <el-table :data='list'> ? ? ? <el-table-column ? ? ? ? prop="name" ? ? ? ? label="姓名" ? ? ? ></el-table-column> ? ? ? <el-table-column ? ? ? ? prop="study" ? ? ? ? label="學(xué)習(xí)科目" ? ? ? ></el-table-column> ? ? ? <el-table-column label="操作"> ? ? ? ? <template slot-scope="scope"> ? ? ? ? ? <el-button @click='transmitClick(scope.row)'>傳遞</el-button> ? ? ? ? </template> ? ? ? </el-table-column> ? ? </el-table> ? ?? ? ? <!-- 兒子組件 --> ? ? <ChildView ? ? ? :is-show="isOpen" ? ? ? :row="row" ? ? > ? ? </ChildView> ? </div> </template>
<script> import ChildView from './Child.vue' export default { ? components: { ChildView }, ? data() { ? ? return { ? ? ? isOpen: false, ? ? ? row: {}, ? ? ? list: [ ? ? ? ? { name: '王麗', study: 'Java' }, ? ? ? ? { name: '李克', study: 'Python' } ? ? ? ] ? ? } ? }, ? methods: { ? ? // 傳遞事件 ? ? transmitClick(row) { ? ? ? this.isOpen = true; ? ? ? this.row = row ? ? } ? } } </script>
2.兒子組件(Child.vue)
中間層,作為父組件和孫子組件的傳遞中介,在兒子組件中給孫子組件添加v-bind="$attrs",這樣孫子組件才能接收到數(shù)據(jù)
<template> ? <div class='child-view'> ? ? <p>兒子組件</p> ? ? <GrandChild v-bind="$attrs"></GrandChild> ? </div> </template>
<script> import GrandChild from './GrandChild.vue' export default { ? // 繼承所有父組件的內(nèi)容 ? inheritAttrs: true, ? components: { GrandChild }, ? data() { ? ? return { ? ? } ? } } </script>
<style lang="stylus"> .child-view { ? margin: 20px ? border: 2px solid red ? padding: 20px } </style>
3.孫子組件(GrandChild.vue)
在孫子組件中一定要使用props接收從父組件傳遞過(guò)來(lái)的數(shù)據(jù)
<template> ? <div class='grand-child-view'> ? ? <p>孫子組件</p> ? ? <p>傳給孫子組件的數(shù)據(jù):{{row.name}} {{row.name !== undefined? '學(xué)習(xí)' : ''}} {{row.study}}</p> ? </div> </template>
<script> export default { ? // 不想繼承所有父組件的內(nèi)容,同時(shí)也不在組件根元素dom上顯示屬性 ? inheritAttrs: false, ? // 在本組件中需要接收從父組件傳遞過(guò)來(lái)的數(shù)據(jù),注意props里的參數(shù)名稱不能改變,必須和父組件傳遞過(guò)來(lái)的是一樣的 ? props: { ? ? isShow: { ? ? ? type: Boolean, ? ? ? dedault: false ? ? }, ? ? row: { ? ? ? type: Object, ? ? ? dedault: () => { } ? ? } ? } } </script>
<style lang="stylus"> .grand-child-view { ? border: 2px solid green ? padding: 20px ? margin: 20px } </style>
結(jié)果:
在上面提過(guò),如果給子組件傳遞的數(shù)據(jù),子組件不使用props接收,那么這些數(shù)據(jù)將作為子組件的特性,這些特性綁定在組件的HTML根元素上,在vue2.40版本之后,可以通過(guò)inheritAttrs = false 來(lái)控制這些特性是否顯示在dom元素上
如:案例中父組件給子組件傳遞的row和isShow,子組件沒(méi)有使用props接收,這個(gè)2個(gè)數(shù)據(jù)直接作為HTML的特殊屬性。
子組件使用inheritAttrs = true,那么特性顯示在dom上,如果設(shè)置為false,那么特性不顯示在dom上
$attrs到底是什么?
先來(lái)看看官方文檔給的定義
包含了父作用域中不作為 prop 被識(shí)別 (且獲取) 的 attribute 綁定 (class 和 style 除外)。當(dāng)一個(gè)組件沒(méi)有聲明任何 prop 時(shí),這里會(huì)包含所有父作用域的綁定 (class 和 style 除外),并且可以通過(guò) v-bind="$attrs" 傳入內(nèi)部組件——在創(chuàng)建高級(jí)別的組件時(shí)非常有用。
既然來(lái)到這里就繼續(xù)往下看!
既然是跟組件間數(shù)據(jù)傳值有關(guān),話不多說(shuō),直接上栗子:
<div id="app"> ? ? Parent: ?{{msg}} ? ? <son-component v-bind:msg="msg"></son-component> </div> let vm = new Vue({ ? ? el: '#app', ? ? data: { ? ? ? msg: 'baseDom' ? ? }, ? ? //使用props接收 ? ? components:{ ? ? ? 'son-component': { ? ? ? ? props: [ ? ? ? ? ? 'msg' ? ? ? ? ], ? ? ? ? template:`<div>Son: ?<grandson-component v-bind:msg="msg"></grandson-component></div>`, ? ? ? ? components:{ ? ? ? ? ? 'grandson-component': { ? ? ? ? ? ? props: [ ? ? ? ? ? ? ? 'msg' ? ? ? ? ? ? ], ? ? ? ? ? ? template: `<div>Grandson: ?{{msg}}</div>` ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? } })
- 根組件內(nèi)調(diào)用son-component,并且綁定根組件data中的變量msg;
- 此時(shí)son-component中通過(guò)定義props可以接收到根組件的msg;
- 然后son-component中定義grandson-component組件,并且綁定msg;
- 此時(shí)grandson-component通過(guò)定義props可以接收到son-component組件的msg;
- 仔細(xì)查閱組件代碼,發(fā)現(xiàn)msg在son-component組件中僅僅起到傳遞作用;
- 有沒(méi)有其它辦法解決傳值冗余呢?別問(wèn),問(wèn)就有;
let vm = new Vue({ ? ? el: '#app', ? ? data: { ? ? ? msg: 'baseDom' ? ? }, ? ? //使用$attrs接收 ? ? components:{ ? ? ? 'son-component': { ? ? ? ? // props: [ ? ? ? ? // ? 'msg' ? ? ? ? // ], ? ? ? ? template:`<div>Son: ?<grandson-component v-bind="$attrs"></grandson-component></div>`, ? ? ? ? components:{ ? ? ? ? ? 'grandson-component': { ? ? ? ? ? ? props: [ ? ? ? ? ? ? ? 'msg' ? ? ? ? ? ? ], ? ? ? ? ? ? template: `<div>Grandson: ?{{msg}}</div>` ? ? ? ? ? } ? ? ? ? } ? ? ? } ? ? } })
- 首先,在son-component中不再接收根組件的msg;
- son-component組件調(diào)用grandson-component組件,綁定主角$attrs;
- 即可實(shí)現(xiàn)接收根組件msg;
總結(jié):多級(jí)組件傳值時(shí),調(diào)用目標(biāo)組件綁定$attrs,可直接獲取根組件所傳遞參數(shù),而不用每一級(jí)組件逐層傳遞。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用ElementUI寫(xiě)一個(gè)前端分頁(yè)查詢的實(shí)例
本文主要介紹了使用ElementUI寫(xiě)一個(gè)前端分頁(yè)查詢的實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02第一次使用webstrom簡(jiǎn)單創(chuàng)建vue項(xiàng)目的一些報(bào)錯(cuò)實(shí)戰(zhàn)記錄
在使用webstorm新建vue項(xiàng)目時(shí)常會(huì)遇到一些報(bào)錯(cuò),特別是新手第一次運(yùn)行項(xiàng)目,這篇文章主要給大家介紹了關(guān)于第一次使用webstrom簡(jiǎn)單創(chuàng)建vue項(xiàng)目的一些報(bào)錯(cuò)實(shí)戰(zhàn)記錄,需要的朋友可以參考下2023-02-02淺談vue中document.getElementById()拿到的是原值的問(wèn)題
這篇文章主要介紹了淺談vue中document.getElementById()拿到的是原值的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07elementui的table列超出隱藏tooltip懸浮顯示問(wèn)題
這篇文章主要介紹了elementui的table列超出隱藏tooltip懸浮顯示問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11vue導(dǎo)出excel文件流中文亂碼問(wèn)題及解決
這篇文章主要介紹了vue導(dǎo)出excel文件流中文亂碼問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06