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’ }

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