Vue2.js——插槽

一、插槽

在2.6.0中,具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。

1.插槽内容:

它允许你像这样合成组件(组件已经注册过):

<navigation-link url="/profile">
  Your Profile
</navigation-link>

然后,你可以在 navigation-link 组件的template中使用插槽:

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a

当组件渲染的时候,将会被替换成 'Your Profile'插槽内可以包含任何模板代码,包括html

<navigation-link url="/profile">
  <!-- 添加一个 Font Awesome 图标 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>

甚至可以在插槽内放置其他的组件:

<navigation-link url="/profile">
  <!-- 添加一个 关于用户界面的组件 -->
  <User></User>
  Your Profile
</navigation-link>

注意:如果 template 中没有包含一个 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃

2.编译作用域

如果你想在一个插槽中使用数据:

<navigation-link url="/profile">
  Logged in as {{ user.name }}
</navigation-link>

该插槽跟模板的其他地方一样可以访问相同实例的属性(也就是相同的’作用域’),但不能访问 的作用域,

例如下面的url是访问不到的:

<navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
</navigation-link>

这里的 url 会是 undefined,因为其 (指该插槽的) 内容是
传递给 而不是
组件内部定义的。

关于 编译作用域:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>编译作用域title>
head>
<body>
    <div id="app">
        
        <cpn v-show="isShow">{{message}}cpn>
    div>
    
    
    <template id="cpn">
        <div>
            <h2>我是子组件cpnh2>
            <p>我是内容156165p>
            <slot>slot>
            <h2>-------------以下是组件ccpn的内容:-------------h2>
            <ccpn>{{message}}ccpn>
        div>
        
    template>
    
    <template id="ccpn">
        <div>
            <h2>我是子组件cpn的子组件ccpnh2>
            <p>我是内容156165p>
            <slot>slot>
        div>
    template>
    <script src="../JS/vue.js">script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                message: '我是app中的message',
                isShow: true
            },
            components:{
                cpn:{
                    template:'#cpn',
                    data(){
                        return {
                            isShow: false,
                            message: '我是cpn组件中的message'
                        }
                    },
                    components: {
                        ccpn: {
                            template: '#ccpn',
                            data() {
                                return {
                                    message: '我是ccpn组件的message'
                                }
                            }
                        }
                    }
                }
            }
    })
    script>
body>
html>

运行效果:
Vue2.js——插槽_第1张图片
作为一条重要的规则:

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

3.后备内容:

有时候我们需要为一个插槽指定具体的后备内容(也就是默认内容),它只会在没有提供内容的时候被渲染。
例如在一个 组件中:

<button type="submit">
  <slot>Submitslot>
button>

我们给这个插槽指定了后备内容,那么当:

//会渲染出Submit
<submit-button>submit-button>
//渲染出Save
<submit-button>
  Save
submit-button>
4.具名插槽:

有时我们需要多个插槽。例如对于一个带有如下模板的 组件:

<div class="container">
  <header>
    
  header>
  <main>
    
  main>
  <footer>
    
  footer>
div>

对于这样的情况, 元素有一个特殊的 attribute:name。这个 attribute 可以用来定义额外的插槽:

<div class="container">
  <header>
    <slot name="header">slot>
  header>
  <main>
    <slot>slot>
  main>
  <footer>
    <slot name="footer">slot>
  footer>
div>

一个不带 name 出口会带有隐含的名字“default”。

在向具名插槽提供内容的时候,我们可以在一个