Customizing the appearance of a Vue.js Single Page Application with

I have a custom-built Vue.js single page application and I am interested in implementing user-switchable dynamic themes. I envision a scenario where users can easily toggle between 'light' and 'dark' themes by clicking a button, and have the entire app update instantaneously to reflect their selection. Additionally, I want all the theme scss files to be stored locally for better control.

While I came across this resource, it falls short as it does not address the issue of using local theme files.

const themes = {
  flatly: "https://bootswatch.com/4/flatly/bootstrap.min.css",
  materia: "https://bootswatch.com/4/materia/bootstrap.min.css",
  solar: "https://bootswatch.com/4/solar/bootstrap.min.css"
};

I attempted to modify the answer provided by replacing the external links with local paths:

const themes = {
  dark: "dark-theme.scss",
  light: "light-theme.scss"
};

However, this approach seems to be ineffective due to potential Webpack or compilation issues that prevent the inclusion of scss files in the project.

In my exploration, I discovered that manually linking the theme files in the index.html file allows them to appear in the client source:

<link rel="stylesheet" type="text/css" href="<%= BASE_URL %>dark-theme.scss">

Yet, I struggle with understanding how to reference these files within the application itself. For instance, referencing

http://localhost:8080/dark-theme.scss
might not work in production.

I also investigated other resources like:

  • this post, which encounters similar hurdles to the one mentioned above
  • this thread, focusing on scss variables without accommodating attribute modifications
  • this article, proposing an approach involving theme-aware components

Moreover, I tested importing the scss files directly in the main.ts file, which successfully added them to the head section but did not enable seamless switching between themes. The lack of identifiable classes or IDs made it challenging to manipulate them effectively.

<style type="text/css" >
  ...
</style>

Answer №1

Main.ts:

import "@/path/to/dark-theme.scss"
import "@/path/to/light-theme.scss"

Dark-theme.scss:

body.dark {
  /* custom styles for dark theme */
}

Light-theme.scss:

body.light {
  /* custom styles for light theme */
}

Index.html (or loading based on local storage or OS settings):

<body class="light">

Add the following code where you want to implement the theme switch:

methods: {
  toggleTheme() {
    document.body.classList.toggle('dark')
    document.body.classList.toggle('light')
  }
}

Answer №2

One neat little trick just popped into my head that you might find useful. Try creating two empty components for your theme in the following way:

<template><div></div></template>
<script>export default {name: 'CustomTheme'}</script>
<style>
  @import "~@/path/to/theme.scss"
</style>

Now, within your application, you can conditionally render these two components using v-if like this:

<custom-theme v-if="theme == 'custom'"/>
<default-theme v-if="theme == 'default'"/>

Note: Please keep in mind that this code has not been tested yet.

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

Trigger a click event to alter the child div elements

I have a <div> that expands when clicked and shrinks back when clicked again. Inside this div are images that should only appear once the div expands. My issue is ensuring that all images except the first one are hidden until the div expands. https: ...

Display data in Highchart legend only if it has values

In a unique scenario, I am required to compare various items and display the results in a chart. The user inputs two, three, or four article IDs and receives the corresponding data displayed in a chart. The issue arises when the user enters only two or th ...

I'm having trouble with my Laravel edit page not functioning properly when using vue.js. Can anyone help me troubleshoot

Currently, I am developing a dashboard to display details. Users can click on the edit button to modify their information. However, when I try to edit by clicking the button, nothing happens. It seems like the editing feature is not functioning properly, a ...

Ways to achieve varying border widths among multiple divs that are linked to text size

Hey there, I'm looking to make some changes to the UI of my game. I want to transform it from this: https://i.sstatic.net/iLpFY.jpg To this (which is an edited version using paint.net of the previous image): https://i.sstatic.net/qudVm.jpg <html& ...

How can I eliminate whitespace from Vue's compiled output?

Why isn't the preserve whitespace feature functioning properly in Vue? The generated code appears to have excessive whitespace: _vm._v( "\n " + _vm._s(_vm.object.created_by_full_name) ...

