vue-learning: 29 - component - the three components of the three API: slot

The third component of the three API: slot

  • <slot>label
  • v-slotinstruction
  • Ordinary Slot
  • It has a default value of slots
  • Named Slot
  • Scope slot

v-slotIs Vue 2.6.0a new grammar instruction is introduced with the aim of reunification before slot / slot-scopeusage. Unified command syntax is more concise and easier to understand.

Before explain propachieve data transfer assembly downward, and eventthe v-on / $emitenables data transfer assembly upwardly. This section v-slotdirective implementing component content customization features.

A simple example of a custom button component:

<div id="app">
    <p>this is example for slot</p>
    <custom-button></custom-button>
</div
const customButton = Vue.extend({
    template: `<button>提交</button>`,
})

const vm = new Vue({
    el: "#app",
    components: {
        customButton,
    },
})

At this time, this custom button is bound to be a submit button because we wrote the text on the button fixed dead "Submit." If we need to use the buttons according to different scenarios, showing different text, such as may be submitted, delete, confirm, or return. In this case we can use components <slot>tag, which corresponds to the contents inside the placeholder assembly.

Ordinary Slot

The above example we only need to define the component in place with the button text <slot><slot>labels to representatives

const customButton = Vue.extend({
    template: `<button>
        <slot></slot>
    </button>`,
})

Then offer to provide content when you can use the component

<div id="app">
    <p>this is example for slot</p>
    <custom-button>提交</custom-button>
    <custom-button>删除</custom-button>
    <custom-button>返回</custom-button>
</div

At this point on the custom button to display the complete text of what is determined by the component use, rather than determine when the component definition.

It has a default value of slots

Demand upgrade, we hope that when the component is not written in the text when you call, the default display "OK." In this case the component may be <slot>a definition of the label text content, it will act as the default content display component.

const customButton = Vue.extend({
    template: `<button>
        <slot>确认</slot>
    </button>`,
})
div id="app">
    <p>this is example for slot</p>
    <!-- 有输入内容显示输入的内容:提交 -->
    <custom-button>提交</custom-button>
    <!-- 没有输入内容时默认显示定义时文字:确认 -->
    <custom-button></custom-button>
</div

Named Slot

The above only provides custom button assembly occupying a slot, but the need to abstract the content of the component kinds, such as a paragraph content component, including custom heading, paragraph text, the writing time of three parts. This component was analyzed by at least three parts, and the contents of three parts only know what the input only when the component uses.

So when we define the component that provides three occupying slots, one for the title, a display for time, other content as text

const customSection = Vue.extend({
    template: `<section>
        <header>
        <slot name="title"></slot>
        </header>

        <main>
        <slot></slot>
        </main>
        
        <footer>
        <slot name="time"></slot>
        <footer>
    </section>`,
})
<custom-section>
    <template v-slot:title>段落标题</template>
    <template>这是段落正文部分,内容很长,这里就省略了......</template>
    <template v-slot:time>2019-5-26</template>
</custom-section>

The syntax is simple:

  • When the component definition: <slot>tag when a specified nameattribute value to
  • When using the assembly, <template>with the label v-slotinstruction parameter indicates the specific names, which represents the current template placeholders for content slotto.

When the contents have multiple named slots, slot when written component calls need <template>labels wrap

Unnamed default slot, there is a name that comes insidedefault

<!-- 定义时 -->
 <main><slot></slot></main>
 <main><slot name="defalut"></slot></main>
<!-- 使用时 -->
<template>这是段落正文部分,内容很长,这里就省略了......</template>
<template v-slot:default>这是段落正文部分,内容很长,这里就省略了......</template>

Dynamic selection of slots
can define multiple sets of slots, external reference display decide which named slot call, equivalent to a switch statement based on conditions in the sub-assembly.

<div id="app">
    <button @click="changeSlot">点击切换slot</button>
    <custom-section>
        <template v-slot:[variable]>改变了插槽</template>
    </custom-section>
</div>
const customSection = Vue.extend({
    template: `<article>
        <slot name="js">this is content for js</slot>
        <slot name="html">this is content for html</slot>
        <slot name="css">this is content for css</slot>
    </article>`,
})
const vm = new Vue({
    el: "#app",
    components: {
        customSection
    },
    data: {
        index: 0,
        arr: ['html', 'css', 'js'],
        variable: 'html'
    },
    methods: {
        changeSlot() {
            this.variable = this.arr[++this.index % 3]
        }
    }
})

Scope slot

Here's the concept of a domain, there is a saying in the official document:

Parent template of all content is the role of the parent in the domain compiled; sub-template of all the contents are compiled in the sub-domain action.

In simple terms:
Slot although the content component tag quilt wrapped, but in fact, like slot subassembly labels attribute in the parent template scope. Data can be referenced within the scope of the direct parent component. But it can not directly reference the data sub-template scope.

