在某些组件的模板中,有一部分区域需要父组件来指定,类似于iOS里面现在自定义的控件里面,调用某个方法需要传一个UIView进去一样。
<!-- message组件:一个弹窗消息 -->
<div class="message-container">
<div class="content">
<!-- 这里是消息内容,可以是一个文本,也可能是一段html,具体是什么不知道,需要父组件指定 -->
</div>
<button>确定</button>
<button>关闭</button>
</div>
插槽的简单用法
此时,就需要使用插槽来定制组件的功能
<!-- message组件:一个弹窗消息 -->
<div class="message-container">
<div class="content">
<!-- slot是vue的内置组件 -->
<slot></slot>
</div>
<button>确定</button>
<button>关闭</button>
</div>
<!-- 父组件App -->
<Message>
<div class="app-message">
<p>App Message</p>
<a href="">detail</a>
</div>
</Message>
<!-- 最终的结果 -->
<div class="message-container">
<div class="content">
<div class="app-message">
<p>App Message</p>
<a href="">detail</a>
</div>
</div>
<button>确定</button>
<button>关闭</button>
</div>
具名插槽
如果某个组件中需要父元素传递多个区域的内容,也就意味着需要提供多个插槽
为了避免冲突,就需要给不同的插槽赋予不同的名字。简单来说就是一共三个插槽,三个插槽怎么对应呢,起个名字吧,就叫具名插槽。
<!-- Layout 组件 -->
<div class="layout-container">
<header>
<!-- 我们希望把页头放这里,提供插槽,名为header -->
<slot name="header"></slot>
</header>
<main>
<!-- 我们希望把主要内容放这里,提供插槽,名为default -->
<slot></slot>
</main>
<footer>
<!-- 我们希望把页脚放这里,提供插槽,名为footer -->
<slot name="footer"></slot>
</footer>
</div>
<!-- 父组件App -->
<BaseLayout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template v-slot:default>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>
代码 这里的示例就是示例项目的左右结构进行完成。
这是使用的代码
<template>
<div class="test-container">
<Layout>
<div class="main">
主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏主区域,宽度占满剩余空间,溢出隐藏
</div>
<template #right>
<div class="right">
右边栏区域,宽度适应内容,溢出隐藏
</div>
</template>
</Layout>
</div>
</template>
<script>
import Layout from "./";
export default {
components: {
Layout,
},
};
</script>
<style scoped>
.test-container {
width: 60%;
height: 600px;
border: 2px solid;
margin: 0 auto;
white-space: nowrap;
}
.left {
width: 200px;
height: 100%;
background: lightcoral;
}
.main {
width: 100%;
height: 100%;
background: lightseagreen;
}
.right {
width: 150px;
height: 100%;
background: lightblue;
}
</style>
1.v-slot: 可以简写为#
下面是组件代码
<template>
<div class="layout-container">
<div class="left">
<slot name="left"></slot>
</div>
<div class="main">
<slot></slot>
</div>
<div class="right">
<slot name="right"></slot>
</div>
</div>
</template>
<script>
export default {};
</script>
<style scoped lang="less">
.layout-container {
width: 100%;
height: 100%;
display: flex;
.left,
.right {
flex: 0 0 auto;
overflow: hidden;
}
.main {
flex: 1 1 auto;
overflow: hidden;
}
}
</style>
作用域插槽
说在作用域插槽内,父组件可以拿到子组件的数据。子组件可以在slot标签上绑定属性值,如:
<slot :nickName="'Tusi'"></slot>
而父组件通过slot-scope绑定的对象下拿到nickName的值。
<template>
<section>
<slot-child>
<template slot-scope="scope">
<div>{{scope.nickName}}</div>
</template>
</slot-child>
</section>
</template>