H5换肤|小程序换肤(静态换肤|动态换肤-后端api传色值|图片)

271 阅读2分钟

h5换肤|小程序换肤(静态换肤|动态换肤-后端api传色值|图片)

  • h5|小程序 静态换肤(sass、vue)

  • h5 动态换肤(sass、vue2)

  • 小程序 动态换肤(vue3)


一、h5|小程序 静态换肤

目录结果图——大概瞅一眼

0.png

实现代码

文件:varible.scss
$theme-color : #409EFF !default;
$button-color: #409EFF !default;
$background-color: #c2cf5f !default;
文件:index.css
@import "./varible";

.background-theme{
    color: $theme-color;
    background-color: $background-color;
}
.button-theme{
    background-color: $button-color;
}
文件:/common/scss/common.scss"
$theme-color : #bd8b39;
$button-color: #d6d13d;
$background-color: #2fb282;

@import "../../themeui/index.scss";
文件:index.vue
<template>
	<view>
        <header class="header background-theme">header</header>
        <button class="button button-theme">button</button>
    </view>
</template>

<style lang="scss">
	/*每个页面公共scss */
	@import "/common/scss/common.scss";
</style>

效果

1.png


二(1)、h5动态换肤-手动切换按钮换肤【已经写了多套皮肤skin1、skin2】

  • 手动切换按钮换肤skin1、skin2

具体实现代码:

文件:index.scss

.background-theme{
    @include fontColor('theme-color');
}

.button-theme{
    @include fontColor('button-color');
}

文件:mixin.scss

// 循环$themes对象,根据传入的$themename,获取对应的$theme对象
@mixin fontColor($color) {
    @each $themename, $theme in $themes {
        // 根据传入的$themename,获取对应的$theme对象
        [data-skin='#{$themename}'] & {
            // 根据传入的$color,获取对应的颜色值
            color: map-get($theme, $color);
			border-color:map-get($theme, $color);
        }
    }
}

文件:varible.scss,文件中 !default不要忘记写

$themes:(
    default-theme:(
        // 主题色
        theme-color: #409EFF,
        button-color: #409EFF, 
        text-color: #333333,
        border-color: #DCDFE6,
        background-color: #F5F7FA, //背景色
    )
)!default;

文件:common.scss

$themes: (
    skin1: ( 
       theme-color: #f00,
	   button-color: #f00, 
    ) ,
	skin2: (
	  theme-color: #bd8b39,
	  button-color: #d6d13d, 
	) 
); 

@import "../../themeui/index.scss";
<template>
	<view> 
		<button @tap="changeSkin('skin1')">skin1</button>
		<button @tap="changeSkin('skin2')">skin2</button>
		<header class="header background-theme">header</header>
		<button class="button button-theme">button</button>
	</view>
</template>

