是否可以通过插槽传递数据?例如,我是否可以拥有一个名为"Button"的命名槽,并向其传递一个添加到a标记中的href?

例如:

MyComponent.vue

<template>
  <div>
    <h2 class="text-lg" v-bind="$slots['heading'].attrs">
      <slot name="heading" />
    </h2>
    <a class="btn" v-bind="$slots['button'].attrs">
      <slot name="button" />
    </a>
  </div>
</template>

MyPage.vue

<template>
  <MyComponent>
    <template #header class="font-bold">
      This is my heading
    </template>
    <template #button href="/about" class="bg-primary">
      About us
    </template>
  </MyComponent>
</template>

HTML语言输出

<div>
    <h2 class="text-lg font-bold">
      This is my heading
    </h2>
    <a class="btn bg-primary" href="/about">
      About Us
    </a>
</div>

推荐答案

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>

Vue.js相关问答推荐

如何将$validator实例注入到使用组合API语法的Vue2.7应用程序中

在哪里可以找到在线沙箱 Vuetify 3 模板来创建最小的可重现示例?

如何在vue js模板中添加foreach和for循环

在 Vue 中删除自定义组件代码重复的方法?

Nuxt3-Vue中的useRoute和useRouter有什么区别

如何将字符串中的
解析为 VUE.js 中的 html 标记

在 Vue 文件中创建根 Vue 实例

VueJS 组件中的图像未加载

如何将 Nuxt.js 更新到最新版本

Keycloak:用户基于角色的客户端登录访问限制

如何在nuxt路由中添加meta?

如何使表格行可点击并展开行 - vue.js - element-ui

Jest错误找不到模块....

基于媒体查询的vue绑定值

Leaflet+Vue+Vuetify / Leaflet map 隐藏 vuetify 弹出对话框

如何在 Vue 数据对象中运行函数?

Vue.js 中的条件 依赖于props值?

使用 svelte js 的原因

vuejs 复制数据对象和删除属性也会从原始对象中删除属性

使用 vue.js 获取调用元素