插槽(组件的优化)
1. 什么是插槽插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。可以把插槽2. . 体验插槽的基础用法 (简写为#)在封装组件时,可以通过 <solt>元素定义插槽,从而为用户预留内容占位符。示例代码如下认为是组件封装期间,为用户预留的内容的占位符。<template><p>这是MyCom
1. 什么是插槽
插槽(Slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。
可以把插槽
2. . 体验插槽的基础用法 (简写为#)
在封装组件时,可以通过 <solt>元素定义插槽,从而为用户预留内容占位符。示例代码如下
认为是组件封装期间,为用户预留的内容的占位符。
<template>
<p>这是MyCom1 组件的第一个p标签</p>
//通过sort 标签,为用户预留内容占位符(插槽)
<slot></slot>
<p>这是MyCom1 组件最后一个P标签</p>
</template>
<my-com-1>
// 在使用MyCom1组件是,为插槽指定具体的内容
<p>用户自定义的内容</p>
</my-com-1>
2.1 没有预留插槽的内容会被丢弃
如果在封装组件时没有预留任何 插槽,则用户提供的任何自定义内容都会被丢弃。示例代码如下 :
<template>
<p>这是MyCom1 组件的第一个p标签</p>
//封装组件,没有预留任何插槽
<p>这是MyCom1 组件的最后一个p标签</p>
</template>
<template>
<p>这是MyCom1 组件的第一个p标签</p>
//封装组件,没有预留任何插槽
<p>这是MyCom1 组件的最后一个p标签</p>
</template>
在封装组件是,为预留的<slot>提供对应的值,这种用法,叫做"作用域插槽"(留有数据的插槽)
<template>
<div class="app-container">
<h1>App 根组件</h1>
<hr />
<Article>
<template #title="{msg,user}">
<h3>我是文章的标题</h3>
<h4>{{msg}}</h4>
<h4>{{user.name}}</h4>
</template>
<template #content>
<p>我是文章的内容</p>
<p>我是文章的内容</p>
<p>我是文章的内容</p>
</template>
<template #footer>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
<p>我是文章的页脚</p>
</template>
</Article>
<div class="box" style="display:none">
<!-- 渲染 Left 组件和 Right 组件 -->
<Left>
<!-- 默认情况下,在使用组件的时候提供的内容都会被填充到名字为default的插槽之中 -->
<!-- 1.如果要内容填充到指定名称的插槽中,需要使用v-slot:这个指令 -->
<!-- 2.v-slot:后面要跟上插槽的名字 -->
<!-- 3.v-slot:指令不能直接用在元素身上,必须在template标签上 -->
<!-- 4.teplate这个标签,他是一个虚拟的标签,只起到一个包裹的作用,但是不会被渲染为任何实质性的html元素 -->
<!-- 5.v-slot:指令的简写形式是# -->
<template #default>
<p>这是在left组件的内容区域,声明的p标签</p>
</template>
</Left>
</div>
</div>
</template>
<script>
import Article from './components/Article.vue'
import Left from './components/Left.vue'
export default {
components: { Left, Article },}
</script>
<style lang="less">
.app-container {
padding: 1px 20px 20px;
background-color: #efefef;
}
.box {
display: flex;
}
</style>
<template>
<div class="article-container">
<!-- 文章的标题 -->
<div class="header-box">
<slot name="title" msg="Helo vue .js" :user="userinfo"></slot>
</div>
<!-- 文章的内容 -->
<div class="content-box">
<!-- 在封装组件是,为预留的<slot>提供对应的值,这种用法,叫做"作用域插槽"(留有数据的插槽) -->
<slot name="content"></slot>
</div>
<!-- 文章的作者 -->
<div class="footer-box">
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'Article',
data() {
return {
userinfo:{
name:"张三",
age:"23"
}
}
},
mounted() {},
methods: {},
}
</script>
<style lang="less" scoped>
.article-container {
>div{
min-height: 150px;
}
.header-box {
background-color: pink;
}
.content-box {
background-color:lightblue;
}
.footer-box {
background-color: lightcoral;
}
}
</style>
在设置是,要先确认接收方与发送方,接收方要通过template里面的v-slot来接收并且指定插槽名字,发送方需要在组件内定义数据通过slot来发送数据,发送形式可以有多种。
注意:1.默认情况下,在使用组件的时候提供的内容都会被被填充到名字为default的插槽之中
2.如果要内容填充到指定的插槽中,需要v-slot:这个指令
3.v-slot:后面要跟上插槽的名字(在name节点中定义的)
4.v-slot:指令不能用在元素的身上,必须在template标签上或者在已经注册节点
5.teplate这个标签的作用,但是不会被渲染为任何实质性的html元素
6.v-slot:指令的简写形式是#
3.自定义指令
vue中的自定义指令分为两个类:
3.1私有自定义指令
在每个vue组件中,可以在directives节点(自定义指令节点)下声明私又自定义指令,实例代码如下
directives:{
color:{
//为绑定的html元素三设置红色的文字
bind(el){
el.style.color='red'
}
}
}
el可以获取全局的dome元素,此外还可以有binding函数打印该函数可以发现里面存有value值,里面有获取到值
再此我们可以打印一下
directives: {
color: {
bind(el, binding) {
el.style.color = 'red'
console.log(binding)
},
},
},
3.2全局自定义指令
在main.js文件中来增加全局自定义指令
// main.js 全局自定义指令
export default {
diretive:{
bind(el,binding){
console.log('v-color的binding函数')
el.style.color = binding.value
},
update(el,binding){
console.log('v-color的binding函数')
el.style.color = binding.value
},
}
}
// 或者可以简写成
Vue.diretive("color",function(el,binding){
el.style.color = binding.value
})
此时该v-color全局可以调用,但是要注意的是需要在本组件里面定义好color数据,不然回出现undefind错误
完整代码如下
<template>
<div class="app-containter">
<h2>app根组件</h2>
<hr />
<Article>
<template #title="{user,msg,use,data}">
<button @click="color='red'">改变color的颜色值</button>
<p v-color='color'>我是文章的标题</p>
</template>
</Article>
</div>
</template>
<script>
import Article from './components/Article.vue'
import Left from './components/Left.vue'
import Right from './components/Right.vue'
export default {
components: { Left, Right, Article },
name: 'App',
directives: {
//定义名为color的指令,指向配置对象
// color:{
// //当指令第一次被绑定到元素上的时候,会立即触发bind函数
// //形参中的el表示当前指令所绑定的DOM对象
// bind (el,binding) {
// console.log("v-color的binding函数")
// el.style.color = binding.value
// console.log(binding)
// },
// // 在dom更新的时候会触发updata里面的binding函数
// update (el,binding) {
// el.style.color = binding.value
// console.log("触发了updata的update函数")
// },
// }
//即包含了updata有包含了bind,因为两者的业务逻辑相似
// color(el,binding){
// el.style.color=binding.value
// }
color: {
bind(el, binding) {
el.style.color = 'red'
console.log(binding)
},
},
},
data() {
return { comName: 'Left', color: 'blue' }
},
methods: {},
}
</script>
<style lang="less" scoped>
.app-containter {
padding: 10px 10px;
}
</style>
<template>
<div class="article-container">
<p v-color='color'>article组件</p>
</div>
</template>
<script>
export default {
name: 'Article',
components:{
},
data() {
return {
color:'red'
};
},
};
</script>
<style lang="less" scoped>
.article-container{
.article-title{
min-height: 150px;
background-color: antiquewhite;
}
.article-content{
min-height: 150px;
background-color: orange;
}
.article-footer{
min-height: 150px;
background-color: pink;
}
}
</style>
更多推荐
所有评论(0)