>  기사  >  웹 프론트엔드  >  Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해

Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해

青灯夜游
青灯夜游앞으로
2022-10-12 19:43:322078검색

이 기사는 Vue의 고급 기술과 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해를 여러분과 공유할 것입니다. 모든 사람에게 도움이 되기를 바랍니다.

Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해

슬롯 소개

Vue의 구성 요소 데이터는 props를 통해 전달되거나 이벤트를 통해 획득 및 전달될 수 있지만 템플릿 콘텐츠(법적 템플릿 콘텐츠, 코드 조각, Vue)를 받아야 하는 경우 구성 요소)를 구현하려면 슬롯을 사용해야 합니다. 물론 함수형 프로그래밍을 통해 간접적으로 달성할 수도 있습니다. [관련 권장 사항:
vuejs 비디오 튜토리얼

]

Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해

컴파일을 위해 슬롯을 js의 함수로 이해할 수 있습니다
  • // 父元素传入插槽内容
    FancyButton('Click me!')
    
    // FancyButton 在自己的模板中渲染插槽内容
    function FancyButton(slotContent) {
        return `<button>
          ${slotContent}
        </button>`
    }
가장 좋은 방법입니다. 캡슐화하는 것은 공통성을 구성 요소로 추출하고 차이점을 슬롯으로 노출하는 것입니다. - 공통성 추출, 차이점 유지
  • 상위 구성 요소 템플릿의 모든 항목은 상위 구성 요소 범위에서 컴파일되고 하위 구성 요소 템플릿의 모든 항목은 하위 구성 요소 범위에서 컴파일됩니다. 컴파일 범위
슬롯 범위에 대한 간략한 분석

기존 슬롯은 컴포넌트 템플릿을 사용자 정의하는 데 사용할 수 있지만 고정된 템플릿으로만 제한되며 특정 내부 항목, 즉 기존 슬롯을 사용자 정의할 수 없습니다. 구성요소 루프의 각 항목에 대해 서로 다른 콘텐츠 배포를 달성할 수 있습니다. 이는 슬롯 범위를 통해 달성할 수 있습니다. 차이점은 매개변수를 전달할 수 있다는 점입니다

//普通的组件定义
        
  •     {{ book.name }}     
//slot-scope组件定义
        
  •                                   {{ book.name }}              
//父组件使用     
상위 구성 요소가 이 API를 사용하면 해당 슬롯이 표시용 템플릿의 슬롯을 대체합니다

공통 API에 대한 간략한 분석

이름이 지정된 슬롯
구성 요소에서 여러 슬롯 종료를 정의할 수 있습니다. 호환 가능 여러 요구 사항이 있으므로 name 속성이 슬롯에 구성되면 여러 슬롯의 콘텐츠가 해당 슬롯 종료로 전달될 수 있습니다. 슬롯은 명명된 슬롯(named Slots)이라고 합니다. 이름은 암시적으로 "default"로 지정됩니다

name属性时,此插槽就被称为具名插槽(named slots),没有提供name的插槽会隐式命名为「default」

Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해

  • v-slot 可以简写为#,其值对应于插槽中的name对应的值;
  • 当在一个组件中同时存在默认插槽和具名插槽时,所有位于顶级的非template节点都被隐式的视为默认插槽的内容,因此可以省略默认插槽的template节点标签;
<com>
    <!-- 隐式的默认插槽 -->
    <!-- <p>A paragraph for the main content.</p>
    <p>And another one.</p> -->
    <template>
        <p>A paragraph for the main content.</p>
        <p>And another one.</p>
    </template>
    <template>
        <p>Here's some contact info</p>
    </template>
</com>
作用域插槽

普通的插槽,是无法获取其他作用域下的数据的,即父组件模板中的表达式只能访问父组件的作用域;子组件模板中的表达式只能访问子组件的作用域
但在某些情况下,插槽中的内容想要同时使用父组件和子组件内的数据,可以通过像组件传递数据props那样,让子组件在渲染时将一部分数据提供给插槽,这样在组件外部(父组件)中就可以使用子组件中的数据了-通过slot的方式

子组件传入插槽的 props 作为了 v-slot 指令的值,可以在插槽内的表达式中访问,其中name是Vue特意保留的attribute,不会作为props进行传递

  • 数据传递
