How to load SCSS files dynamically based on the result of Axios in Vue JS

Viewed 497

In my Vue application, I want to change the theme dynamically. ie, I had created 3 different themes for different types of users and also I had created an API call to identify the logged-in user type. Based on this result of the API call, I want to change the theme of the Vue application. The theme files in SCSS and I have attached my App.vue file below.

<template>
  <div id="app">
    <component :is="layout">
    </component>
  </div>
</template>

<script>
  import Pages from "./mixins/PagesScripts";

  const defaultLayout = "default-layout";
  export default {
    name: 'App',
    computed: {
      layout() {
        // TODO: Implement more layout and layout rendering mechanisms here
        return defaultLayout;
      }
    },
    mixins: [Pages],
    mounted(){
      // Here I will call the API using Axios and based on the API result, I want to change the 
      // below SCSS file to pages1,pages2 etc..
    }
  };
</script>
<style lang="scss">
  @import "assets/scss/pages";
</style>

I am using Vue-CLI version 4.4.6.

1 Answers

If you don't want to load all themes at once (themes are heavy or you have many of them) - Injecting <link> into a header is an option. But this isn't very flexible for the development process and for the user experience.

// ...
  methods: {
    injectThemeLink(themeFile){
      this.file = document.createElement('link');
      file.rel = 'stylesheet';
      file.href = file
      document.head.appendChild(file)
    },

    updateThemeFile(themeFile){
      this.file.setAttribute('href', themeFile)
    }
  }
// ...

A more simple approach - is loading all themes to make switching smooth for the user. But generally, you can define theme as a set of CSS-vars and change it depending on, let's say, <body> attribute like:

<body theme="red">...</body>

And use like this:

/* all.css */
::root {
  --text-color: black;
}
/* red.css */
body[theme=red]{
  --text-color: red;
}

/* green.css */
body[theme=red]{
  --text-color: green;
}

/* in components */
p { 
  color: var(--text-color);
}
Related