>웹 프론트엔드 >JS 튜토리얼 >Vue 콘텐츠 배포 슬롯

Vue 콘텐츠 배포 슬롯

大家讲道理
大家讲道理원래의
2017-08-19 10:13:311792검색

앞의 말

 컴포넌트를 구성하기 위해서는 상위 컴포넌트의 컨텐츠와 하위 컴포넌트의 자체 템플릿을 혼합하는 방법이 필요합니다. 이 프로세스를 콘텐츠 배포(또는 "전환")이라고 합니다. Vue는 특수 <slot> 요소를 원시 콘텐츠용 슬롯으로 사용하여 현재 초안 웹 구성 요소 사양을 따르는 콘텐츠 배포 API를 구현합니다. 이 글에서는 Vue 콘텐츠 배포 슬롯을 자세히 소개합니다<slot> 元素作为原始内容的插槽。本文将详细介绍Vue内容分发slot

编译作用域

  在深入内容分发 API 之前,先明确内容在哪个作用域里编译。假定模板为

<child-component>
  {{ message }}
</child-component>

  message 应该绑定到父组件的数据,还是绑定到子组件的数据?答案是父组件。组件作用域简单地说是:父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译。

  一个常见错误是试图在父组件模板内将一个指令绑定到子组件的属性/方法:

<!-- 无效 -->
<child-component v-show="someChildProperty"></child-component>

  假定someChildProperty是子组件的属性,上例不会如预期工作。父组件模板不应该知道子组件的状态

  如果要绑定作用域内的指令到一个组件的根节点,应当在组件自己的模板上做:

Vue.component('child-component', {
  // 有效,因为是在正确的作用域内
  template: '<p v-show="someChildProperty">Child</p>',
  data: function () {
    return {
      someChildProperty: true
    }
  }
})

  类似地,分发内容是在父作用域内编译

 

默认丢弃

  一般地,如果子组件模板不包含<slot>插口,父组件的内容将会被丢弃

var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p>测试内容</p>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

<p id="example">
  <parent></parent></p><script src="https://unpkg.com/vue"></script><script>var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
  </p>  `,
};var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p>测试内容</p>
    </child>
  </p>  `,
  components: {    'child': childNode
  },
};// 创建根实例new Vue({
  el: '#example',
  components: {    'parent': parentNode
  }
})</script>

  如下图所示,所包含的

测试内容

被丢弃

 

匿名slot

  当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot></slot>
  </p>
  `,
};

var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p>测试内容</p>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

  如果出现多于1个的匿名slot,vue将报错

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot></slot>
    <slot></slot>
  </p>
  `,
};

【默认值】

  最初在 <slot> 标签中的任何内容都被视为备用内容,或者称为默认值。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容

  当slot存在默认值,且父元素在中没有要插入的内容时,显示默认值

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot><p>我是默认值</p></slot>
  </p>
  `,
};
var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child></child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

  当slot存在默认值,且父元素在中存在要插入的内容时,则显示设置值

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot><p>我是默认值</p></slot>
  </p>
  `,
};
var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p>我是设置值</p>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

 

具名Slot

  <slot> 元素可以用一个特殊的属性 name 来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot

컴파일 범위

콘텐츠 배포 API에 대해 자세히 알아보기 전에 먼저 콘텐츠가 어느 범위에서 컴파일되는지 명확히 하세요. 템플릿이

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot name="my-header">头部默认值</slot>
    <slot name="my-body">主体默认值</slot>
    <slot name="my-footer">尾部默认值</slot>
  </p>
  `,
};

메시지를 상위 구성 요소의 데이터에 바인딩해야 할까요, 아니면 하위 구성 요소의 데이터에 바인딩해야 할까요? 대답은 부모 구성 요소입니다. 구성 요소 범위는 간단히 말해서 상위 구성 요소 템플릿의 콘텐츠가 상위 구성 요소 범위에서 컴파일되고 하위 구성 요소 템플릿의 콘텐츠가 하위 구성 요소 범위에서 컴파일된다는 의미입니다.

  일반적인 실수는 상위 구성 요소 템플릿 내에서 하위 구성 요소의 속성/메서드에 지시문을 바인딩하려고 하는 것입니다.

var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p slot="my-header">我是头部</p>
      <p slot="my-footer">我是尾部</p>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

  someChildProperty가 하위 구성 요소의 속성이라고 가정하면, 위의 예는 예상대로 작동하지 않습니다. 상위 구성 요소 템플릿은 하위 구성 요소의 상태를 알 수 없습니다.

범위가 지정된 지시문을 구성 요소의 루트 노드에 바인딩하려면 구성 요소 자체 템플릿에서 수행해야 합니다.

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot name="my-body">主体默认值</slot>
    <slot></slot>
  </p>
  `,
};

마찬가지로, 배포 콘텐츠는 상위 범위에서 컴파일됨

기본적으로 삭제됨

일반적으로 하위 구성 요소 템플릿에 <slot> 소켓이 포함되어 있지 않으면 콘텐츠는 discarded

