组件(4):使用slot进行内容分发

组件的作用域(一)

父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

父子组件的编译相互独立,编译时只能使用各自作用域中的属性和方法,例如,你不可以在父组件模板内,将一个指令绑定到子组件的属性或方法上。如果这么做控制台会报一个属性未定义的错误。

如果想要绑定一个指令以便控制子组件的行为,那么你可以在子组件的模板内,将一个指令绑定到子组件的属性或方法上;或者在父组件的模板内,将指令绑定到父组件的属性或方法上。

new Vue({
    el: ‘#app-2‘,
    data: {
        makeChildShow: true
    },
    components: {
        "component-2-1": {
            template: ‘<span>I am an sub component.</span>‘,
            data: function () {
                return {
                    childIsShow: true
                }
            }
        },
        "component-2-2": {
            template: ‘<span v-show="childIsShow">I am an sub component.</span>‘,
            data: function () {
                return {
                    childIsShow: true
                }
            }
        }
    }
})
<div id="app-2">
  <ul>
    <li>绑定到子组件属性:<component-2-1 v-show="childIsShow"></component-2-1></li>
    <li>绑定到父组件属性:<component-2-1 v-show="makeChildShow"></component-2-1></li>
    <li>在子组件模板内将指令绑定到子组件属性:<component-2-2></component-2-2></li>
  </ul>
</div>

列表第一项,由于父组件找不到属性childIsShow,将不会显示。

默认情况下的内容分发

将父组件的内容插入子组件模板的方式,我们称为内容分发
默认情况下,在子组件中插入的父组件内容是不显示的。

new Vue({
    el: ‘#app-1‘,
    data: { message: ‘I come from parent.‘ },
    components: {
        "component-1": {
            template: ‘<p>I am an sub component.</p>‘,
        }
    }
})
<div id="app-1" class="demo">
  <component-1>
    {{ message }}
  </component-1>
</div>

内容分发失败,message不会显示。

单个插口

如果想使用内容分发,将父组件内容插入到子组件的模板中,必须在子组件的模板内标记一个<slot>备选内容</slot>,父组件将找到这个<slot>备选内容</slot>标记,并将自己的内容替换<slot>备选内容</slot>
如果父组件没有待分发的内容,备选内容成为最终渲染的结果。

new Vue({
    el: ‘#app-3‘,
    components: {
        "component-3": {
            template: ‘            <ul>                <li>子组件内容</li>                <li>子组件内容</li>                <slot><li>插口备选内容</li></slot>                <li>子组件内容</li>                <li>子组件内容</li>            </ul>‘
        }
    }
})
<div id="app-3">
  <h5>父组件标题</h5>
  <component-3>
    <li>父组件插入内容</li>
  </component-3>
</div>

具名插口(多个插口)

单插口模式做内容分发,只能一股脑把套入子模板的内容插入到有<slot></slot>标记的地方。
而具名插口在内容和slot上都做上标记,对应的内容只能分发到对应的slot上。
标记内容用slot="tag"; 标记slot<slot name="tag">

new Vue({
    el: ‘#app-4‘,
    components: {
        "component-4": {
            template: ‘            <div>                <header>                    <slot name="header"></slot>                </header>                <article>                    <slot></slot>                </article>                <footer>                    <slot name="footer"></slot>                </footer>                <section><slot></slot></section>            </div>‘
        }
    }
})
<div id="app-4">
  <component-4>
    <h5 slot="header">我来组成头部</h5>
    <p>没被标记的slot都我插</p>
    <div slot="footer">我来组成腿部</div>
  </component-4>
</div>

以上定义了两个个不具名的插口,虽然这里显示正确,但是控制台报错,说定义重复的默认插口会有不预期的错误

组件作用域(二)

根据具名插口,再来看个组件作用域的例子

