Change the Vue3 PrimeVue theme or CSS file with a simple click or upon page load

One way to incorporate themes is by importing them in the main.js file at the root of the app:

import 'primevue/resources/themes/arya-orange/theme.css';

However, I am exploring ways to dynamically switch CSS files based on the user's system theme and selection. Therefore, I moved this logic into my main App.vue:

export default {
  name: "App",
  components: {
    HelloWorld,
    toDo,
  },
  mounted() {

    //window.matchMedia('(prefers-color-scheme: dark)').matches ? do dark : do light
  },
};

<style>
@media (prefers-color-scheme: dark) {
  @import url("primevue/resources/themes/bootstrap4-dark-blue/theme.css");
}
@media (prefers-color-scheme: light) {
  @import url("primevue/resources/themes/bootstrap4-light-blue/theme.css");
}
</style>

I cannot import anything inside mounted, and importing inside media queries within style tags is not considered correct usage.

After researching, I could not find any alternative solutions or guidance to resolve this issue. The existing solutions mainly focus on scoping components and using classes.

One approach I could consider is consolidating all rules for one theme under:

@media (prefers-color-scheme: dark) {

and another set for the light theme. However, this does not address how to switch themes based on user selection.

EDIT:

I managed to make it work upon loading:

(async () => {
  if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
    await import('primevue/resources/themes/bootstrap4-dark-blue/theme.css');
  } else {
    await import('primevue/resources/themes/bootstrap4-light-blue/theme.css');
  }
})();

Additionally, on user click, the initial import can be overridden with:

  methods: {
    theme() {
      (async () => {
          await import("primevue/resources/themes/bootstrap4-light-blue/theme.css");
      })();
    },
  },

HOWEVER, when attempting to toggle back to the original theme upon click, nothing happens. This might be due to the dark theme being loaded initially if the system was set to dark. As a result, toggling back to the dark theme upon click does not take effect because it was already loaded initially.

Any suggestions would be greatly appreciated.

Answer №1

To achieve the desired outcome, one method is to follow the approach adopted on the PrimeVue website. Essentially, the css theme is incorporated by including a link in the index.html file:

<!DOCTYPE html>
<html lang="en">
    <head>
...
<link id="theme-link" rel="stylesheet" href="<%= BASE_URL %>themes/saga-blue/theme.css">
    </head>
    <body>
...
    </body>
</html>

For reference and demonstration, please view this specific example.

In order to dynamically switch themes, you can implement a function similar to this one:

changeTheme(event) {
    let themeElement = document.getElementById('theme-link');
    themeElement.setAttribute('href', themeElement.getAttribute('href').replace(this.theme, event.theme));
    this.theme = event.theme;
    this.activeMenuIndex = null;
    EventBus.emit('change-theme', event);
    this.$appState.darkTheme = event.dark;
    if (event.theme.startsWith('md')) {
        this.$primevue.config.ripple = true;
    }
    localStorage.setItem('theme', this.theme);
}

This methodology mirrors the practices outlined in the PrimeVue documentation. For further insight, visit this associated resource.

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

Is there a way to load an image onto the ngx-image-cropper without triggering the imageChangedEvent event?

My latest project involved creating a custom cropper using ngx-image-cropper, which allows for cropping and rotating images. For the sprint demo, I needed the images to be displayed as soon as the application loads without having to trigger the fileChangeE ...

What is the best way to destructure an array enclosed within the Promise keyword in JavaScript?

