Vue学习笔记之11-slot插槽

slot插槽

  • 为什么要使用slot插槽

    • 组件的插槽是为了让我们封装的组件更加具有扩展性
    • 让使用者可以灵活地决定组件内部的内容到底展示什么
    • 网页和网页间每一个组件有很多的区别, 也有很多共性, 如果我们为每一个网页都去单独地封装一个组件是不合适的, 所以我们需要slot插槽
  • 如何封装一个灵活的组件

    • 将共性(相同的地方)抽取放到组件中, 将不同的地方暴露为插槽
    • 预留了插槽, 就可以让使用者根据自己的需求, 决定插槽内的内容
  • slot的基本使用

    • 在子组件中, 用特殊的元素标签slot就可以为子组件创建一个插槽
    • 插槽中插入的内容是什么由父组件来决定
  • slot的注意点

    • slot的默认值, 在父组件中没有写入要插入的内容的话, 就会默认显示slot的默认值
    • 如果父组件中一次性插入多个元素, 那么所有的元素都会进行替换
<body>
  <div id="app">
    <!-- 在组件的标签中填入要替换slot占位的元素 -->
    <cpn><button>按钮</button></cpn>
    <cpn><span>我是span</span></cpn>
    <!-- 如果一次性填入多个替换的元素, 所有的替换元素都会进行替换 -->
    <cpn>
      <i>我是i</i>
      <p>我是替换的p</p>
      <span>我是替换的span</span>
    </cpn>

    <!-- 如果标签内没有填入要替换的slot占位的元素, slot会使用默认的元素替换 -->
    <cpn></cpn>
    <cpn></cpn>
    <cpn></cpn>
  </div>

  <template id="cpn">
    <div>
      <h2>我是h2</h2>
      <p>我是p</p>
      <!-- 在组件中使用solt标签占位 -->
      <!-- 在slot标签中填入默认的元素, 默认元素会在子组件标签没有填入替换的元素的时候显示出来 -->
      <slot><button>我是默认的按钮</button></slot>
    </div>
  </template>

  <script>
    const app = new Vue({
      el: "#app",
      components: {
        cpn: {
          template: "#cpn"
        }
      }
    })
  </script>
</body>

具名slot的使用

  • 当子组件的功能复杂时, 子组件的插槽可能由很多个, 那么在父组件中给插槽插入内容的时候, 如何区分插入的是哪一个插槽呢?
    • 此时需要给插槽起一个名字, 添加一个name属性
    • 然后在插入的元素中添加slot属性, 值为需要替换的插槽的name值
<body>
  <div id="app">
    <!-- 使用子组件的时候, 给需要替换的添加slot属性, 值为需要替换的slot标签的name值, 即可定向替换元素 -->
    <cpn><button slot="center">替换中间的</button></cpn>
  </div>

  <template id="cpn">
    <div>
      <!-- 给插槽标签添加name属性 -->
      <slot name="left"><span>左边</span></slot>
      <slot name="center"><span>中间</span></slot>
      <slot name="right"><span>右边</span></slot>
    </div>
  </template>
  <script>
    const app = new Vue({
      el: "#app",
      components: {
        cpn: {
          template: "#cpn"
        }
      }
    })
  </script>
</body>

编译的作用域

  • 在组件模板中使用的所用东西, 来自该组件
  • 官方的准则: 父组件模板的所有东西都会在父级作用域内编译, 子级组件模板的所有东西都会在子级作用域内编译
<body>
  <div id="app">
    <!-- 在这里使用的isShow数据是来自根组件的,因为这里是app根组件 -->
    <cpn v-show="isShow"></cpn>
  </div>

  <template id="cpn">
    <div>
      <!-- 在这里使用的isShow数据是来自cpn组件的, 因为这里是cpn子组件 -->
      <h2>我是标题</h2>
      <p>我是内容</p>
      <span v-show="isShow">我是span</span>
    </div>
  </template>
  <script>
    const app = new Vue({
      el: "#app",
      data: {
        isShow: true
      },
      components: {
        cpn: {
          template: "#cpn",
          data() {
            return {
              isShow: false
            }
          }
        }
      }
    })
  </script>
</body>

作用域插槽的使用

  • 总结起来就是一句话, 父组件替换插槽的标签, 但是内容由子组件来提供
  • 就是父组件来决定如何渲染子组件的内容
  • 如何使用作用域插槽
    • 子组件模板中, 通过给slot标签添加v-bind:自定义名称=“想要暴露的数据” 属性来发送子组件的数据
    • 在父组件中的子组件标签中嵌套一个一个template标签(Vue2.5.x以后可以使用其他的标签比如div等)
    • 在这个template标签中添加 slot-scope=“也是自定义的名字” 来接收slot标签发送的数据
    • 在template标签内就可以使用子组件发送来的数据了
<body>
  <div id="app">
    <!-- 默认是按照子组件模板中设定的模板渲染 -->
    <cpn></cpn>

    <!-- 如果想在父组件中其他的形式展示子组件的内容, 就要使用作用域插槽 -->
    <cpn>
      <!-- 在子组件标签中嵌套一个template标签(Vue2.5.x以后可以使用其他的标签比如div等) -->
      <!-- 在该标签中添加 slot-scope="也是自定义的名字" 来接收slot标签发送的数据 -->
      <template slot-scope="acceptdata">
        <!-- 在这个标签内就可以使用子组件发送来的数据了 -->
        <!-- <span v-for="item in acceptdata.cpndata"> {{item}} - </span> -->
        <span>{{acceptdata.cpndata.join(" - ")}}</span>
      </template>
    </cpn>
  </div>

  <template id="cpn">
    <div>
      <!-- 通过slot标签中添加 v-bind:自定义名称="想要暴露的数据" 属性来发送子组件的数据 -->
      <slot :cpndata="pLanguages">
        <ul>
          <li v-for="item in pLanguages">{{item}}</li>
        </ul>
      </slot>
    </div>
  </template>
  <script>
    const app = new Vue({
      el: "#app",
      components: {
        cpn: {
          template: "#cpn",
          data() {
            return {
              pLanguages: ["JavaScript", "C++", "C#", "python"]
            }
          }
        }
      }
    })
  </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值