var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p slot="my-body">我是主体</p>
      <p>我是其他内容</p>
      <p slot="my-footer">我是尾部</p>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
    <slot name="my-body">主体默认值</slot>
  </p>
  `,
};

아래 그림과 같이

test 콘텐츠

img src="https://img.php .cn/upload/article/000/000/004/ea9cd4b5a1243e63c504926b758b7700-0.png" alt=""/>

익명 슬롯

 언제 하위 구성 요소 템플릿에는 속성이 없는 슬롯이 하나만 있습니다. 상위 구성 요소의 전체 콘텐츠 조각은 슬롯이 있는 DOM 위치에 삽입되고 슬롯 태그 자체는 교체됩니다.

var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <p slot="my-body">我是主体</p>
      <p>我是其他内容</p>
      <p slot="my-footer">我是尾部</p>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};
🎜🎜🎜🎜
<p class="child">
  <slot text="hello from child"></slot></p>
🎜🎜 🎜🎜🎜 익명 슬롯이 2개 이상인 경우 vue 오류를 보고합니다🎜🎜🎜
var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
      <slot xxx="hello from child"></slot>
  </p>
  `,
};
var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <template scope="props">
        <p>hello from parent</p>
        <p>{{ props.xxx }}</p>
      </template>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};
🎜🎜🎜🎜🎜 【기본값】🎜🎜  원래 <slot> 태그에 포함된 모든 항목은 🎜폴백 콘텐츠🎜로 간주됩니다. 그렇지 않으면 기본값이라고도 합니다. 대체 콘텐츠는 하위 구성 요소의 범위 내에서 컴파일되며 호스트 요소가 비어 있고 삽입할 콘텐츠가 없는 경우에만 표시됩니다.🎜🎜 슬롯에 기본값이 있고 상위 요소에 <에 삽입할 항목이 없는 경우 ;child> 콘텐츠에는 기본값이 표시됩니다🎜🎜🎜
var childNode = {
  template: `  <ul>
    <slot name="item" v-for="item in items" :text="item.text">默认值</slot>
  </ul>
  `,
  data(){
    return{
      items:[
        {id:1,text:'第1段'},
        {id:2,text:'第2段'},
        {id:3,text:'第3段'},
      ]
    }
  }
};
🎜🎜🎜 🎜🎜 슬롯에 기본값이 있고 상위 요소에 에 삽입할 콘텐츠가 있는 경우 설정 값이 표시됩니다🎜🎜🎜
var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <template slot="item" scope="props">
        <li>{{ props.text }}</li>
      </template>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};
🎜🎜🎜🎜🎜 🎜

이름이 지정된 슬롯

🎜  요소는 특수 속성 name을 사용하여 콘텐츠 배포 방법을 구성할 수 있습니다. 여러 슬롯의 이름이 다를 수 있습니다. 명명된 슬롯은 해당 slot 속성 🎜🎜🎜rrreee🎜🎜🎜🎜rrreee🎜🎜🎜🎜🎜🎜이 있는 콘텐츠 조각의 요소와 일치합니다. 여전히 🎜인 익명 슬롯을 가질 수 있습니다. 기본 슬롯🎜, 콘텐츠 조각에 대해 일치하는 대체 슬롯을 찾을 수 없습니다. 익명 슬롯은 슬롯 속성이 없는 요소에 대한 슬롯으로만 사용할 수 있습니다. 슬롯 속성이 있는 요소에 대해 슬롯이 구성되지 않은 경우 >Insert ,

나는 다른 콘텐츠

Insert <slot>이며

가 삭제됩니다. 🎜🎜🎜🎜🎜 기본 슬롯이 없으면 일치하는 항목을 찾을 수 없는 이러한 콘텐츠 조각은 또한 삭제됩니다 🎜🎜🎜rrreee🎜🎜🎜🎜rrreee🎜🎜🎜  

나는 다른 콘텐츠

가 삭제되었습니다🎜🎜🎜🎜🎜🎜

作用域插槽

  作用域插槽是一种特殊类型的插槽,用作使用一个 (能够传递数据到) 可重用模板替换已渲染元素。

  在子组件中,只需将数据传递到插槽,就像将 props 传递给组件一样

<p class="child">
  <slot text="hello from child"></slot></p>

  在父级中,具有特殊属性 scope<template> 元素必须存在,表示它是作用域插槽的模板。scope 的值对应一个临时变量名,此变量接收从子组件中传递的 props 对象

var childNode = {
  template: `  <p class="child">
    <p>子组件</p>
      <slot xxx="hello from child"></slot>
  </p>
  `,
};
var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <template scope="props">
        <p>hello from parent</p>
        <p>{{ props.xxx }}</p>
      </template>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

  如果渲染以上结果,得到的输出是

【列表组件】

  作用域插槽更具代表性的用例是列表组件,允许组件自定义应该如何渲染列表每一项

var childNode = {
  template: `  <ul>
    <slot name="item" v-for="item in items" :text="item.text">默认值</slot>
  </ul>
  `,
  data(){
    return{
      items:[
        {id:1,text:'第1段'},
        {id:2,text:'第2段'},
        {id:3,text:'第3段'},
      ]
    }
  }
};

var parentNode = {
  template: `  <p class="parent">
    <p>父组件</p>
    <child>
      <template slot="item" scope="props">
        <li>{{ props.text }}</li>
      </template>
    </child>
  </p>
  `,
  components: {
    'child': childNode
  },
};

 

위 내용은 Vue 콘텐츠 배포 슬롯의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.