一、插槽
插槽(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
})
一 叶 知 秋,奥 妙 玄 心