new Vue({
    el: ‘#app-7‘,
    methods: {
        parentMethod: function () {
            console.log("It is the parent‘s method");
        }
    },
    components:{
        "component-7":{
            methods:{
                childMethod: function(){
                    console.log("It is the child‘s method")
                }
            },
            template:"                <button>                    <slot name=‘first‘></slot>                    <span @click=‘childMethod‘>子组件模板定义部分①|</span>                    <slot name=‘second‘></slot>                    <span @click=‘childMethod‘>子组件模板定义部分②</span>                </button>"
        }
    }
})
<div id="app-7">
  <component-7>
      <span slot="first" @click="parentMethod">内容分发部分①|</span>
      <span slot="second" @click="parentMethod">内容分发部分②|</span>
  </component-7>
</div>


内容分发部分属于父组件作用域,因此点击按钮的内容分发部分,会调用父组件方法,输出"It is the parent‘s method"
子组件模板定义属于子组件作用域,点击这个部分,会调用子组件方法,输出"It is the child‘s method"

插口作用域

在内容分发的过程中,父组件分发的内容可以使用定义在子组件模板<slot>上的属性(即插口作用域上定义的属性)。如<slot slotval="值"></slot>,在父组件分发内容上,可以通过slot-scope="obj"获取到所有在插口上定义的属性,通过{{obj.slotval}}就可以在slot-scope内部使用这个数据。
特殊的,在<template>标签中使用slot-scope<template>自身是不会在页面上显示,只起到传递数据媒介的作用。

new Vue({
    el: ‘#app-5‘,
    components: {
        "component-5":{
            template: ‘<div class="child">                <slot slotvala="a、来自插口作用域上的数据" slotvalb="b、来自插口作用域上的数据"></slot>                </div>‘
        }
    }
})
<div id="app-5">
  <component-5>
    <!--这里可以是其他标签,但会被渲染到页面,如<div slot-scope="">-->
    <template slot-scope="slot_data_obj">
      <span>{{slot_data_obj.slotvala}}</span>
      <span>{{slot_data_obj.slotvalb}}</span>
    </template>
  </component-5>
</div>

由于slot-scope的值本质上只是个javascript对象,因此可以使用es6的解构语法进行<slot>属性的映射。
以上又可以怎么写

<template slot-scope="{slotvala,slotvalb}">
  <span>{{slotvala}}</span>
  <span>{{slotvalb}}</span>
</template>

插口作用域应用在列表上

插口不仅可以通过自身属性传递数据给分发的内容,还可以在其上定义v-for指令,从而将迭代的特性也传递给分发的内容。

new Vue({
    el: ‘#app-6‘,
    components: {
        "component-6":{
            data:function(){
                return {
                    items: [
                        {id:1,text:"哪都通快递"},
                        {id:2,text:"龙虎山天师府"},
                        {id:3,text:"曜星社"}
                    ]
                }
            },
            template: ‘            <ul>                <slot name="item" v-for="item in items" v-bind:text="item.text" v-bind:id="item.id"></slot>            </ul>‘
        }
    }
})
<div id="app-6">
  <component-6>
    <li slot="item" slot-scope="{text,id}">
      {{ id+"、"+text }}
    </li>
  </component-6>
</div>

内容分发中的<li>被插入slot中,并且因为slot中的v-for指令而进行迭代,迭代之后通过slot-scope获取slot上的属性数据。

内联模板

当使用子组件的内联特性——inline-template时,父组件的内容分发部分就被解释为子组件的模板,而子组件的template属性也将被这个部分取代(取代后template失效),并且作用域也属于子组件。

new Vue({
    el:‘#app-8‘,
    components:{
        ‘component-8‘:{
            template:‘...‘//全部被替换
            data:function(){
                return {
                    childMsg:‘child\‘s data‘
                }
            }

        }
    }
})
<div id="app-8">
    <component-8 inline-template>
        <div>
            <p>这些将作为组件自身的模板。</p>
            <p>而非父组件透传进来的内容。</p>
            <p>子组件数据: {{ childMsg }}</p>
        </div>
    </component-8>
</div>

"child‘s data"来自子组件的childMsg

由于其特点,在使用内联模板时,最容易产生的误区就是混淆作用域。

原文地址:https://www.cnblogs.com/baimeishaoxia/p/11970616.html

时间: 2024-08-06 14:32:32

组件(4):使用slot进行内容分发的相关文章

Vue学习笔记入门篇——组件的内容分发(slot)

