您好,登錄后才能下訂單哦!
今天小編給大家分享一下vue3 $attrs和inheritAttrs怎么用的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
$attrs
屬性解釋:包含了父作用域中不作為組件 props 或自定義事件的 attribute 綁定和事件。當一個組件沒有聲明任何prop 時,這里會包含所有父作用域的綁定,并且可以通過 v-bind="$attrs" 傳入內部組件——這在創建高階的組件時會非常有用。
inheritAttrs
屬性解釋:如果你不希望組件的根元素繼承特性,你可以在組件的選項中設置 inheritAttrs: false
可能不是很好理解,我們可以舉個例子來驗證一下。
<template> <div> <MyInput type="text" placeholder="輸入用戶名" v-model="state.text" /> <MyInput type="password" placeholder="輸入密碼" v-model="state.pass" /> </div> </template>
<script setup> import MyInput from "@/components/myInput.vue"; import { reactive } from "vue"; const state = reactive({ text: "", pass: "", }); </script>
<template> <div class="input"> <input v-bind="$attrs" v-model="modelValue" /> </div> </template>
<script> export default { props: { modelValue: [String, Number], }, }; </script>
<template> <div class="input"> <input v-bind="$attrs" v-model="modelValue"/> </div> </template>
<script> export default { inheritAttrs: false, props: { modelValue: [String, Number], }, }; </script>
小結:
由上述例子可以看出,子組件的props中未注冊父組件傳遞過來的屬性。
當設置inheritAttrs:true時,子組件的頂層標簽元素中會渲染出父組件傳遞過來的屬性(例如:type="text"等)
當設置inheritAttrs: false時,子組件的頂層標簽元素中不會渲染出父組件傳遞過來的屬性
不管inheritAttrs為true或者false,子組件中都能通過$attrs屬性獲取到父組件中傳遞過來的屬性。
官網的文檔簡短而又不清晰,實在是看不懂,只好自己找代碼驗證來看看是什么意思:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.1.5/vue.global.js"></script> </head> <body> <div id="app"> <father :v1="'value1'" :v2="'value2'" :v3="'value3'"></father> </div> </body> </html>
<script> const app = Vue.createApp({ data() { return {} }, }) app.component('father', { // inheritAttrs: false, props: ['v1'], template: ` <div><p>v1 is {{v1}}</p> <son v-bind='$attrs' :some="1"></son> </div>`, created() { console.log('father:', this.$attrs) } }) app.component('son', { // inheritAttrs: false, props: ['v2'], template: `<div><p>v2 is {{v2}}</p> <grandSon v-bind='$attrs'></grandSon> </div>`, created() { console.log('son:', this.$attrs) } }) app.component('grandSon', { props: ['v3'], template: `<p>v3 is {{v3}}</p>`, created() { console.log('grandSon:', this.$attrs) } }) app.mount('#app') </script>
頁面顯示的結果:
v1 is value1
v2 is value2
v3 is value3
頁面源代碼:
<div id="app" data-v-app=""> <div v2="value2" v3="value3"> <!-- 這是father --> <p>v1 is value1</p> <div v3="value3" some="1"> <!-- 這是 son--> <p>v2 is value2</p> <p some="1">v3 is value3</p> <!-- 這是 grandSon --> </div> </div> </div>
控制臺打印是當前組件的$attrs:
father: Proxy {v2: "value2", v3: "value3", __vInternal: 1}
son: Proxy {v3: "value3", some: 1, __vInternal: 1}
grandSon: Proxy {some: 1, __vInternal: 1}
首選,father組件被傳入了3個值,但是實際使用props接收的只有v1,v2和v3作為attributes在DOM里面渲染了。
上圖的devtool 也可以說明,另外就是控制臺也同時證明了。
同樣son組件只是接收v2作為prop:
grandSon組件只是接收v3作為prop
father prop:v1,attributes: v2,v3
son prop:v2 ,attributes:v3,some
grandSon prop:v3,,attributes: some
發現無論是father傳入的3個值v1,v2,v3還是son又傳入的值':some=1',
只要不被prop傳入下一層組件,那么一定是在下一層組件的$attrs,也就是說不被作為prop的值會傳入下一個組件作為attrs的一員。一個組件的attrs由父組件傳遞以及自己自帶的組合而成。
上面說的是$attrs,那么inheritAttrs則說的是attrs繼承,這里的繼承是控制DOM渲染,不繼承也就是不渲染了,但是實際還是存在這個attrs的。
`inheritAttrs`屬性默認是true,所以能看到上面的結論,attrs會往下傳,當設置為false的時候就不會在DOM渲染從上一層繼承來的attrs。
修改一下代碼:
app.component('father', { inheritAttrs: false, // 不繼承 props: ['v1'], template: ` <div><p>v1 is {{v1}}</p> <son v-bind='$attrs' :some="1"></son> </div>`, created() { console.log('father:', this.$attrs) } })
father組件這不繼承attrs,控制臺的打印沒變:
father: Proxy {v2: "value2", v3: "value3", __vInternal: 1}
son: Proxy {v3: "value3", some: 1, __vInternal: 1}
grandSon: Proxy {some: 1, __vInternal: 1}
devtool這里依然可以看到attrs
但是看源代碼:
<div id="app" data-v-app=""> <div> <!-- 這里是 father --> <!-- 看這行 --> <p>v1 is value1</p> <div v3="value3" some="1"> <!-- 這里是 son--> <p>v2 is value2</p> <p some="1">v3 is value3</p> <!-- 這里是 grandSon--> </div> </div> </div>
DOM渲染里面的v2,v3 attrs都不存在了。
以上就是“vue3 $attrs和inheritAttrs怎么用”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。