切图妞

vuePress-theme-reco 切图妞    2020 - 2021
切图妞 切图妞
前端知识梳理
  • Vue
  • 浏览器 & 网络
  • HTML & CSS
  • Web安全
  • 算法
文章分类
  • 前端小麻烦
  • 配置乐园
  • 实战不完全手册
  • 手撕源码
宝藏女孩
  • 模板仓
  • 项目简介
  • GitHub
  • Segmentfault
  • CSDN
时间轴
author-avatar

切图妞

19

Article

18

Tag

前端知识梳理
  • Vue
  • 浏览器 & 网络
  • HTML & CSS
  • Web安全
  • 算法
文章分类
  • 前端小麻烦
  • 配置乐园
  • 实战不完全手册
  • 手撕源码
宝藏女孩
  • 模板仓
  • 项目简介
  • GitHub
  • Segmentfault
  • CSDN
时间轴

小程序换肤功能

vuePress-theme-reco 切图妞    2020 - 2021

小程序换肤功能

切图妞 2020-06-10 小程序

需求是希望从后台进行的颜色配置。接口请求获取颜色后进行整套换肤。网上的小程序换肤大多是几套固定的颜色进行更换,无法满足这种灵活的方案。主要解决:js如何转成css;分享时到每个页面都能拿到最新配色;尽量减少代码减少请求进行全局配置

需求是希望从后台进行的颜色配置。接口请求获取颜色后进行整套换肤。网上的小程序换肤大多是几套固定的颜色进行更换,无法满足这种灵活的方案,难点在于:

  • js如何转成css
  • 分享时到每个页面都能拿到最新配色
  • 尽量减少代码减少请求进行全局配置

# css变量

使用下面demo的方法,可以将js的颜色转到css中使用

let myStyle = `--color:blue;` 
this.setData({
    myStyle: myStyle,
})
1
2
3
4
< view class = "container"
style = "{{myStyle}}" >
    <
    text > qietuniu < /text> < /
view >
1
2
3
4
5
 .container {
     background: var(--color);
 }
1
2
3

# 全局混入

采用混入的方法结合生命周期onLoad,实现进入小程序时调用获取颜色接口。

# 混入配置

modules文件夹中新建mixins. js文件

if (!Object.entries) {
    Object.entries = function(obj) {
        var ownProps = Object.keys(obj),
            i = ownProps.length,
            resArray = new Array(i); // preallocate the Array
        while (i--)
            resArray[i] = [ownProps[i], obj[ownProps[i]]];

        return resArray;
    };
}

// 保存原生的 Page 函数
const originPage = Page

Page = (options) => {
    const mixins = options.mixins
    // mixins 必须为数组
    if (Array.isArray(mixins)) {
        delete options.mixins
        // mixins 注入并执行相应逻辑
        options = merge(mixins, options)
    }
    // 释放原生 Page 函数
    originPage(options)
}

// 定义小程序内置的属性/方法
const originProperties = ['data', 'properties', 'options']
const originMethods = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap']

function merge(mixins, options) {
    mixins.forEach((mixin) => {
        if (Object.prototype.toString.call(mixin) !== '[object Object]') {
            throw new Error('mixin 类型必须为对象!')
        }
        // 遍历 mixin 里面的所有属性
        for (let [key, value] of Object.entries(mixin)) {
            if (originProperties.includes(key)) {
                // 内置对象属性混入
                options[key] = {
                    ...value,
                    ...options[key]
                }
            } else if (originMethods.includes(key)) {
                // 内置方法属性混入,优先执行混入的部分
                const originFunc = options[key]
                options[key] = function(...args) {
                    value.call(this, ...args)
                    return originFunc && originFunc.call(this, ...args)
                }
            } else {
                // 自定义方法混入
                options = {
                    ...mixin,
                    ...options
                }
            }
        }
    })
    return options
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

在app. js中引入

	require('./modules/mixins.js')
1

# 颜色混入

modules文件夹中新建colorMixins. js文件 有设置时采用设置配色,无设置时采用默认配色

const app = getApp();
module.exports = {
    data: {
        primaryColor: `--primary: #fe9a69;--second: #ff6d5a;--price: #ff6d5a;` ,
        primaryTheme: '#fe9a69'
    },
    onLoad() {
        this.getPrimaryColor()
    },
    getPrimaryColor() {
        app.getPrimaryColor(['theme']).then(res => {
            const theme = res.theme
            if (theme && theme.color) {
                this.setData({
                    primaryColor: `--primary: ${theme.color.color1};--second: ${theme.color.color2};--price: ${theme.priceColor.color}` ,
                    primaryTheme: theme.color.color1
                })
            } else {
                this.setData({
                    primaryColor: `--primary: #fe9a69;--second: #ff6d5a;--price: #ff6d5a;` ,
                    primaryTheme: '#fe9a69'
                })
            }
        })
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 使用

# 页面级

页面js中注入

Page({
            mixins: [require('../../../modules/colorMixin.js')]
        })
1
2
3

wxml:

< view style = "{{primaryColor}}" >
    <
    view class = "btn" > 按钮 < /view> < /
view >
1
2
3
4

wxss:

/* 主题颜色设定 */
.btn {
    background: var(--primary)
}
1
2
3
4

# 组件级

# 自定义组件

只要页面级有设置颜色,子组件也能拿到,只要在样式文件里设置颜色即可。建议小程序每个页面只有一个父节点,通过设置最上层等父节点即可实现子孙节点获取到动态颜色的操作。

# switch/radio等组件

需要直接在页面中使用颜色变量,

<
switch color = '{{primaryTheme}}' / >
1
2