Vue插槽

Vue 插槽

插槽用于向组件传递内容,插槽内可以包含任何模板代码,包括 HTML,甚至组件。如果 组件 没有包含一个 <slot> 元素,则任何传入它的内容都会被抛弃。

<slot-conponent>
    Fluently
</slot-conponent>
Vue.component('slot-conponent', {
    data() {
        return {

        }
    },
    template: `
        <div>
            Hello <slot></slot>
        </div>
    `
})
var app = new Vue({
    el: '#app',
    data: {}
})
<!-- 渲染为 -->
<div>
    Hello Fluently
</div>

具名插槽

定义具体名称的插槽,组件内的内容会根据名称自动匹配到模板对应的地方。如果没有匹配项,则显示在默认插槽上,否则不显示。

<!-- 具名插槽 -->
<slot-name>
    <template slot="header">
        <h1>header</h1>
    </template>
    <template slot="footer">
        <h1>footer</h1>
    </template>
    <template slot="main">
        <h1>main</h1>
    </template>
    <template><h1>默认插槽</h1></template>
</slot-name>
<!-- 具名插槽另一种写法 -->
<slot-name>
    <h1 slot="header">header</h1>
    <h1 slot="footer">footer</h1>
    <h1 slot="main">main</h1>
    <h1>默认插槽</h1>
</slot-name>
Vue.component('slot-name', {
data() {
    return {

    }
},
template: `
    <div>
        <header>
            <slot name="header"></slot>
        </header>
        <main>
            <slot name="main"></slot>
        </main>
        <footer>
            <slot name="footer"></slot>
        </footer>
        <!-- 默认插槽 -->
        <div>
            <slot></slot>
        </div>
    </div>
`
})

默认插槽

为插槽提供默认内容,同时允许覆盖默认内容

<slot-default></slot-default>
<slot-default>Modify</slot-default>
Vue.component('slot-default', {
    data() {
        return {

        }
    },
    template: `
        <div>
            <slot>Default</slot>
        </div>
    `
})

插槽编译作用域

父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。

<!-- 插槽编译作用域 -->
<slot-scope>{{msg}}</slot-scope>
<!-- 访问出错,父级作用域模板不能访问子级数据 -->
<slot-scope>{{childMsg}}</slot-scope>
Vue.component('slot-scope', {
    data() {
        return {
            childMsg: 'childScope'
        }
    },
    template: `
        <div>
            <slot>{{childMsg}}</slot>
        </div>
    `
})
var app = new Vue({
    el: '#app',
    data: {
        msg: 'Scope'
    }
})

作用域插槽

组件能够从子组件获取数据(slot-scope 特性从子组件获取数据),根据数据去独立渲染对应的表现

<todo-list v-bind:todos="todos">
    <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
    <template slot-scope="slotProps">
        <!-- 为待办项自定义一个模板,-->
        <!-- 通过 `slotProps` 定制每个待办项。-->
        <span v-if="slotProps.todo.isComplete">✓</span>
        {{ slotProps.todo.text }}
    </template>
</todo-list>
Vue.component('todo-list', {
    props: ['todos'],
    data() {
        return {

        }
    },
    template: `<ul>
                <li v-for="todo in todos" v-bind:key="todo.id">
                    <slot v-bind:todo="todo">
                        <!-- 回退的内容 -->
                        {{ todo.text }}
                    </slot>
                </li>
                </ul>`
})
var app = new Vue({
    el: '#app',
    data: {
        msg: 'Scope',
        todos: [{
            text: 'Java',
            id: 1,
            isComplete: false
        }, {
            text: 'JavaScript',
            id: 2,
            isComplete: true
        }, {
            text: 'Vue',
            id: 3,
            isComplete: true
        }]
    }
})

解构 slot-scope

下面两种 template 具有相同的效果,通过解构 slot-scope 能够使作用域插槽变得更干净一些

<!-- 作用域插槽 -->
<todo-list v-bind:todos="todos">
    <!-- 将 `slotProps` 定义为插槽作用域的名字 -->
    <template slot-scope="slotProps">
        <!-- 为待办项自定义一个模板,-->
        <!-- 通过 `slotProps` 定制每个待办项。-->
        <span v-if="slotProps.todo.isComplete">✓</span>
        {{ slotProps.todo.text }}
    </template>
</todo-list>

<!-- 解构Slot -->
<todo-list v-bind:todos="todos">
    <template slot-scope="{ todo }">
        <span v-if="todo.isComplete">✓</span>
        {{ todo.text }}
    </template>
</todo-list>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • By Leaf 在学习的过程中遇到了Vue的slot元素,开始不知道也不了解它的用途、用法,即然遇到了不懂的知识点...
    HYC_阅读 10,464评论 7 42
  • 什么是组件? 组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装...
    youins阅读 13,158评论 0 13
  • 以下内容是我在学习和研究Vue时,对Vue的特性、重点和注意事项的提取、精练和总结,可以做为Vue特性的字典; 1...
    科研者阅读 14,770评论 3 24
  • 这两天的疑惑:按照背景-方法-案例来写是一种写作方案吧? 我的定位是讲科学聊商业,其实是两个方向,商业的话我觉得套...
    三只萤火虫阅读 1,098评论 0 0
  • 今天早上,我还在睡意之中就被妈妈的说话声吵醒。我起来一看,呀!一条蛇。妈妈就说“快看,厕所有一条蛇。快拿雄黄来”我...
    雅航_08bc阅读 1,020评论 0 0