Vue3 SFC playground个
VUE不支持这一点.不过,我想有几种解决办法是可能的.最简单的方法是使用DOM操作属性(这很糟糕,Vue呈现函数不能很好地处理DOM操作),并使用MutationWatch对属性更改做出react .
为此,我们将定制组件SlotAttrs
插入槽中.此外,如果存在一些插槽属性,则可以自动插入此组件:
这将成为
<template #heading><SlotAttrs class="font-bold bg-primary"/>
这一点:
<template #heading class="font-bold bg-primary">
为此,我可以写一个汇总插件,请通知如果你需要这个进一步的详细说明.
SlotAttrs.vue
<script setup>
import { getCurrentInstance, onMounted, onUpdated, useAttrs } from 'vue';
const self = getCurrentInstance();
const attrs = useAttrs();
onMounted(()=>{
const observer = new MutationObserver(syncAttrs);
syncAttrs();
function syncAttrs(){
observer.disconnect();
const parent = self.vnode.el.parentElement.closest('[slot-attrs]');
if(!parent){
console.warn('No element found to inject slot attributes!');
return;
}
for(const name in attrs){
if(name === 'class'){ // do the same for style for example
attrs[name].match(/[\w-]+/g).forEach(name => parent.classList.add(name));
}else{
parent.setAttribute(name, attrs[name]);
}
}
observer.observe(parent, {attributes:true});
}
});
</script>
<template></template>
MyComponent.vue
<script setup>
import {ref} from 'vue';
const large = ref(false);
setInterval(() => large.value = !large.value, 1000);
</script>
<template>
<div>
<h2 :class="{'text-lg':large}" slot-attrs>
<slot name="heading" />
</h2>
<a class="btn" slot-attrs>
<slot name="button" />
</a>
</div>
</template>
<style scoped>
.text-lg{
font-size: 50px !important;
}
h2 {font-weight:normal; }
</style>
附录VUE:
<script setup>
import MyComponent from './MyComponent.vue';
import SlotAttrs from './SlotAttrs.vue';
</script>
<template>
<MyComponent>
<template #heading><SlotAttrs class="font-bold bg-primary"/>
This is my heading
</template>
<template #button><SlotAttrs href="/about" class="bg-primary" />
About us
</template>
</MyComponent>
</template>
<style scoped>
:deep(.font-bold){
font-weight: bold;
}
:deep(.bg-primary){
background:lightblue;
}
</style>