换肤的几种实现

212 阅读1分钟

方式1:改变皮肤link元素的href地址。【以vue+element-ui项目为例】

  • 1.先准备多套皮肤的css样式文件。若是element-ui,直接elementui.github.io/theme-chalk… 下载需要的主题。然后index.html引入默认的样式文件。

image.png

  • 2.换肤的时候改变link的href的地址
<template>
  <div id="app">
    <el-radio-group v-model="themeValue" @change='changeTheme'>
      <el-radio :label="'blue'">blue</el-radio>
      <el-radio :label="'green'">green</el-radio>
      <el-radio :label="'red'">red</el-radio>
    </el-radio-group>
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view />
  </div>
</template>

<script>
export default {
  data () {
    return {
      themeValue: 'blue',
    };
  },
  created () {
  },
  mounted () {
  },
  methods: {
    //换肤功能。
    changeTheme (val) {
      const linkDom = document.querySelector('link[title]');
      linkDom.setAttribute("href", `/theme/${val}/index.css`)
    }
  },
}
</script>
<style lang="scss">
#app {
  text-align: center;
  #nav {
    padding: 30px;
  }
}
</style>

方式2:js改变scss变量,间接影响使用该变量的地方。【以vue+scss项目为例】

  • 1.App.vue
/* 定义全局的scss变量,并给定默认值 */
:root {
  /* 背景色 */
  --theme_bg_color: red;
  /* 按钮色彩 */
  --theme_button_color: yellowgreen;
}
  • 2.其它页面组件
.about {
  background: var(--theme_bg_color);
}
  • 3.换肤的地方
<el-radio-group v-model="themeValue" @change='changeTheme'>
  <el-radio :label="'blue'">blue</el-radio>
  <el-radio :label="'green'">green</el-radio>
  <el-radio :label="'red'">red</el-radio>
</el-radio-group>

//换肤功能。父辈标签上设置。会直接影响到所有使用该变量的地方
changeTheme (val) {
  document.documentElement.style.setProperty("--theme_bg_color", val);
}

方式3:修改顶级id等类名

  • 1.index.html
<!-- 加上id是为了给默认样式 -->
<body id="body-theme-blue">
  <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>
  <!-- built files will be auto injected -->
</body>
  • 2.新建theme.scss,不同的id选择器引入不同的样式文件
#body-theme-blue {
  @import './theme/theme-blue.scss';
}

#body-theme-orange {
   @import './theme/theme-orange.scss';
}
  • 3.main.js引入theme.css
import ElementUI from 'element-ui';
// import 'element-ui/lib/theme-chalk/index.css';
import './theme.scss'
Vue.use(ElementUI);
  • 4.新建theme-blue.scss + theme-orange.scss
$--color-primary: #409EFF !default;
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";


$--color-primary: orange !default;
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";

  • 5.换肤
<el-radio-group v-model="themeValue" @change='changeTheme'>
  <el-radio :label="'blue'">blue</el-radio>
  <el-radio :label="'orange'">orange</el-radio>
</el-radio-group>

 //换肤功能。
changeTheme (val) {
  document.body.setAttribute("id", `body-theme-${val}`)
}