What are the best practices for integrating PrimeVue with CustomElements?

Recently, I decided to incorporate PrimeVue and PrimeFlex into my Vue 3 custom Element. To achieve this, I created a Component using the .ce.vue extension for the sfc mode and utilized defineCustomElement along with customElements.define to compile it as a web component. Afterward, I implemented it in the index.html file to test its functionality in the Browser.

While the setup partially worked, there were some issues. One key challenge was figuring out how to translate app.use(PrimeVue) for my specific 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);

//Setting up VueApplication for testing/reference, which is functioning correctly. 
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>

Although the PrimeVue-Autocomplete feature displays, the styles are not rendering correctly.

Therefore, my primary question remains:

How can I fully utilize all aspects of PrimeVue within a custom Component?

In simple terms, how do I configure a Vue 3 CustomElement with PrimeVue successfully?

Answer №1

After some experimentation, I've discovered a workaround that does the job (although not in an ideal way). To ensure everything runs smoothly, it's best to import the styles and js/ts modules directly into the component(s) themselves.

The primary styles should be imported into the root component of the web component for optimal functionality. This necessity arises from:

I encountered difficulties while attempting to properly import primeflex, so I resorted to utilizing the cdn link. However, I believe internal imports are feasible, and I will update this answer once I've figured out the process.

To utilize a specific PrimeVue component, follow the guidelines provided in the documentation for importing and registering it.

<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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d3a3a1babeb6b5bfb6ab93e0fde2fde3">(protected email)</a>/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));

However, there is a limitation: Because of the absence of plugin support (or my lack of awareness about it), the following lines:

import PrimeVue from 'primevue/config';
app.use(PrimeVue);

are not viable options. Unfortunately, I can't fully predict the consequences this might entail.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transformer Class: An object containing properties that are instances of another class

class ClassA { x: number; y: number; sum(): number { return this.x + this.y; } } class ClassB { @Type(() => ClassA) z: {[key: string]: ClassA}; } const b = transformObject(ClassB, obj); const z = b.z[key]; const s = z.s ...

Utilizing HTML and JavaScript to dynamically switch stylesheets based on the width of

When it comes to using stylesheets for mobile and non-mobile devices, there is a need for different approaches. The idea of comparing browser height and width in JavaScript seems like a good one, but the implementation may not always work as expected. ...

To ensure proper display, the canvas should be set to display block when its width is 100vw and height is 100vh

Can anyone explain why I need to include display: block when my canvas is full page? Without it, the canvas size appears larger even though the width and height values are the same. Appreciate any insights. Thanks! ...

Columns in Bootstrap4 housing elements positioned absolutely

Recently, I've been developing a game that involves using absolute positioning for certain elements. This is necessary for creating moving animations where elements need to slide around and overlap to achieve a specific effect. As I focus on optimizi ...

Having trouble vertically aligning text in Bootstrap 4?

I'm having trouble getting the text to align vertically in the middle and closer to the image. The vertical-align:middle property doesn't seem to be working for me. Additionally, when I resize the screen width, the layout changes from a horizonta ...

Import JSON data into Angular 2 Component

After much effort, I have finally figured out how to load JSON data into an Angular 2 Component. datoer.service.ts: import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import { Observable } from ...

Setting the value in an Autocomplete Component using React-Hook-Forms in MUI

My form data contains: `agreementHeaderData.salesPerson ={{ id: "2", name: "Jhon,Snow", label: "Jhon,Snow", value: "<a href="/cdn-cgi/l/email-prot ...

Picking up Angular component property values within a callback function from Google Charts

Trying to utilize the angular-google-charts library in Angular 13.2, I am working on creating a TreeMap with a customized tooltip feature. The GoogleChartComponent offers an options property called generateTooltip which requires a callback function. My goa ...

Display an API generated popup list using Vue's rendering capabilities

I'm attempting to generate a pop-up within a displayed list using custom content retrieved from an API request. Currently, my code looks like this: <template> <div class="biblio__all"> <a v-for="i in items" ...

Ways to format table using flex-wrap sans the use of flexbox

My HTML and CSS structure is as follows: .item { background: white; padding: 5px; display: inline-block; text-align: center; } .item > div { background: yellow; width: 60px; height: 60px; border-radius: 50%; display: table-cell; ...

Embed full content in iframe using bootstrap 4

Embedding an iframe of an appointment scheduling frontend on my page has been a challenge. While the width is correct, the height of the frame is too small. Despite attempting various CSS modifications, I have not been able to achieve the desired result. I ...

Using jQuery to add or remove multiple classes at once

My navigation tabs use jQuery to add and remove classes for the active tab. However, I'm facing an issue where the active class is not removed when a new tab is clicked or when the user scrolls to a new section. Please refer to the following gist for ...

What is the best way to confirm the return type of a React.Component instance?

When working with TypeScript, there is a React Component called Cell: class Cell extends Component<void, void> { ... } Using it like this: <Cell /> The return type being received is JSX.Element. However, I want to make sure that the return ...

Do you think it's wise to utilize React.Context for injecting UI components?

I have a plan to create my own specialized react component library. These components will mainly focus on implementing specific logic rather than being full-fledged UI components. One key requirement is that users should have the flexibility to define a se ...

Tips for showcasing styled text in Vue using API data

I'm having trouble formatting text in Vue. Within a component, I have a textarea that stores a string with backspaces, etc ... in an API like this: A cellar but not only...\n\nWelcome to the Nature & Wine cellar, a true Ali-baba's cave ...

Refine the observable data

Trying to filter a list of items from my Firebase database based on location.liked === true has been a challenge for me. I've attempted using the traditional filter array method but have not had success. Can anyone suggest an alternative method to acc ...

Designed radio buttons failing to activate when focused using a keyboard

I'm facing an issue with radio input buttons that I've dynamically added to a div using jQuery. They function properly when clicked with a mouse, but do not get activated when using the keyboard tab-focus state. NOTE: To style the radio buttons ...

Dealing with mistakes in an Angular service

I've been grappling with error handling in Angular. I attempted to handle errors within a service, but I'm uncertain if that's the correct approach. @Injectable({ providedIn: 'root', }) export class CaseListService { public con ...

Is there a foolproof method to verify if a user truly has visibility of a div element?

When I search online, most solutions only consider the viewport and/or the first parent container that is scrollable when trying to determine if a div is visible. However, I am wondering if there is a foolproof method to check if a div is truly visible t ...

What is the process for extracting the elements of an array fetched from a service in Angular 2?

Currently, I am learning Angular 2 + PrimeNG and going through a quick start project available at the following link: https://github.com/primefaces/primeng-quickstart The project is a CRUD application and it functions flawlessly. The data is neatly displa ...