<script>
	export default {
		methods: { 
		 // 按钮手动切换换肤
			changeSkin(skin) {
				window.document.documentElement.setAttribute('data-skin', skin)
			},
		},
		// 挂载
		created() { 
		    window.document.documentElement.setAttribute('data-skin', 'skin2')
		}, 
</script>

效果:

2.png

二(2)、h5动态换肤-根据组件属性动态传值换肤

  • 根据组件属性动态传值换肤

  • varible.scss 和 index.css 、 mixin.css文件里代码没有变化

  • 主要是common.scss、app.vue里文件有变化

  • 新增了组件 configProvider.vue

实现代码:

文件:varible.scss
$themes:(
    default-theme:(
        // 主题色
        theme-color: #409EFF,
        button-color: #409EFF, 
        text-color: #333333,
        border-color: #DCDFE6,
        background-color: #F5F7FA, //背景色
    )
)!default;
文件:index.css
@import "./varible";
@import "./mixin";

// 改为:
.background-theme{
    @include fontColor('theme-color');
}

.button-theme{
    @include fontColor('button-color');
}
文件:mixin.css
// $themes:(
//     default-theme:(
//         theme-color: #409EFF,
//         primary-color: #409EFF, 
//         text-color: #333333,
//         border-color: #DCDFE6,
//         background-color: #F5F7FA, //背景色
//     )
// )

// 循环$themes对象,根据传入的$themename,获取对应的$theme对象
@mixin fontColor($color) {
    @each $themename, $theme in $themes {
        // 根据传入的$themename,获取对应的$theme对象
        [data-skin='#{$themename}'] & {
            // 根据传入的$color,获取对应的颜色值
            color: map-get($theme, $color);
        }
    }
}
文件:/common/scss/common.scss"
// 改成:使用变量
$themes: (
    skin1: ( 
       theme-color: var(--data-theme-color, #f00),
	   button-color: var(--data-button-color, #f00),
	   background-color: var(--data-background-color, #f00)
    ) ,
	skin2: ( 
	   theme-color: var(--data-theme-color, #bd8b39),
	   button-color: var(--data-button-color, #bd8b39),
	   background-color: var(--data-background-color, #d6d13d)
	) 
); 

@import "../../themeui/index.scss";

新建组件:文件 configProvider.vue

<template>
    <view> 
          <slot></slot>
    </view>
</template>
<script>
export default {
    name: 'configProvider', 
    props: ['theme'],
    created() {
        for(let item in this.theme) {
            let _name = '--data-' + item;
            console.log(this.theme[item], _name);       
            console.log(document.querySelector(":root"));
            
            document
                .querySelector(":root")
                .style.setProperty(_name, this.theme[item])
        }
    },
}
</script>

main.js中引入: configProvider.vue

import Vue from 'vue'
import api from './common/request/http'
import App from './App' 
// 自定义组件 
import configProvider from './themeui/configProvider.vue'
 
// 全局注册组件
Vue.component('configProvider', configProvider)

Vue.config.productionTip = false

Vue.prototype.$api = api;
Vue.prototype.$site = 1;

App.mpType = 'app'

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

应用组件config-provider,文件:app.vue
根据参数传入参数::theme="{'theme-color': 'green'}",修改主题颜色
<template>
	<view> 
		<config-provider :theme="{'theme-color': 'green', 'button-color': 'green'}">
			<button @tap="changeSkin('skin1')">skin1</button>
			<button @tap="changeSkin('skin2')">skin2</button>
			<header class="header background-theme">header</header>
			<button class="button button-theme">button</button>
		</config-provider>
	</view>
</template>

<script>
	import {
		mapMutations
	} from 'vuex';
	
	export default {
		methods: { 
			changeSkin(skin) {
				window.document.documentElement.setAttribute('data-skin', skin)
			},
		},
		// 挂载
		created() {
			console.log('App onload');
			
		    window.document.documentElement.setAttribute('data-skin', 'skin2')
		}, 
		
</script>
<style lang="scss">
	/*每个页面公共scss */
	@import "/common/scss/common.scss";
</style>

效果:

3.png

注意:在小程序中目前还不支持,小程序没有document属性


三、小程序 动态换肤(uniapp+vue3)

vue3css中可以直接绑定变量,在setup()中定义的变量,具体代码如下:

<template>
	<view class="container">
	   <image :src="imageUrl" ></image>
	   <view class="box" :style="{ backgroundImage: 'url(' + imageUrl + ')' }">记得设置宽高哦</view>
	</view>
</template>

<script setup>
	import {ref,computed, onMounted,getCurrentInstance } from "vue"; 
	
    // 默认图片,可以动态加载
	const imageUrl = ref('../../static/images/page_bg.png'); 
 
	// 默认色系,可以根据后台api动态修改加载
	const backgroundColor = ref('#0D6FB8'); // 默认背景色
	const themeColor = ref('#0E357F'); // 默认字体颜色
</script>

<style lang="scss">

.container{
       // 绑定背景颜色,可以根据后台api动态修改加载
       color: v-bind('themeColor');
	   background-color: v-bind('backgroundColor');
	}
</style>

效果:

4.png