Currently, I am attempting to extract information from a PSQL table using the following code: async function requestData() { var selectQuery = `SELECT "fName", "lName", "phoneNumber", "eMail" FROM public."Use ...

Ways to attach dynamic methods within a v-for loop

I am currently working on a situation where I need to dynamically assign methods to elements that are being generated by a template using a v-for loop. These methods will be assigned based on the value of a particular variable, specifically the 'btn.m ...

exploring the realm of creating constants in AngularJS functions

controller.js angular.module('app.main') .controller('MainCtrl', function ($scope, currentUser, addAPI) { $scope.form = {}; $scope.subdomain = currentUser.domainName; $scope.add = function () { addAPI.addAdmin(loc ...

What is the process for creating a register command using discord.js and MongoDB Atlas?

How can I save my Discord member data using a register command? Please provide assistance! bot.js client.on("message", msg => { if (msg.content === "!register, ign:<input from member>, level:<input from member>"){ ...

Tips for activating multiple buttons at once

Currently, I am facing a challenge with managing three buttons that are dynamically generated within a div using v-for in Vue.js. My goal is to set an active class on the clicked button while removing the active class from the previously selected button. A ...

What happens with the styling in this project when the CSS file is blank?

As a first-year CS student in university, I have been diving into the world of React.js. Currently, I am exploring a resume project and noticed that both app.js and index.js files are empty. I am curious to know how the styling is achieved in this project. ...

Is it possible to transfer values to Vue.js from within a server-rendered template (e.g. merging a Vue.js application with a django template)?

Is it possible to transfer values from a server-rendered template to Vue.js (e.g. linking a Vue.js app with a django template)? Possible Uses Enhancing specific pages within a server-rendered environment: Incorporate a basic Vue application on a singl ...

Utilize AJAX to accurately capture and handle error codes

Here is a snippet of code that I want to send to my server: $.ajax({ type: 'POST', url: 'post.php', data: { token: '123456', title: 'some title', url: 'http://somedomain.com', data: & ...

Guide on utilizing an NPM package with Vue that mandates the usage of the Node.js filesystem (fs) functionality

Whenever I try to utilize an NPM package in Vue that relies on fs, it consistently fails and throws errors. The error messages usually mention something like "fs could not be resolved" or "fs.readFileSync is not a function". I have come across other sourc ...

Unable to establish connection to MongoHQ using Node.js connection URL

I have successfully set up and run a Node.js app using my local development MongoDB with the following settings and code: var MongoDB = require('mongodb').Db; var Server = require('mongodb').Server; var dbPort = 27017; v ...

Ways to access and delete the canvas using ref steps?

Having a canvas in a react component, I utilized react refs to access the node and implemented a destroy() method. However, I encountered an error: TypeError: canvasRef.current.destroy is not a function How can we properly access the node (canvas) using r ...

Checking validation with parsley.js without triggering form submission

I have been working with the latest release of Parsley for data validation. While it is validating my data correctly, I am encountering an issue where the form does not submit after validation is complete. I have spent hours trying to troubleshoot this pro ...

Beware of UTF-8 Decoding Problems: Avoid using "0"-prefixed octal literals and octal escape sequences as they are outdated. For octal literals, opt for the "0o" prefix

I've hit a roadblock trying to achieve this task, any assistance would be greatly appreciated. I have a string that looks like this "jas\303\241nek" and I need to convert it to look like "jasánek". After using [this web ...

How to properly implement envMap in Three.js?

Could someone assist me in finding a material similar to the one shown here? I attempted to implement it using the following code: * { margin: 0; padding: 0; } .object { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: no ...

Develop an array using a variable's value in JavaScript

I need assistance with creating an array of variable length based on a dynamic value ranging from 1 to 15. The goal is to populate the array differently depending on the specific value of the variable. For instance, if the variable's value is 1, I wo ...

Struggling with configuring a 'post' endpoint in an express server problem

My goal is to validate that my client is able to successfully post information to its server. I have configured a specific 'route' on my Express server for this purpose. // server.js this is the server for the PvdEnroll application. // var ex ...

Tips for eliminating flicker upon the initial loading of a webpage caused by dynamic changes in CSS styles through JavaScript

Struggling with the load order of my CSS and JavaScript... Currently, I have a div with a blue background that is styled to appear sliced diagonally. However, upon initial page load (or CTRL+SHIFT+R), there's a brief moment where the slice effect doe ...

What are the best ways to combine, organize, and iterate through JavaScript objects?

When I run a loop, it returns a combination of integer values and objects as shown below: 2 {firstName:"John", lastName:"Doe", age:28, eyeColor:"blue"} 3 {firstName:"Jane", lastName:"Doe", age:22, eyeColor:"brown"} 1 {firstName:"Jack", lastName:"Doe", age ...

What is preventing the control from being passed back from the PHP file to the AJAX success function?

My website is built using PHP, Javascript, and AJAX. Below is the essential code snippet: JS code (AJAX function): $("#btn_add_event").click(function(){ var strSeriaze = $( "#formAddEvent" ).serialize(); url = $( "#formAddEvent" ).attr('act ...