淺談 Vue 中用於父子元件傳遞資料的方式:prop 和 slot
阿新 • • 發佈:2022-04-22
簡單介紹
開發可複用元件時,經常需要父子元件間相互傳遞資料。Vue 提供了 prop 和 slot 兩種特性用於處理不同的場景:
- prop 主要用於向子元件傳遞子元件必需的資料,類似於函式的一般引數。這類資料進入子元件後無法主動影響子元件的狀態,只能被動地被子元件使用。
- slot 主要用於擴充套件子元件,使子元件具備原先沒有的內容或功能。插槽的內容進入子元件後,可能只是被子元件所使用(顯示額外的內容),也可能定義了使用子元件的內容或功能的表示式(這種情況類似於回撥函式)。
這裡的比喻不一定準確,但是可能有助於理解這兩種特性的使用場景和行為。
prop 的定義與使用
在子元件的 props 屬性中定義需要暴露到外部的 prop,然後在父元件中通過指定名稱傳入資料,而且可以指定 prop 的型別、是否必需、預設值等特性,這些特點都與函式引數的用法很像。
簡單示例——顯示“地區-日期-時間”的元件,<son>
表示子元件:
父元件:
<!-- HTML模板 --> <son :region="region" :date="date" :time="time"></son> // Javascript ... // 其他內容省略 data() { return { region: { country: "China", province: "Beijing" }, today: new Date(), }; }, computed: { date() { return this.today.getDate(); }, time() { return { hour: this.today.getHours(), minute: this.today.getMinutes(), second: this.today.getSeconds(), }; }, }, components: { son, }, ...
子元件
... // 其他內容省略 props: { region: { country: String, province: String, }, date: { type: Number, required: true, }, time: { hour: { type: [Number, String], default: 0, }, minute: { type: Number, default: 0, }, second: { type: Number, default: 0, }, }, }, ...
插槽 slot 的型別與使用
- 預設插槽:父元件中未指定插槽名稱或作用域的內容,會進入子元件預設插槽
<slot></slot>
。同時,多個預設插槽會重複傳入的內容。使用已被廢棄的slot="default"
方式將插槽的名字宣告為 default 相當於預設插槽。 - 具名插槽:父元件中指定了插槽名稱的內容,會進入子元件的具名插槽,當子元件不存在指定的具名插槽時,傳遞的內容會被靜默忽略。同樣地,多個具名插槽也會重複傳入的內容。
- 作用域插槽:父元件中
插槽使用示例
父元件:
<son>
這是一句話。
<template>這是另一句話。</template>
<!-- 具名插槽 -->
<template v-slot:header>
<p>這是頭部</p>
</template>
<template #content>
<p>這是主體</p>
</template>
<!-- 這裡指定了不存在的具名插槽,裡面的內容會被忽略 -->
<template #footer>
<p>這是底部</p>
</template>
<!-- 作用域插槽 -->
<!-- 這裡將作用插槽中的預設內容姓替換為了名 -->
<template v-slot:person="scope">
<p>{{scope.user.firstName}}</p>
</template>
</son>
子元件:
<div class="son">
<!-- 具名插槽 -->
<slot name="header"></slot>
<!-- 相同的具名插槽會重複輸出傳入的內容 -->
<slot name="content"></slot>
<slot name="content"></slot>
<!-- 預設插槽 -->
<slot></slot>
<!-- 作用域插槽 -->
<slot
name="person"
:user="user"
>{{ user.lastName }}</slot>
</div>
頁面輸出結果:
總結
綜上,prop 表現得更像資料型函式引數,至於子元件使用這些資料做什麼、怎麼做,父元件無法干預;而 slot 更像是傳入了一個回撥函式,使子元件具備了更多功能,甚至可以像回撥函式操作 caller 函式內部資料一樣,操作子元件的內部資料。