36、组件插槽

- 组件的最大特性就是复用性,而用好插槽能大大提高组件的可复用能力

匿名插槽

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
<!-- 这里的所有组件标签中嵌套的内容会替换掉slot  如果不传值 则使用 slot 中的默认值  --> 
    <alert-box>有bug发生</alert-box>
    <alert-box>有一个警告</alert-box>
    <alert-box></alert-box>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      组件插槽:父组件向子组件传递内容
	  当组件渲染的时候,这个 <slot> 元素将会被替换为“组件标签中嵌套的内容”。
	  插槽内可以包含任何模板代码,包括 HTML
    */
    Vue.component('alert-box', {
      template: `
        <div>
          <strong>ERROR:</strong>
          <slot>默认内容</slot>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        
      }
    });
  </script>
</body>
</html>

具名插槽

- 具有名字的插槽
- 使用 <slot> 中的 "name" 属性绑定元素

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <base-layout>
		<!-- 2、 通过slot属性来指定, 这个slot的值必须和下面slot组件得name值对应上
		如果没有匹配到 则放到匿名的插槽中   --> 
      <p slot='header'>标题信息</p>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <p slot='footer'>底部信息信息</p>
    </base-layout>

    <base-layout>
		<!-- 注意点:template临时的包裹标签最终不会渲染到页面上     -->  
      <template slot='header'>
        <p>标题信息1</p>
        <p>标题信息2</p>
      </template>
      <p>主要内容1</p>
      <p>主要内容2</p>
      <template slot='footer'>
        <p>底部信息信息1</p>
        <p>底部信息信息2</p>
      </template>
    </base-layout>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      具名插槽
	  	1、 使用 <slot> 中的 "name" 属性绑定元素 指定当前插槽的名字
  具名插槽的渲染顺序,完全取决于模板,而不是取决于父组件中元素的顺序  */
    Vue.component('base-layout', {
      template: `
        <div>
          <header>
            <slot name='header'></slot>
          </header>
          <main>
            <slot></slot>
          </main>
          <footer>
            <slot name='footer'></slot>
          </footer>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        
      }
    });
  </script>
</body>
</html>

作用域插槽用法:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<style type="text/css">
  .current {
    color: orange;
  }
</style>
<body>
  <div id="app">
	  <!--
	  	1、当我们希望li 的样式由外部使用组件的地方定义,因为可能有多种地方要使用该组件,
	  	但样式希望不一样 这个时候我们需要使用作用域插槽 
	  	
	  -->
    <fruit-list :list='list'>
		<!-- 2、 父组件中使用了<template>元素,而且包含slot-scope="slotProps",
					slotProps在这里只是临时变量   
					slot-scope是固定的,后面的参数是自己取的
					info 是组件里面slot里面定义的
				---> 
      <template slot-scope='slotProps'>
        <strong v-if='slotProps.info.id==3' class="current">{{slotProps.info.name}}</strong>
        <span v-else>{{slotProps.info.name}}</span>
      </template>
    </fruit-list>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      作用域插槽
	  3、 在子组件模板中,<slot>元素上有一个类似props传递数据给组件的写法msg="xxx",
	  ###   插槽可以提供一个默认内容,如果如果父组件没有为这个插槽提供了内容,会显示默认的内容。
	  		如果父组件为这个插槽提供了内容,则默认的内容会被替换掉
			<slot :info='item'>{{item.name}}</slot>
			
			:info 自己定义的,可以是其他值,只要父组件相slotProps.info.id对应就行
    */
    Vue.component('fruit-list', {
      props: ['list'],
      template: `
        <div>
          <li :key='item.id' v-for='item in list'>
            <slot :info='item'>{{item.name}}</slot>
          </li>
        </div>
      `
    });
    var vm = new Vue({
      el: '#app',
      data: {
        list: [{
          id: 1,
          name: 'apple'
        },{
          id: 2,
          name: 'orange'
        },{
          id: 3,
          name: 'banana'
        }]
      }
    });
  </script>
</body>
</html>

 

 

 

 

 

### Vue3 父组件插槽的用法 在 Vue3 中,父组件可以通过 `<slot>` 元素向子组件传递内容。这种机制允许父组件定义子组件内部某些部分的具体表现形式,从而实现更灵活和可扩展的设计模式。 #### 默认插槽 默认插槽是最基本的形式,它不需要任何名称或额外配置即可工作。当子组件中存在未命名的 `<slot>` 时,父组件可以直接将 HTML 或其他组件作为其内容嵌套到该位置上。 ```html <!-- 子组件 Card.vue --> <template> <div class="card"> <h4>Card Title</h4> <slot></slot> <!-- 这里是默认插槽 --> </div> </template> <script> export default { name: 'Card' } </script> ``` 父组件可以这样使用: ```html <Card> This is the content of the card. </Card> ``` 上述代码会将 “This is the content of the card.” 渲染到 `Card` 组件中的默认插槽处[^1]。 --- #### 命名插槽 为了支持更加复杂的布局需求,Vue 提供了 **命名插槽** 的功能。通过给 `<slot>` 添加名字属性 (`name`) 来区分不同的区域,并让父级能够针对这些特定的名字填充相应的内容。 以下是带有头部 (header) 和底部 (footer) 的卡片组件的例子: ```html <!-- 子组件 NamedSlotsExample.vue --> <template> <div class="container"> <header><slot name="header"></slot></header> <main><slot></slot></main> <!-- 默认插槽 --> <footer><slot name="footer">Default Footer Content</slot></footer> </div> </template> ``` 而在父组件中,则利用 `v-slot:` 指令绑定具体数据至对应的插槽之中: ```html <NamedSlotsExample> <template v-slot:header> <h2>This is a custom header.</h2> </template> <p>Main body text goes here...</p> <template v-slot:footer> <button type="button">Custom Button in Footer</button> </template> </NamedSlotsExample> ``` 这里分别设置了自定义头尾部以及主体部分内容;如果某个命名插槽没有被覆盖,默认显示设置好的备用文字【如 footer 部分】[^2]。 --- #### 作用域插槽 除了单纯传输静态结构外,有时还需要共享一些动态的数据或者方法给外部调用者——这便是所谓的作用域插槽所解决的问题所在。我们可以在 slot 上附加额外的信息并通过 props 形式暴露出去供使用者读取并处理后再呈现最终效果。 下面展示了一个列表项组件案例,其中每一行都接收来自父级传递过来的对象数组之一员作参数: ```html <!-- 子组件 ScopedSlotList.vue --> <template> <ul> <li v-for="(item, index) in items" :key="index"> <slot :text="item.text" :id="item.id"></slot> </li> </ul> </template> <script> export default { data() { return {items:[{ id:1 ,text:'Item One'},{ id:2,text:'Item Two'}]} } }; </script> ``` 接着,在实际运用场景下就可以像如下这般操作啦! ```html <ScopedSlotList> <template v-slot="{ text }"> {{ text }} </template> </ScopedSlotList> ``` 此片段表明我们将每条记录里的文本字段提取出来单独成列进行可视化输出。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值