컴포넌트를 구성하기 위해서는 상위 컴포넌트의 컨텐츠와 하위 컴포넌트의 자체 템플릿을 혼합하는 방법이 필요합니다. 이 프로세스를 콘텐츠 배포(또는 "전환")이라고 합니다. 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 所在的 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>
元素可以用一个特殊的属性 name
来配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot
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=""/>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>
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!