//子组件
<template> 
    <slot></slot> 
</template>
  • 数据接收
    • 默认插槽接收
    //父组件 - 使用方
    <mycom>
      {{ shopInfo }} {{ userInfo }}
    </mycom>
    • 具名插槽接收
    <mycom>
      <template>
        {{ shopInfo }}
      </template>
    
      <template>
        {{ introduction }}
      </template>
    
      <template>
        {{ userInfo }}
      </template>
    </mycom>
  • 使用slot-scope时,用最后一个slot-scope替换模板中的slot
<cpm>
    <!-- 不显示 -->
    <div>555</div>
    <!-- 不显示 -->
    <div>
        <div>{{scope.name}}</div>
    </div>
    <!-- 显示 -->
    <div>
        <div>{{scope}}</div>
        <div>{{scope.name}}</div>
        <div>{{scope.age}}</div>
    </div>
</cpm>
  • 使用作用域插槽时,可以实现既可以复用子组件slot,又可以使得slot的内容不一致,它允许使用者传递一个模板而不是已经渲染好的元素给插槽,所谓作用域是指模板虽然在父级作用域中渲染的,但是却可以拿到子组件的数据
  • 常规的v-bind需要携带参数key值进行传递,例如v-bind:info = '123';但是有时候会省略这个key值,直接进行传递数据,如v-bind = 'item'Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해
v-slot#로 축약할 수 있으며, 그 값은 슬롯에 해당하는 값입니다. name에 해당하는 값입니다. code>;구성 요소에 기본 슬롯과 명명된 슬롯이 모두 있는 경우 모든 최상위 비템플릿 노드는 암시적으로 기본 슬롯의 콘텐츠로 간주되므로 template 기본 슬롯의 노드 라벨은 생략 가능합니다.
// data: {
//     shapes: [
//         { name: 'Square', sides: 4 },
//         { name: 'Hexagon', sides: 6 },
//         { name: 'Triangle', sides: 3 }
//     ],
//     colors: [
//         { name: 'Yellow', hex: '#F4D03F', },
//         { name: 'Green', hex: '#229954' },
//         { name: 'Purple', hex: '#9B59B6' }
//     ]
// }
<my-list>
    <template>
        <div>{{ shape.name }} <small>({{ shape.sides }} sides)</small>
</div>
    </template>
</my-list>
<my-list>
    <template>
        <div>
            <div></div>
            {{ color.name }}
        </div>
    </template>
</my-list>
<div>
    <div>{{ title }}</div>
    <div>
        <div>
            <slot></slot>
        </div>
    </div>
</div>


Vue.component('my-list', {
    template: '#my-list',
    props: [ 'title', 'items' ]
});

scope Slot

🎜🎜 🎜일반 슬롯은 다른 범위, 즉 표현식의 데이터를 얻을 수 없습니다. 상위 구성 요소 템플릿에서는 상위 구성 요소의 범위에만 액세스할 수 있습니다. 하위 구성 요소 템플릿의 표현식은 하위 구성 요소의 범위에만 액세스할 수 있습니다.
그러나 경우에 따라 콘텐츠는 슬롯에서 상위 구성 요소와 하위 구성 요소 모두의 데이터를 사용하려고 하면 구성 요소와 같은 데이터 props를 전달할 수 있습니다. 하위 구성 요소가 렌더링할 때 데이터의 일부를 슬롯에 제공하도록 합니다. 하위 구성 요소의 데이터를 구성 요소(상위 구성 요소) 외부에서 사용할 수 있도록 - slot🎜🎜🎜🎜sub-comComponent 메서드를 통해 슬롯에 전달된 props는 다음의 값으로 사용됩니다. v-slot 지시문을 사용하며 슬롯의 표현식에서 액세스할 수 있습니다. Name은 Vue에서 특별히 예약한 속성이며 props🎜🎜 🎜🎜데이터 전달🎜🎜
<template>
    <div>
        <my-component></my-component>
    </div>
</template>
<script>
export default {
    name:&#39;my-component&#39;,
    props: {
        count: {
            type: Number,
            default: 1
        }
    }
}
</script>
🎜🎜Data로 전달되지 않습니다. received🎜🎜기본 슬롯 수신🎜🎜
<component></component>
//component 就是js import进的组件实例,其值可以是标签名、组件名、直接绑定一个对象等
🎜🎜명명된 슬롯 수신🎜🎜
<div>
    <cpn></cpn>
