VUE换肤功能实现

换肤

主题的替换无外乎替换图片和样式,下面就说一下怎样替换图片和样式

替换图片

假如我们现在有两个主题

  • theme_red
  • theme_blue

首先我们把两个主题的图片也分别放在对应的文件夹下

  • image/theme_red/xxx
  • image/theme_blue/xxx

在Config.js文件中保存主题的名称

1
export const themename = "theme_blue";

替换图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import {themename} from "../../config/Config";

const myMixin = {
mounted() {
this.changetheme()
},
updated() {
this.changetheme()
},
methods: {
changetheme: function () {
let imgs = document.getElementsByTagName("img");
for (const img of imgs) {
let src = img.src;
if (src.indexOf(themename) === -1) {
src = src.replace("/theme_blue/", "/" + themename + "/");
img.src = src;
}
}
}
}
}

export {myMixin};

在需要的页面引用

1
2
3
4
5
6
7
import {myMixin} from "./assets/js/vue_mixin";
export default {
mixins: [myMixin],
data: function () {
return {}
}
}

Tip:

混入 — Vue.js (vuejs.org)

不要只在mounted中调用更换图片,因为这样只会触发一次。导致刚开始没有生成DOM的元素的图片地址都无法替换。

mountedupdated都要调用,页面初始化的时候不会调用updated回调。

替换样式

替换样式就相对简单了

我们把页面原来的样式分别放在新建的两个样式下

1
2
3
4
5
6
7
.theme_red{
//复制原样式
}

.theme_blue{
//复制原样式
}

页面中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div :class="themename">

</div>
</template>

<script>

import {themename} from "@/config/Config";
import {myMixin} from "./assets/js/vue_mixin";
export default {
mixins: [myMixin],
data: function () {
return {
themename: themename,
}
}
</script>

Tip:

当然这样样式是冗余的,我们也可以只绑定需要修改的样式,因为我是在开发客户端时使用的,不用考虑样式的冗余。

后话

当然也可以用webpack打包多个样式,按主题加载样式,用方法返回图片的路径,在需要根据主题替换的图片上都绑定该方法。不过还是感觉我用的这个方式相对来说更简单。