vue插槽v-slot

1.什麼是slot

	<app>
        <menu-main></menu-main>
        <menu-sub></menu-sub>
        <div>
          <app-footer></app-footer>
        </div>
    </app>

<app>爲例,在<app>中混合了父組件的內容和子組件的模板時,就會用到slot,這個過程叫做內容分發。
使用slot的組件有兩個特點:
1.它創建時不知道某個部分需要掛載什麼,這部分內容需要父組件調用時決定。
2.組件可能有它自己的模板。

編譯作用域

//父組件
<child-component v-show="show">
     {{messge}}
</child-component>
//子組件child-component
<template>
	<h1>{{title}}</h1>
	<div>
		<slot></slot>
	</div>
</template>

在上述代碼中,父組件引用child-component子組件,{{message}}就是一個插槽slot,它綁定的時父組件的數據,而不是子組件的數據。所以它是在父組件的作用域中編譯。v-show綁定的參數show也是父組件的數據。
{{title}}是子組件的數據,所以它是在子組件的作用域中編譯。

slot用法

slot分成三類: 匿名插槽、具名插槽、作用域插槽

匿名插槽與具名插槽

有時候我們在組件中希望使用多個插槽,爲了能識別父組件傳入的插值數據在正確的位置,我們可以給slot加上name,以便區分。
例如<base-layout>組件

<div class="container">
  <header>
    <!-- 我們希望把頁頭放這裏 -->
  </header>
  <main>
    <!-- 我們希望把主要內容放這裏 -->
  </main>
  <footer>
    <!-- 我們希望把頁腳放這裏 -->
  </footer>
</div>

它希望有三處插槽。我們可以這麼定義

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
    //或者
    <slot name="default"></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

這些帶有name的插槽,我們就叫做具名插槽。沒有帶有name的(<slot></slot>)我們稱爲匿名插槽。

父元素調用:

<base-layout>
// 會被渲染到<slot name="header"></slot>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>
// 會被渲染到<slot></slot>
  <p>A paragraph for the main content.</p>
  <p>And another one.</p>
// 會被渲染到<slot name="footer"></slot>
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

我們在一個 元素上使用 v-slot 指令,並以 v-slot 的參數的形式提供其名稱,現在 <template> 元素中的所有內容都將會被傳入相應的插槽。任何沒有被包裹在帶有 v-slot 的 中的內容都會被視爲默認插槽的內容。如果你想更清晰一點,可以給默認的插槽加上 v-slot=“default”。注意 v-slot 只能添加在一個 <template>
<template>上的插槽名稱也可以是動態的。如:dynamicSlotName的值可以改變。

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>

具名插槽的縮寫: v-slot 也有縮寫,即把參數之前的所有內容 (v-slot:) 替換爲字符 #。例如 v-slot:header 可以被重寫爲 #header。匿名插槽縮寫需要帶上default,如#default="{user}",否則#=“{user}”無效。

作用域插槽

作用域插槽是一種特殊的slot,通常情況下,插槽訪問的數據都來自於父組件,但是有時候我們需要插槽訪問子組件的數據,爲了讓 子組件數據 在父級的插槽內容中可用,我們可以將數據 作爲 元素的一個特性綁定上去。
例如:

//子組件
<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>
//父組件
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

綁定在 元素上的特性被稱爲插槽 prop( v-bind:user=“user”)。現在在父級作用域中,我們可以給 v-slot 帶一個值來定義我們提供的插槽 prop 的名字。v-slot:default="xxx"名字可以任意。當存在具名插槽時,匿名插槽.default不能去掉,否則會造成作用域不明確

解構插槽 Prop

我們可以用解構的方式接受子組件傳遞過來的參數。例如上面例子,

//父組件
<current-user>
  //<template v-slot:default="slotProps">
  <template v-slot:default="{ user }">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

子組件傳遞屬性值爲user,父組件接受時結果會包裹在一個對象中,所以在支持的環境下 (單文件組件或現代瀏覽器),我們可以直接解構出來。
prop也可以重命名,如代碼,我們將接受的user重命名爲person。

<current-user v-slot="{ user: person }">
  {{ person.firstName }}
</current-user>

prop也可以設置默認值,當prop接受的數據位undifined時取默認值。

<current-user v-slot="{ user = { firstName: 'Guest' } }">
  {{ user.firstName }}
</current-user>

user設置默認值 { firstName: ‘Guest’ }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章