一、插槽
插槽(Slot)是 vue 为组件的封装者提供的能力。允许封装者在封装组件时,把不确定的,希望由用户指定的部分定义为插槽。
<template>
<div class="app-container">
<h1>App 根组件</h1>
<hr />
<div class="box">
<!-- 渲染 Left 组件和 Right 组件 -->
<Left>
<!--
默认情况下,在使用组件的时候提供的内容都会被填充到名称为 default 的插槽当中
v-slot 指令只能用于 template 组件中
-->
<!-- <template v-slot:default> -->
<template #default>
<p>这是在 Left 组件中声明的 p 标签</p>
</template>
</Left>
</div>
</div>
</template>
<script>
import Left from "@/components/Left.vue";
export default {
components: {
Left,
},
};
</script>
<style lang="less">
.app-container {
padding: 1px 20px 20px;
background-color: #efefef;
}
.box {
display: flex;
}
</style>
<template>
<div class="left-container">
<h3>Left 组件</h3>
<hr />
<!-- 声明插槽区域 -->
<!-- Vue 官方规定每个插槽都要有一个 name 名称,若省略了 name 属性,则有一个默认 name 名称:default -->
<slot>
<!-- 若用户没有在使用 Left 组件时指定插槽中的内容,即默认展示 slot 标签中的内容:官方称为 “后备内容” -->
这是 deault 插槽中默认的内容
</slot>
</div>
</template>
<script>
export default {};
</script>
<style lang="less">
.left-container {
padding: 0 20px 20px;
background-color: orange;
min-height: 250px;
flex: 1;
}
</style>
二、具名插槽
带有 name 名称的 slot 插槽就是具名插槽
<template>
<div class="aricle-container">
<!-- 文字的标题 -->
<div class="header-box">
<slot name="title"></slot>
</div>
<!-- 文字的内容 -->
<div class="content-box">
<slot name="content"></slot>
</div>
<!-- 文字的作者 -->
<div class="footer-box">
<slot name="author"></slot>
</div>
</div>
</template>
<script>
export default {
name: "Article",
data() {
return {};
},
};
</script>
<style lang="less" scoped>
.aricle-container {
> div {
min-height: 150px;
}
.header-box {
background-color: pink;
}
.content-box {
background-color: lightskyblue;
}
.footer-box {
background-color: lightgreen;
}
}
</style>
<template>
<div class="app-container">
<h1>App 根组件</h1>
<Article>
<template #title>
<h3>一首诗</h3>
</template>
<template #content>
<div>
<p>锄禾日当午,汗滴禾下土</p>
<p>锄禾日当午,汗滴禾下土</p>
<p>锄禾日当午,汗滴禾下土</p>
<p>锄禾日当午,汗滴禾下土</p>
</div>
</template>
<template #author>
<p>佚名</p>
</template>
</Article>
<hr />
<div class="box">
<!-- 渲染 Left 组件和 Right 组件 -->
<Left style="display: none">
<!--
默认情况下,在使用组件的时候提供的内容都会被填充到名称为 default 的插槽当中
v-slot 指令只能用于 template 组件中
-->
<!-- <template v-slot:default> -->
<template #default>
<p>这是在 Left 组件中声明的 p 标签</p>
</template>
</Left>
</div>
</div>
</template>
<script>
import Left from "@/components/Left.vue";
import Article from "@/components/Article.vue";
export default {
components: {
Left,
Article,
},
};
</script>
<style lang="less">
.app-container {
padding: 1px 20px 20px;
background-color: #efefef;
}
.box {
display: flex;
}
</style>
作用域插槽:
<!-- 在封装组件时,为预留的 slot 提供属性对应的值,这种做法叫做:作用域插槽 -->
<div class="content-box">
<slot name="content" msg="hello vue"></slot>
</div>
<template #content="obj">
<div>
<p>锄禾日当午,汗滴禾下土</p>
<p>锄禾日当午,汗滴禾下土</p>
<p>锄禾日当午,汗滴禾下土</p>
<p>锄禾日当午,汗滴禾下土</p>
<p>{{ obj }}</p>
</div>
</template>
三、自定义指令
1、私有自定义指令
在每个 vue 组件中,可以在 directives
节点下声明私有自定义指令
directives:{
color:{
// 为绑定到的 HTML 元素设置红色的文字
bind(el){
// 形参中的 el 是绑定了此指令的、原生的 DOM 对象
el.style.color = 'pink'
}
}
}
注意:
当指令第一次绑定到元素时调用 bind
函数,当 DOM 更新时 bind
函数不会触发。
update
函数会在每次 DOM 更新时被调用
directives: {
color: {
// 为绑定到的 HTML 元素设置红色的文字
bind(el, binding) {
// 形参中的 el 是绑定了此指令的、原生的 DOM 对象
el.style.color = binding.value;
},
update(el, binding) {
el.style.color = binding.value;
},
},
},
若 bind 和 update 函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:
color(el, binding) {
el.style.color = binding.value;
},
2、全局自定义指令
全局共享的自定义指令需要通过 Vue.directive()
进行声明
// 参数一:字符串,表示全局自定义指令的名字
// 参数二:对象,用来接收指令的参数值
Vue.directive('color',function(el,binfing){
el.style.color = binding.value
})
一 叶 知 秋,奥 妙 玄 心