IE presenting problems with JQuery content loaded via Ajax

I operate a website that showcases various products, each with a corresponding link to a fancybox displaying detailed information about the product (detailed.php file). <a class="fancy fancy'.$_GET['type'].'" href="detail.php?id=&ap ...

What is the best way to set up a dropdown menu in a data grid where the width matches the fields?

I am looking to optimize the layout for various screen resolutions and ensure compatibility with the latest versions of IE, Firefox, and Chrome. https://i.sstatic.net/3OLh0.jpg ...

Method for extracting URL parameters while utilizing a hash within the URL

I've been exploring AJAX with hash in URL using prototypejs. Consider the following URL: http://example.com/#/example/104?v=0&d=a&rpp=10 print_r( $_GET ); // output: array() However, when I try this URL: http://example.com/example/104?v= ...

Converting a for loop into a fixed-size array?

I am currently developing a backbone application and have been given some sample code by the provider. The code includes a for loop that generates player names as 'player_1', 'player_2', and so on. However, I would like to manually ente ...

Is it possible to position a border outside of the parent element's constraints?

Struggling with a design challenge that requires me to create a UI like the one shown in the following image. This is how the closed accordion state looks: https://i.sstatic.net/THVgr.png And here is the open accordion state. Notice the red circled area ...

Transforming an array into key-value pairs where the keys are odd elements and the values are even elements

Is there a straightforward way to transform this initial array: [ "Bargain", "deal", "Consistent", "Steady; regular", "Accurately", "a thing bought or offered for sale much more cheaply than is usual or expected.", "Charge", "demand (an am ...

Angular tutorial: Accessing individual HTML elements within the *ngFor loop

I am facing an issue trying to access the "box-message" class using "document.querySelectorAll('.box-message')" within a tree structure where the "*ngFor" directive is utilized. After making an "http rest" request, the *ngFor directive finishes ...

Angular directive: inability to pass ng-repeat item through isolate scope

I am currently working on a directive that has an isolate scope. The template of the directive includes an ng-repeat on an element, along with the following code snippet: ng-click="selection(item)" Within the directive's scope definition, I have spe ...

"Utilizing JavaScript to Disable a MenuItem in ASP .NET: A Step-by-Step

I have successfully designed a customized menu interface using ASP.NET. <asp:Menu ID="Name1" runat="server" OnMenuItemClick="DoSth_MenuItemClick" Visible="true"> <Items> <asp:MenuItem Text="Function description" Value="Val" ToolTip=" ...

Ways to conceal the lower details in DataGrid Material-UI

Utilizing the DataGrid component from MUI and I'm eager to conceal this element. Any suggestions on how I can achieve this? Thanks! https://i.sstatic.net/2YG9s.png ...

Guide on parsing a JavaScript file and converting the default export module to JSON with Node.js

What I'm trying to accomplish in my Node.js project is reading a sample.js file with ES Module syntax and extracting the default export from it. sample.js import foo from "foo"; const bar = [ { name: "Homer", }, { n ...

python and html tutorial for adding text from bottom to top

Looking for help with rearranging lines in an HTML file? If you want the lines to be displayed in reverse order, here's an example: (1) (2) (3) You need them to appear like this: (3) (2) (1) try: record_cam.strHandler ...

Use a personalized CSS class with the Kendo Dropdown Widget

Is there a way to assign a custom CSS class to the dropdown HTML container that is created when using the .kendoDropDownList() method on a <select> or <input> element? In this fiddle ( http://jsfiddle.net/lav911/n9V4N/ ) you can see the releva ...

Steps for accessing specific menu div on a new tab

I'm facing an issue with my one page website. Whenever I click on a menu item, it directs me to a specific div tag on the page. However, if I right-click on a menu item and select 'open in new tab', it opens the URL "www.mysite.com/#" instea ...

"Exploring the World Wide Web with Internet Explorer Driver and Webdriver

After trying everything I know to make internet explorer work with webdriver.io, I've encountered a confusing issue. To start, download the internet explorer driver from this link: http://www.seleniumhq.org/download/. The file is an .exe named ' ...