How to import css file from node_modules in Vue-component - css

I want to connect this toastr-library into my component:
my-component.vue
<script>
import toastr from 'toastr';
export default {
mounted(){
toastr.success('Hello from toastr!');
}
}
</script>
<template>
<div>
Template for my-component.vue here.
</div>
</template>
<style>
/* HOW TO IMPORT `toastr.css` FROM NODE_MODULES HERE?
</style>
How to connect library's css from node_modules directory?

As #LinusBorg suggested here in vue-loader discussion thread, you can use src-attribute inside <style>-tag:
my-component.vue
<script>
import toastr from 'toastr';
export default {
mounted(){
toastr.success('Hello from toastr!');
}
}
</script>
<template>
<div>
Template for my-component.vue here.
</div>
</template>
<style src='toastr/build/toastr.min.css'></style>

Related

Vue3, child component doesn't render dynamic string value [duplicate]

This question already has answers here:
ref vs reactive in Vue 3?
(7 answers)
Closed last month.
When I import HelloWorld component into App.vue, I'm unable to see the content of contenutoHeader.
HelloWorld:
<template>
<h1>{{ contenutoHeader }}</h1>
</template>
<script>
const contenutoHeader = "Sto funzionando";
export default {
name: "HelloWorld",
};
</script>
App.vue
<template>
<div>
<HelloWorld />
</div>
</template>
<script setup>
import HelloWorld from "./components/HelloWorld.vue";
</script>
Any suggestion?
You need to add your state to the data, like so:
<template>
<h1>{{ contenutoHeader }}</h1>
</template>
<script>
export default {
name: "HelloWorld",
data () {
return {
contenutoHeader: "Sto funzionando"
}
}
};
</script>
Anything within the data is reactive and can be used in your template

Vuetify 3 - Cannot Import Async Components

I know this isn't the best time to use vuetify 3 but, i did. Hoping everything goes well until i found out that a lot of components are still missing.
Now, I am having a problem importing a lazy component using defineAsyncComponent.
my DOM doesn't seem to recognize async components.
I don't know if it is a vuetify error but my project is made out of vuetify so I was suspecting it was the problem.
Below is my code in dashboardACtionsLayout.vue
<template>
<div>
<div class="d-flex mb-3 mt-2">
<add-customer-modal />
</div>
</div>
</template>
<script setup>
import { defineAsyncComponent } from "vue";
components: {
addCustomerModal: defineAsyncComponent(() =>
import("#/components/customer/addCustomerModal.vue")
);
}
</script>
<style lang="scss" scoped></style>
and this is the error i am getting in my console:
Use defineAsyncComponent like below.
<template>
<div>
<div class="d-flex mb-3 mt-2">
<add-customer-modal />
</div>
</div>
</template>
<script setup>
import { defineAsyncComponent } from "vue";
const AddCustomerModal = defineAsyncComponent(() =>
import('#/components/customer/addCustomerModal.vue')
)
</script>
<style lang="scss" scoped></style>
note:
The name of your component is addCustomerModal, while vue's recommendation is that the beginning of all words should be capitalized, like AddCustomerModal.
It is now fixed as of #m kh answer. But when I try to register two components using this code; `
const AddCustomerModal = defineAsyncComponent(() =>
import("#/components/customer/addCustomerModal.vue")
);
const CustomersModal = defineAsyncComponent(() => {
import("#/components/customer/customersModal.vue");
});
` I will get an error like this

Tailwind classes not getting applied for Astro Layouts

I am using Astro Tailwind integration, and I am trying to add some tailwind classes to MainLayout.astro which resides in layouts directory as follows
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<main class="mx-20 mb-20 md:mb-28 xl:container xl:mx-auto">
<slot />
</main>
</body>
</html>
But styles are not getting applied to the <main> tag (according to browser dev tools inspection), but styles to the rest of the pages are getting applied.
What I have tried?
Restarting the dev server
Edit:
tailwind.config.cjs look like below
/** #type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"],
...
};
Edit 2:
astro.config.mjs
import { defineConfig } from "astro/config";
import react from "#astrojs/react";
import image from "#astrojs/image";
import tailwind from "#astrojs/tailwind";
// https://astro.build/config
export default defineConfig({
integrations: [
react(),
tailwind(),
image({
serviceEntryPoint: "#astrojs/image/sharp",
}),
],
});

How do I use PrimeVue in CustomElements?

I have a Vue 3 custom Element in which I want to use PrimeVue & PrimeFlex etc.
So I first create a Component, use the .ce.vue extension for the sfc mode and use the combination of defineCustomElement and customElements.define to compile it to a web component. Finally I use it in the index.html to see if it works in the Browser.
It works to some extent but not completely. For example, I am unsure about how to translate app.use(PrimeVue) for my case.
//customElement.ce.vue
<template>
<div>Test</div>
<AutoComplete field="name" />
</template>
<script lang="ts">
import { defineComponent } from "vue";
import AutoComplete from "primevue/autocomplete";
export default defineComponent({
name: "customElement",
props: {
msg: String,
},
components: { AutoComplete },
setup: () => {
console.log(JSON.stringify(theme));
return { PrimeVue };
},
styles: [],
});
</script>
<style scoped lang="scss"></style>
//main.ts
import { createApp, defineCustomElement } from "vue";
import App from "./App.vue";
//PrimeVue
import PrimeVue from "primevue/config";
import "/node_modules/primeflex/primeflex.css";
import "primevue/resources/primevue.min.css";
import "primevue/resources/themes/saga-blue/theme.css";
//CustomElement
import customElement from "#/components/customElement.ce.vue";
const customElementWC = defineCustomElement(customElement);
customElements.define("custom-element", customElementWC);
//Setup VueApplication for testing/reference, this works as expected.
const app = createApp(App);
app.use(PrimeVue);
app.mount("#app");
//index.html (for testing)
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div> //test app
<custom-element /> //the custom Web Component
<!-- built files will be auto injected -->
</body>
</html>
So I can see that the PrimeVue-Autocomplete is being shown, but the styles are not working.
So the question is:
How can I use all of PrimeVue in a custom Component?
Or in other words: How do I setup a Vue 3 CustomElement with PrimeVue?
So I have found a workaround (not a proper solution).
The way to make most of it work is to import the styles and js/ts modules in the component(s) itself.
The main styles make the most sense to import in the root component of the web component.
The reason why it has to be there is, due to:
https://github.com/vuejs/vue-cli/issues/6033 and
https://github.com/vuejs/core/issues/4662
that web components can't use plugins, or at least I don't know how. In other words there is no app.use() method.
I still couldn't properly import primeflex so I had to use the cdn link. I think it is possible to use an internal import, and I will update the answer when I find out how.
To use a specific PrimeVue component, simply import and register it as the documentation describes.
<template>
<Button />
</template>
<script lang="ts">
import Button from "primevue/button";
import { defineComponent } from "vue";
export default defineComponent({
components: { Button },
});
</script>
<style>
#import url("https://unpkg.com/primeflex#3.1.0/primeflex.css");
</style>
<style lang="scss" src="#/assets/scss/globals.scss"></style>
<style src="primevue/resources/primevue.min.css"></style>
<style src="primevue/resources/themes/tailwind-light/theme.css"></style>
//main.ts
import { defineCustomElement } from "vue";
import App from "./App.ce.vue";
customElements.define("custom-element", defineCustomElement(App));
Limitation:
Due to the missing plugin support (or my lack of knowledge of it) the lines:
import PrimeVue from 'primevue/config';
app.use(PrimeVue);
are not possible. Unfortunately, I can't fully grasp the impact that might have.

How to use asset URLs in style binding with Vite

I want to show a background image from my assets folder. When I use an image tag, the image is shown properly, so the image is well placed, but throws a 404 when I use the background-image style. Any idea about what is happening?. I am using Vue 3 with TypeScript and Vite 2.
This does not resolve the URL:
<div style="background-image: url(./assets/img/header.png)"
></div>
But this does:
<img src="./assets/img/header.png" alt="Header" />
The URL needs to be resolved with import in <script>. #vue/compiler-sfc does not automatically resolve the URLs in <div>.style, but it does for <img>.src, which is why your second example works correctly.
Solution
Use the import keyword in a <script> block to expose the resolved image URL to the template:
<script setup>
import imagePath from '#/assets/logo.svg'
</script>
<template>
<div class="logo" :style="{ backgroundImage: `url(${imagePath})` }"></div>
</template>
<style>
.logo {
height: 400px;
width: 400px;
}
</style>
demo
This is due to vite can't handle alias by default, so we need to set up an alias in vite config file.
there is no need to setup the import image in script tag.
just put the below code in vite.config.js file
import { defineConfig } from "vite";
import vue from "#vitejs/plugin-vue";
import path from "path";
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
"#": path.resolve(__dirname, "/src"),
"~#": path.resolve(__dirname, "/src"),
},
},
});

Resources