本文为转载,原文:Vue学习笔记入门篇--组件的内容分发(slot) 介绍 为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板.这个过程被称为 内容分发 (或 "transclusion" 如果你熟悉 Angular).Vue.js 实现了一个内容分发 API,使用特殊的 'slot' 元素作为原始内容的插槽. 编译作用域 在深入内容分发 API 之前,我们先明确内容在哪个作用域里编译.假定模板为: <child-component> {{ messa

Vue内容分发slot

前面的话 为了让组件可以组合,需要一种方式来混合父组件的内容与子组件自己的模板.这个过程被称为 内容分发 (或 “transclusion” ).Vue实现了一个内容分发 API,参照了当前 Web 组件规范草案,使用特殊的 <slot> 元素作为原始内容的插槽.本文将详细介绍Vue内容分发slot 编译作用域 在深入内容分发 API 之前,先明确内容在哪个作用域里编译.假定模板为 <child-component> {{ message }} </child-compone

slot内容分发

slot 内容分发:为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板. 比如我们遇到组件需要相互嵌套这样的情况: App.vue 文件 <template> <div class="app"> <Hello> <World></World> <Vue></Vue> </Hello> </div> </template> Hello.vue 文件

Vue一个案例引发「内容分发slot」的最全总结

今天我们继续来说说 Vue,目前一直在自学 Vue 然后也开始做一个项目实战,我一直认为在实战中去发现问题然后解决问题的学习方式是最好的,所以我在学习一些 Vue 的理论之后,就开始自己利用业余时间做了一个项目,然后通过项目中的一些案例进行总结. 今天我们来说说 Vue 中的内容分发 <slot>,首先 Vue 实现了一套内容分发的 API,这套 API 是基于当前的 Web Components 规范草案,将 <slot> 元素作为承载内分发内容的出口,内容分发是 Vue 中一个

slot内容分发的使用

一.定义了一个组件custom,该组件本身已经具备template模板了,直接调用<custom></custom>即可渲染模板 <div id="app"> <custom></custom> </div> <script> Vue.component('custom',{ template:` <div class="customStyle"> <p>cu

Vue:Axios异步通信、计算属性、内容分发、自定义事件

1. Axios 什么是Axios Axios 是一个开源的可以用在浏览器端和 NodeJS 的异步通信框架,她的主要作用就是实现 AJAX 异步通信,其功能特点如下: 从浏览器中创建 XMLHttpRequests 从 node.js 创建 http 请求 支持 Promise API [JS中链式编程] 拦截请求和响应 转换请求数据和响应数据 取消请求 自动转换 JSON 数据 客户端支持防御 XSRF(跨站请求伪造) GitHub:https://github.com/axios/axio

CDN(内容分发网络)技术原理

原文转自:http://kb.cnblogs.com/page/121664/ 1. 前言 Internet的高速发展,给人们的工作和生活带来了极大的便利,对Internet的服务品质和访问速度要求越来越高,虽然带宽不断增加,用户数量也在不断增加,受Web服务器的负荷和传输距离等因数的影响,响应速度慢还是经常抱怨和困扰.解决方案就是在网络传输上利用缓存技术使得Web服务数据流能就近访问,是优化网络数据传输非常有效的技术,从而获得高速的体验和品质保证. 网络缓存技术,其目的就是减少网络中冗余数据的

CDN 内容分发网络

CDN的全称是Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接.负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上.其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度. 一.

[转]CDN(内容分发网络)技术原理

1. 前言 Internet的高速发展,给人们的工作和生活带来了极大的便利,对Internet的服务品质和访问速度要求越来越高,虽然带宽不断增加, 用户数量也在不断增加,受Web服务器的负荷和传输距离等因数的影响,响应速度慢还是经常抱怨和困扰.解决方案就是在网络传输上利用缓存技术使得Web服 务数据流能就近访问,是优化网络数据传输非常有效的技术,从而获得高速的体验和品质保证. 网络缓存技术,其目的就是减少网络中冗余数据的重复传输,使之最小化,将广域传输转为本地或就近访问.互联网上传递的内容,大部