Apparently, in the last few PrimeVue updates there has been a PrimeVue.changeTheme()
method that I would very much like to use. The documentation says that two things are required.
resources/themes
folder and placing them under the public folder.index.html
file, create links to these styles along with giving them an ID so that this ID is later passed to the function.So that's what I did but the solution doesn't quite work, perhaps I'm misunderstanding something. Link to docs: https://v3.primevue.org/theming/
index.html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<link id="lara-dark-purple-link" rel="stylesheet" href="/themes/lara-dark-
purple/theme.css">
<link id="lara-light-purple-link" rel="stylesheet" href="/themes/lara-light-
purple/theme.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
Here is code from component which hold buttons with theme changing:
<script setup>
import { onMounted } from 'vue';
import { usePrimeVue } from 'primevue/config';
const PrimeVue = usePrimeVue();
const toggleDarkMode = () => {
PrimeVue.changeTheme('lara-dark-purple', 'lara-dark-purple', 'lara-dark-purple-link', () => {});
}
const toggleLightMode = () => {
PrimeVue.changeTheme('lara-light-purple', 'lara-light-purple', 'lara-light-purple-link', () => {});
}
</script>
My folder structure:
Your solution is almost correct. You just didn't understand the use of the <link>
id
, but no problem, let me quickly summarize it for you:
Second part is making the theme.css accessible via a link element...
<!-- Add default theme url to href | now default is light -->
<link id="id-to-link" rel="stylesheet" href="/themes/lara-light-purple/theme.css">
your-id
in function as 3rd parameter....so that the id of the link can be provided as the 3rd parameter to the changeTheme function.
// if current theme is dark
const selectLightTheme = () => {
// 1. Current theme name
// 2. Next theme name
// 3. id of <link>, what reference to where set theme css file
PrimeVue.changeTheme('lara-dark-purple', 'lara-light-purple', 'id-to-link', () => {});
}
// if current theme is light
const selectDarkTheme = () => {
// 1. Current theme name
// 2. Next theme name
// 3. id of <link>, what reference to where set theme css file
PrimeVue.changeTheme('lara-light-purple', 'lara-dark-purple', 'id-to-link', () => {});
}
Source from documentation: https://v3.primevue.org/theming/
<!-- Add default theme url to href | now default is light -->
<link id="id-to-link" rel="stylesheet" href="/themes/lara-light-purple/theme.css">
import { ref } from 'vue';
import { usePrimeVue } from 'primevue/config';
// set default theme folder-name to currentTheme
const currentTheme = ref('lara-light-purple'); // lara-light-purple or lara-dark-purple (1st parameter)
const PrimeVue = usePrimeVue();
// change current theme to next
const toggleTheme = () => {
// What is next theme? (2nd parameter)
let nextTheme = 'lara-light-purple';
if (currentTheme.value === 'lara-light-purple') nextTheme = 'lara-dark-purple';
else if (currentTheme.value === 'lara-dark-purple') nextTheme = 'lara-light-purple';
// 1. Current theme name
// 2. Next theme name
// 3. id of <link>, what reference to where set theme css file --> fix, single id to <link>
PrimeVue.changeTheme(currentTheme.value, nextTheme, 'id-to-link', () => {});
// So current theme now:
currentTheme.value = nextTheme;
}
// CDN Vue Import
const { createApp, ref } = Vue
const app = createApp({
setup() {
// set default theme folder-name to currentTheme
const currentTheme = ref('lara-light-purple'); // lara-light-purple or lara-dark-purple (1st parameter)
// const PrimeVue = usePrimeVue(); // If I were not using CDN, my PrimeVue variable would not exist yet. In that case, I would need to declare it with the usePrimeVue() function loaded from primevue/config
// change current theme to next
const toggleTheme = () => {
// What is next theme? (2nd parameter)
let nextTheme = 'lara-light-purple';
if (currentTheme.value === 'lara-light-purple') nextTheme = 'lara-dark-purple';
else if (currentTheme.value === 'lara-dark-purple') nextTheme = 'lara-light-purple';
// PrimeVue.changeTheme('lara-light-purple', 'lara-dark-purple', 'id-to-link', () => {});
// --> The usePrimeVue() function is not available in the CDN version, so I am currently implementing a native JS solution in place of changeTheme (the only additional task is to ensure the FULL URL for both templates)
// Native JS Solution:
document.getElementById('id-to-link').href = `https://cdn.jsdelivr.net/npm/[email protected]/resources/themes/${nextTheme}/theme.css`
// So current theme now:
currentTheme.value = nextTheme;
}
return { toggleTheme }
},
components: {
"Button": primevue.button,
},
template: `
<Button label="Click to Toggle Theme" @click="toggleTheme" />
`
}).mount('#app')
<!-- Core Vue -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js"></script>
<!-- Core Primevue -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/resources/primevue.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/core/core.min.js"></script>
<!-- Add default theme url to href | now default is light -->
<link id="id-to-link" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/resources/themes/lara-light-purple/theme.css">
<!-- App -->
<div id="app"></div>