</div>
<template>
    <div>
        <h2>Lbxin</h2>
        <p>class - 11</p>
    </div>
</template>
<script>
var app = new Vue({
    el: &#39;#app&#39;,
    data: {
        isShow: true
    },
    components: {
        cpn: {
            template: &#39;#com&#39;,
            data() {
                isShow: false
            }
        }
    }
})
</script>
🎜🎜slot-scope 사용 시 템플릿의 슬롯을 마지막 슬롯 범위로 교체하세요🎜🎜
<template>
  <p>My paragraph</p>
</template>
🎜🎜scope 슬롯 사용 시 다음을 수행할 수 있습니다. 하위 구성 요소 슬롯을 재사용하고 슬롯의 내용을 일관되지 않게 만듭니다. 이를 통해 사용자는 이미 렌더링된 요소 대신 템플릿을 슬롯에 전달할 수 있습니다. 이는 템플릿이 상위 요소에서 렌더링되지만 이를 의미합니다. 범위에 따라 하위 구성 요소의 데이터를 얻을 수 있습니다. 일반 v-bind는 v-bind:info = '123'와 같은 전송을 위해 매개변수 키 값을 전달해야 합니다. <code>v-bind = 'item'과 같이 생략되고 데이터가 직접 전송됩니다. 이 사용법은 전체 개체의 모든 속성을 현재 요소에 바인딩합니다. 속성이 너무 많은 시나리오에 적합합니다. 바인딩해야 하는 것🎜🎜
let template = document.getElementById('my-paragraph');
let templateContent = template.content;
document.body.appendChild(templateContent);
🎜🎜Recursive 컴포넌트🎜🎜🎜🎜Recursive 컴포넌트는 컴포넌트 자체에서 호출되기 때문에 일반 컴포넌트처럼 정의할 수 없습니다. 구성 요소의 재귀는 자체 이름 구성에 따라 달라집니다(이름은 구성 요소의 인스턴스를 찾기 위해 구성 요소의 이름 옵션을 탐색하는 데에도 사용됩니다).
  • 满足条件
    • 需要给组件设置一个name属性
    • 需要有一个明确的结束条件
<template>
    <div>
        <my-component></my-component>
    </div>
</template>
<script>
export default {
    name:&#39;my-component&#39;,
    props: {
        count: {
            type: Number,
            default: 1
        }
    }
}
</script>
动态组件

有时候我们需要根据一些条件,动态的切换/选择某个组件,在函数式组件中,没有上下文的概念,常用于程序化的在多个组件中选择一个,可以间接的解决动态切换组件的需求,缺点是基于js对象进行开发,不方便开发;
Vue官方提供了一个内置组件<component></component>和is的属性,用来解决上述的问题

<component></component>
//component 就是js import进的组件实例,其值可以是标签名、组件名、直接绑定一个对象等
  • 为了使得组件具有缓存作用,可以使用的内置组件,这样只要不离开当前页面,切换到其他组件后deforeDestory不会执行,因此组件具有了缓存功能

拓展

components的第二种写法

常规的组件components是直接通过引用定义好的组件进行展示的,也可以直接在当前组件内定义,然后通过配置components进行渲染

<div>
    <cpn></cpn>
</div>
<template>
    <div>
        <h2>Lbxin</h2>
        <p>class - 11</p>
    </div>
</template>
<script>
var app = new Vue({
    el: &#39;#app&#39;,
    data: {
        isShow: true
    },
    components: {
        cpn: {
            template: &#39;#com&#39;,
            data() {
                isShow: false
            }
        }
    }
})
</script>

Web Component <slot></slot> 简介

HTML的slot元素,是Web Components技术套件的一部分,是Web组件内的一个占位符,该占位符可以在后期使用自己的标记语言进行填充,这样可以创建单独的DOM树,并将其与其他的组件组合在一起 -- MDN

