Vue Component 之 Slot
栏目: JavaScript · 发布时间: 6年前
内容简介:關於顯示於 Component 的 data,除了使用 prop 傳遞外,也可使用 slot 傳遞。Vue 2.5.17Vue CLI 3.0.3
關於顯示於 Component 的 data,除了使用 prop 傳遞外,也可使用 slot 傳遞。
Version
Vue 2.5.17
Vue CLI 3.0.3
Slot Content
<navigation-link url="/profile"> Your Profile </navigation-link>
在自己寫了 component 間夾了 data。
<a v-bind:href="url"class="nav-link"> <slot></slot> </a>
在 component 的 HTML template 中使用 <slot></slot>
,則 component 間夾的 data 將取代 <slot></slot>
。
若 HTML template 內沒有 <slot></slot>
,則 data 將不會顯示
最後 HTML 為:
<a v-bind:href="url"class="nav-link"> Your Profile </a>
<slot></slot>
可視為 placeholder,專門顯示 component tag 間的 data,如此就不必什麼 data 都靠 prop 傳遞。
Slot 可是為傳遞 data 的另外一種方式,尤其是 顯示型
的 data
<navigation-link url="/profile"> <!-- Add a Font Awesome icon --> <span class="fa fa-user"></span> Your Profile </navigation-link>
Component tag 間不單只能放 data,也可以放其他 HTML。
<navigation-link url="/profile"> <!-- Use a component to add an icon --> <font-awesome-icon name="user"></font-awesome-icon> Your Profile </navigation-link>
Component tag 間也可以放其他 component。
Named Slot
Vue 也允許在一個 component 間有多個 slot,此時必須使用 Named Slot 。
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
我們希望 base-layout
component 的 header
、 main
與 footer
三部分都使用 slot,由 user 提供 data。
一個 component 只能有一個 default slot ,其他都必須是 named slot
所以在 header
與 footer
使用了 named slot,在 <slot></slot>
多了 name
,設定 slot 的名稱為 header
與 footer
。
main
則使用 default slot,不特別為 slot 取名稱。
<base-layout> <template slot="header"> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template slot="footer"> <p>Here's some contact info</p> </template> </base-layout>
使用 base-layout
component 時,由於有多個 slot,要搭配 template
tag 將 data 與 HTML 包起來,並使用 slot
attribute 指定 slot 名稱。
沒使用 template
tag 部分,則為 default slot。
<base-layout> <h1 slot="header">Here might be a page title</h1> <p>A paragraph for the main content.</p> <p>And another one.</p> <p slot="footer">Here's some contact info</p> </base-layout>
也可以直接對 HTML 加上 slot
attribute。
最後 HTML 為:
<div class="container"> <header> <h1>Here might be a page title</h1> </header> <main> <p>A paragraph for the main content.</p> <p>And another one.</p> </main> <footer> <p>Here's some contact info</p> </footer> </div>
3 個 slot 完全被取代。
Default Slot Content
Slot 雖然目的就是由 user 提供 data 顯示,但有時候會想在 component 內提供預設顯示 data。
<button type="submit"> <slot>Submit</slot> </button>
submit-button
component 預設顯示 Submit
,但也允許 user 提供其他 data 顯示,如 Save
與 Upload
,就可在 <slot>
與 </slot>
之間夾預設顯示 data。
Scoped Slot
若想由 user 自訂 slot,但實際 data 卻是在 component 內,此時就要使用 Scoped Slot 。
<ul> <li v-for="(todo, index) in todos" :key="index"> {{ todo.title }} </li> </ul>
todo-list
component 雖然已經提供 todo.title
的顯示,但為了讓 component 更有彈性,想提供 slot 由 user 能夠提供不同顯示方式。
<ul> <li v-for="(todo, index) in todos" :key="index"> <slot :todo="todo"> {{ todo.title }} </slot> </li> </ul>
將 todo
以 prop 方式傳進 slot,此為預設顯示方式。
<todo-list :todos="todos"> <template slot-scope="slotProps"> <span v-if="slotProps.todo.completed">✓</span> {{ slotProps.todo.text }} </template> </todo-list>
User 提供了不同的顯示方式取代 slot。
在 <template>
加上 slot-scope
attribute 指定 scope 名稱,然後使用 scope 名稱存取 component 內的 data。
不一定得使用 <template>
tag,任何 HTML tag 加上 slot-scope
皆可
<todo-list :todos="todos"> <template slot-scope="{ todo }"> <span v-if="todo.completed">✓</span> {{ todo.text }} </template> </todo-list>
若搭配 ECMAScript 2015 的 Object Destructuring,則有更好的寫法。
因為 slotProps
本質就是有 todo
property 的 object。
可使用 { todo }
將 todo
取出為變數直接使用,則不必在定義 slotProps
這種中介變數。
Conclusion
- 有了 Slot,顯示型的 data 就不必再使用 prop,可直接使用 slot 傳遞
- 若 component 提供多個 slot,則要使用 Named Slot
- Slot 也可提供預設顯示 data
- 若想提供 user 自訂 slot,卻要讀取 component 內的資料,則要使用 Scoped Slot;若搭配 ECMAScript 2015 的 Object Destructuring 寫法,則非常精簡
Reference
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。