const customSection = Vue.extend({
    template: `<section>
        <header>
        <slot name="title"></slot>
        </header>

        <main>
        <slot></slot>
        </main>

        <footer>
        <slot name="time"></slot>
        <footer>
    </section>`,
    data:() => {
        return {
            innerTitle: '写在子级的标题'
        }
    }
})

const vm = new Vue({
    el: "#app",
    data: {
        outerTitle: '写在父级的标题'
    },
    components: {
        customSection,
    },
})

The above code, we are in the root element vmdefines the title outerTitle: '写在父级的标题', sub-assemblies also custom-sectiondefines the title innerTitle: '写在子级的标题'.

<div id="app">
    <p>这里可以直接引用父级标题:{{ outerTitle }}</p>
    <custom-section>
        <!-- 在插槽模板内也可以使用父级作用域内的数据的 -->
        <template v-slot:title>{{ outerTitle }}</template>
        <!-- <template v-slot:title>段落标题</template> -->
        <template>这是段落正文部分,内容很长,这里就省略了......</template>
        <template v-slot:time>2019-5-26</template>
    </custom-section>
</div>
<div id="app">
    <p>这里是肯定不可以直接引用子级标题:{{ innerTitle }}</p>
    <custom-section>
        <!-- 在插槽也不能直接引用子组件内的数据,控制台会报错!!! -->
        <template v-slot:title>{{ innerTitle }}</template>
        <!-- <template v-slot:title>段落标题</template> -->
        <template>这是段落正文部分,内容很长,这里就省略了......</template>
        <template v-slot:time>2019-5-26</template>
    </custom-section>
</div>

But the content is a final slot in the sub-assembly, so often data is needed inside the subassembly to operate. In this case it is necessary to transfer the data within the sub-assembly upwardly defining the slot, the slot so that the call may be used.

const customSection = Vue.extend({
    template: `<section>
        <header>
        // <slot name="title"></slot>
        <slot name="title" :title="innerTitle"></slot>
        </header>

        <main>
        <slot></slot>
        </main>

        <footer>
        <slot name="time"></slot>
        </footer>
    </section>`,
    data:() => {
        return {
            innerTitle: '写在子级的标题'
        }
    }
})
 <div id="app">
    <p>这里可以直接引用父级标题:{{ outerTitle }}</p>
    <custom-section>
        <!-- <template v-slot:title>段落标题</template> -->
        <template v-slot:title="slotProp">{{ slotProp.title }}</template>
        <template>这是段落正文部分,内容很长,这里就省略了......</template>
        <template v-slot:time>2019-5-26</template>
    </custom-section>
</div>

See when defining <slot>provided with tag v-bindvalues need to pass the binding subassembly

<slot name="title" :title="innerTitle"></slot>

When slot call, by v-slotreceiving a value after use.

<template v-slot:title="slotProp">{{ slotProp.title }}</template>

And the v-slotvalue is taken over in the form of an object, the definition v-bindcan be bound to a plurality, in v-slotthe key-value to the reception, the use of the object dot call.

<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="slotProp">{{ slotProp.title + '-' + slotProp.author }}</template>

Slot prop deconstruction of
course, if you do not want to use objects RBI calls, you can also use the object syntax to call ES6 deconstruction.

<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="{ title, author }">{{ title + '-' + author }}</template>

Slot prop rename
If you pass up the prop may be variable with the same name as the parent scope references may be renamed when the deconstruction

<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="{ title, author:writer }">{{ title + '-' + writer }}</template>

The default value of prop slot
can also write a default content, avoid receiving the prop is undefined situation

<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="{ title, author='anonymity'}">{{ title + '-' + author }}</template>

Slot prop is a function of the parameters
in the official document explained, the inner workings of the slot is the slot include in your function parameters in a single pass, so the new syntax ES6 function parameters can be used, such as deconstruction, The default parameter values, etc.

function (slotProps) {}
function ({title, author}) {}
function ({title, author=anonymity}) {
  // 插槽内容
}

v-slotShorthand#
with v-bindabbreviated as :, v-onabbreviated as @as v-slotshorthand @
when the use of abbreviations #must be followed by one slot name, as #when binding a default slot, you need to write#default

// 可以
<template v-slot="slotProp"></template>
// 错误
<template #="slotProp"></template>
// 改成
<template #defalut="slotProp"></template>

When the exclusive default slot, v-slot can be bound label on the subassembly, template omitted

<div id="app">
    <p>this is example for slot</p>
    <custom-button v-slot={type}>{{ type ? '确定' : '删除'}}</custom-button>
    <custom-button #default={type}>{{ !type ? '确定' : '删除'}}</custom-button>
</div
const customButton = Vue.extend({
    template: `<button><slot :type="btnType"></slot></button>`,
    data() => {
        return {
            btnType: 1, // 1 确定 0 删除
        }
    }
})

const vm = new Vue({
    el: "#app",
    components: {
        customButton,
    },
})

to sum up

v-slot:slotName="slotProp"
#:slotName="slotProp"

Guess you like

Origin www.cnblogs.com/webxu20180730/p/11031257.html