常见的填充Web组件的shadow DOM的模板有template和slot

  • 模板 - Templates

    • 需要在网页上重复的使用相同的标记结构时,为了避免CV的操作可以通过模板的方式进行实现
    • 需要注意的是模板 - Template 和其内部的内容是不会在DOM中呈现的,可以通过js进行访问并添加到DOM中,从而在界面上进行展示
    <template>
      <p>My paragraph</p>
    </template>
    let template = document.getElementById('my-paragraph');
    let templateContent = template.content;
    document.body.appendChild(templateContent);
    • 可以配合Web Component一起使用,实现纯js自定义的组件
    customElements.define('my-paragraph',
      class extends HTMLElement {
        constructor() {
          super();
          let template = document.getElementById('my-paragraph');
          let templateContent = template.content;
    
          const shadowRoot = this.attachShadow({mode: 'open'})
            .appendChild(templateContent.cloneNode(true));
      }
    })
    
    // 自定义标签使用
    <my-paragraph></my-paragraph>
    • 后续的样式逻辑也需要加在template中,方便通过后续的相关逻辑(如template.content获取到然后打入到指定的容器中)
  • Web Component简介

    • Web Component的一个很重要的属性就是封装 - 可以将标记结构、样式和行为影藏起来,并于界面上的其他代码隔离开来,保证代码的独立性

    • Web Component标准非常重要的一个特性是,使得开发者可以将HTML页面的功能封住成custom elements(自定义标签)

    • customElements 接口用来实现一个对象,允许开发者注册一个custom elements的信息,返回已注册的自定义标签的信息;

    • customElements.define方法用来注册一个custom element,接收三个参数

      • 参数一:表明创建元素的名称,其注册的名称不能简单的单词,需要由短划线进行拼接

      • 参数二:用于定义元素行为的类

      • 参数三:一个包含extends属性配置的配置对象,可选,指定了所创建的自定义元素是继承于哪个内置的元素,可以继承任何内置的元素;

        customElements.define(
            'word-count', 
            WordCount, 
            { extends: 'p' }
        );

        可以使用ES2015的类实现

        class WordCount extends HTMLParagraphElement {
          constructor() {
            // 必须首先调用 super 方法
            super();
            // 元素的功能代码写在这里
            ...
          }
        }
    • 自定义标签的类型

      • 类型一:Autonomous custom elements 是独立的元素,它不继承其他内建的 HTML 元素,可以直接通过标签的方式进行HTML使用<popup-info></popup-info>,也可以通过js的方式进行使用document.createElement("popup-info")
      • 类型二:Customized built-in elements 继承自基本的 HTML 元素。在创建时,你必须指定所需扩展的元素,使用时,需要先写出基本的元素标签,并通过 is属性指定 custom element 的名称;<p is="word-count"></p>document.createElement("p", { is: "word-count" })

      参考文献 - MDN

  • shadow DOM简介

    • 图解Shandow DOM

    Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해

    • Shadow host:一个常规 DOM 节点,Shadow DOM 会被附加到这个节点上。

    • Shadow tree:Shadow DOM 内部的 DOM 树。

    • Shadow boundary:Shadow DOM 结束的地方,也是常规 DOM 开始的地方。

    • Shadow root: Shadow tree 的根节点。

    shadow DOM主要是将一个隐藏的、独立的DOM树附加到常规的DOM树上,是以shadow DOM节点为起始根节点,在这个根节点的下方,可以是任意的元素,和普通的DOM元素一致

如常见的video标签,其内部的一些控制器和按钮等都是通过Shandow DOM进行维护的,开发者可以通过这个API进行自己独立的逻辑控制

  • 基本用法

    • Element.attachShadow()方法可以将一个shadow DOM添加到任何一个元素上,接收一个配置对象参数,该对象有一个mode的属性,值可以是open - 可以通过外部js获取 Shadow DOM和closed - 外部不可以通过js进行获取 Shadow DOM
    let shadow1 = elementRef.attachShadow({mode: 'open'});
    let shadow2 = elementRef.attachShadow({mode: 'closed'});
    let myShadowDom = shadow1.shadowRoot; // 具体内容
    let myShadowDom = shadow2.shadowRoot; //null
    • 当需要将一个shadow DOM添加到自定义的标签上时,可以在自定义的构造函数中添加如下逻辑;
    let shadow = this.attachShadow({mode: 'open'});
    // 将一个shadow DOM添加到一个元素上之后就可以使用DOM API进行操作访问了

(学习视频分享:web前端开发编程基础视频

위 내용은 Vue의 슬롯, 콘텐츠 배포 및 명명된 슬롯에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제