I have a table "css_rules" with 2 columns: "id_type" and "icone_type".
I’d like to generate CSS rules like this:
.custom-marker .[id_type] {
background-image: url(http://example.com/[icone_type].svg);
}
What I tried is that:
async setup(props, { emit }) {
const apiUrl = import.meta.env.VITE_APP_API_URL;
const cssRules = reactive({});
const cssText = computed(() => {
let result = '';
for (const key in cssRules) {
result += `.custom-marker .${key} {`;
const rules = cssRules[key];
for (const property in rules) {
result += `${property}: ${rules[property]};`;
}
result += '}';
}
return result;
});
onMounted(async () => {
await fetch(`${apiUrl}/referentiels/lister/typesressource`, {
method: 'GET',
credentials: 'include',
})
.then((r) => r.json())
.then((r) => {
r.forEach((type) => {
cssRules[type.id_type] = {
backgroundImage: `url(http://example.com/${type.icone_type}.svg) !important`,
};
});
});
});
return {
cssText,
};
},
And in the template:
<template>
<div id="map">XXX</div>
{{ cssText }}
<style>
{{ cssText }}
</style>
</template>
The fact is that the "cssText" text displays perfectly, but I have an error:
[plugin:vite:vue] Tags with side effect ( and ) are ignored in client component templates.
Apparently I can’t create my own style
tag inside my component. How could I solve this?
2
Answers
I am not aware of a way in Vue to dynamically add or remove CSS classes. But you can do it in regular JS, by creating a style tag and adding it to the HTML head:
Here it is in a small snippet:
Have a look at how Vuetify does it, they use a library for document head management (
@vueuse/head
), and use DOM manipulation (as above) as fallback.Since you want to dynamically assign the image URL, I recommend using style binding. With this, you can create an object that contains CSS properties in camel case and assign it to the
style
prop. Observe:Live Demo