发布时间:2023-11-04 19:00
下面先来认识一下插槽
在开发中,我们会经常封装一个个可复用的组件:
抽取共性、预留不同
;<template>
<div>
<my-slot-cpn>
<button>我是按钮</button>
</my-slot-cpn>
<my-slot-cpn>
<my-input-cpn />
</my-slot-cpn>
<h2>我不是插槽的组件</h2>
<my-slot-cpn>
<h4>插槽里面很多内容</h4>
<i>你信不信我</i>
<del>啦啦啦啦啦</del>
</my-slot-cpn>
<my-slot-cpn></my-slot-cpn>
</div>
</template>
<script>
import MySlotCpn from \"./MySlotCpn.vue\";
import MyInputCpn from \"./MyInputCpn.vue\";
export default {
name: \"App\",
components: { MySlotCpn, MyInputCpn },
methods: {},
};
</script>
<style scoped>
</style>
MySlotCpn.vue
<template>
<div>
<h3>组件的开始</h3>
<slot>
<i>我是插槽,没有填写信息,我就是默认的</i>
</slot>
<h3>组件的结束</h3>
</div>
</template>
<script>
export default {};
</script>
<style lang=\"scss\" scoped>
</style>
MyInputCpn.vue
<template>
<div>
<input type=\"text\" placeholder=\"我是输入框\" />
</div>
</template>
<script>
export default {};
</script>
<style lang=\"scss\" scoped>
</style>
我们可以通过 v-slot:[dynamicSlotName]方式动态绑定一个名称;
具名插槽使用的时候缩写:
跟 v-on 和 v-bind 一样,v-slot 也有缩写;
即把参数之前的所有内容 (v-slot:) 替换为字符 #;
<template>
<div>
<nar-bar :name=\"name\">
<template v-slot:left> 我是左边的插槽 </template>
<template v-slot:center>我是中间的插槽</template>
<template v-slot:right>我是右边的插槽</template>
<template #[name]>我是语法糖和动态插槽</template>
</nar-bar>
</div>
</template>
<script>
import NarBar from \"./NarBar.vue\";
export default {
name: \"App\",
data() {
return {
name: \"lisi\",
};
},
components: {
NarBar,
},
};
</script>
<template>
<div>
<div class=\"nav-bar\">
<div class=\"left\"><slot name=\"left\"></slot></div>
<div class=\"center\"><slot name=\"center\"></slot></div>
<div class=\"right\"><slot name=\"right\"></slot></div>
<div class=\"name\"><slot :name=\"name\"></slot></div>
</div>
</div>
</template>
<script>
export default {
props: {
name: String,
},
};
</script>
在Vue中有渲染作用域的概念:
但是有时候我们希望插槽可以访问到子组件中的内容是非常重要的:
<template>
<div>
<template v-for=\"(item, index) in names\" :key=\"item\">
<slot :item=\"item\" :index=\"index\"></slot>
<slot name=\"lisi\"></slot>
</template>
</div>
</template>
<script>
export default {
props: {
names: {
type: Array,
default: () => []
}
}
}
</script>
<style scoped>
</style>
App.vue
<template>
<div>
<nar-bar :name=\"name\">
<template v-slot:left> 我是左边的插槽 </template>
<template v-slot:center>我是中间的插槽</template>
<template v-slot:right>我是右边的插槽</template>
<template #[name]>我是语法糖和动态插槽</template>
</nar-bar>
<hr />
<show-names :names=\"names\">
<template v-slot=\"names\">
<p>{{ names.item }}-{{ names.index }}</p>
</template>
</show-names>
<hr />
// 如果我们有默认插槽和具名插槽,那么按照完整的template来编写
<show-names :names=\"names\">
<template v-slot=\"slotProps\">
<span>{{ slotProps.item }}---{{ slotProps.index }}</span>
</template>
</show-names>
<hr />
// 果我们的插槽只有默认插槽时,组件的标签可以被当做插槽的模板来使用,这样,我们就可以将 v-slot 直 接用在组件上
<show-names :names=\"names\" v-slot=\"slotProps\">
<button>{{ slotProps.item }}-{{ slotProps.index }}</button>
</show-names>
<hr />
<show-names :names=\"names\">
<template v-slot=\"slotProps\">
<button>{{ slotProps.item }}-{{ slotProps.index }}</button>
</template>
//如果我们的插槽是默认插槽default,那么在使用的时候 v-slot:default=\"slotProps\"可以简写为vslot=\"slotProps\":
<template v-slot:lisi>
<h2>我是name的插入内容</h2>
</template>
</show-names>
</div>
</template>
<script>
import NarBar from \"./NarBar.vue\";
import ShowNames from \"./ShowNames.vue\";
export default {
name: \"App\",
data() {
return {
names: [\"张三\", \"李四\", \"王五\", \"赵六\", \"孙七\"],
};
},
components: {
NarBar,
ShowNames,
},
};
</script>