由于小程序支持 CSS 变量,可以比较方便地实现换肤功能。页面中的动态颜色使用 CSS 变量取值,通过 js 控制内联样式(inlined styles)或切换不同的样式类(css classes),实现 CSS 变量的动态切换,从而达到换肤的目的。

方案实现

Step 1: 定义 CSS 变量

将 CSS 变量定义在主题的样式类中,并在入口文件中引入:

// theme.css
.theme-1 {
    --color-primary: red;
}
.theme-2 {
    --color-primary: blue;
}

Step 2: 引入 CSS 变量

这里使用 i18n 的思路,将每个主题样式类定义为 i18n 中的一个 locale,再引入到每个页面中。

// i18n.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';

Vue.use(VueI18n);

const i18n = new VueI18n({
    locale: 'vendorA',
    messages: {
        vendorA: {
            theme: {
                css: 'theme-1',
            },
        },
        vendorB: {
            theme: {
                css: 'theme-2',
            },
        },
    },
});

Vue.prototype._i18n = i18n;

export default i18n;
<template>
    <view :class="[theme.css, 'page-test']">
    </view>
</template>

<script>
    export default {
        computed: {
            theme() {
                return this.$t('theme');
            },
        },
    };
</script>

<style>
    .page-test {
        background-color: var(--color-primary, white);
    }
</style>
// main.js
import Vue from 'vue';
import App from './App';
import i18n from './i18n.js';

const app = new Vue({
  i18n,
  ...App,
});
app.$mount();

Step 3: 切换 CSS 变量

通过切换 i18n 中定义的不同的 locale 来达到切换皮肤的目的。

<template>
    <view>
        <button @click="handleClick">Click to change!</button>
    </view>
</template>

<script>
    export default {
        method: {
            handleClick() {
                this._i18n.locale = 'vendorB';
            },
        },
    };
</script>

参考文档