Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

75
Visualizações
Class Attribute Overwritten in Renderless Vue Component

I've built a renderless base icon Vue component that just outputs whatever is in its slot but with some additional attributes added to the slotted component. One of the attributes I set is class="icon" which allows me to have my styles for all icons in one place.

Icon.vue

<script>
import Vue from "vue";

export default {
  name: "u-icon",
  render(createElement) {
    const svg = this.$slots.default[0];
    const attrs = svg.data.attrs;

    attrs.xmlns = "http://www.w3.org/2000/svg";
    attrs.class = "icon";
    attrs["aria-hidden"] = "true";
    attrs.focusable = "false";
    attrs.role = "img";

    return this.$slots.default;
  },
};
</script>

<style>
.icon {
  // ...
}
</style>

Close-Icon.vue

I can then more easily create many different icon components such as this close icon component.

<template>
  <u-icon>
    <svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
      <line x1="4" y1="4" x2="20" y2="20"></line>
      <line x1="4" y1="20" x2="20" y2="4"></line>
    </svg>
  </u-icon>
</template>

<script>
import icon from "~/icon.vue";
export default {
  name: "close-icon",
  components: {
    "u-icon": icon,
  },
};
</script>

Actual Outcome

The problem is when I use the close-icon component and set a class like so:

<close-icon class="foo"/>

The rendered output is not combining the two classes "icon foo".

<svg class="foo" ...>
  ...
</svg>

Expected Outcome

How can I ensure that the class is not overwritten but appended to so that the output is:

<svg class="icon foo" ...>
  ...
</svg>

If possible, any changes I make should be made to Icon.vue and I'd like to avoid making changes to Close-Icon.vue since there are a large number of other icons.

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

class and style bindings are not part of the $attrs - source

I'm not sure why your code even work without the class binding on close-icon but if you want to add/modify the classes of existing VNode (coming from default slot), you should use svg.data.staticClass instead of svg.data.attrs.class

Example below even handles the case in which static class is also placed directly on the svg element inside close-icon - renders <svg class="foo bar icon" ...

Vue.component("u-icon", {  
  render(createElement) {
    const svg = this.$slots.default[0];
    const attrs = svg.data.attrs;
    
    attrs.xmlns = "http://www.w3.org/2000/svg";
    attrs["aria-hidden"] = "true";
    attrs.focusable = "false";
    attrs.role = "img";
    
    svg.data.staticClass = (svg.data.staticClass || "") + " icon";

    return this.$slots.default;
  },
});

Vue.component("close-icon", {
  template:`
  <u-icon>
    <svg viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" class="bar">
      <line x1="4" y1="4" x2="20" y2="20"></line>
      <line x1="4" y1="20" x2="20" y2="4"></line>
    </svg>
  </u-icon>
  `
})

new Vue({
  el: "#app"
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
<div id="app">
  <close-icon class="foo"></close-icon>
</div>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda