需求是希望从后台进行的颜色配置。接口请求获取颜色后进行整套换肤。网上的小程序换肤大多是几套固定的颜色进行更换,无法满足这种灵活的方案。主要解决:js如何转成css;分享时到每个页面都能拿到最新配色;尽量减少代码减少请求进行全局配置
需求是希望从后台进行的颜色配置。接口请求获取颜色后进行整套换肤。网上的小程序换肤大多是几套固定的颜色进行更换,无法满足这种灵活的方案,难点在于:
- js如何转成css
- 分享时到每个页面都能拿到最新配色
- 尽量减少代码减少请求进行全局配置
# css变量
使用下面demo的方法,可以将js的颜色转到css中使用
let myStyle = `--color:blue;`
this.setData({
myStyle: myStyle,
})
1
2
3
4
2
3
4
< view class = "container"
style = "{{myStyle}}" >
<
text > qietuniu < /text> < /
view >
1
2
3
4
5
2
3
4
5
.container {
background: var(--color);
}
1
2
3
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
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
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
2
3
wxml:
< view style = "{{primaryColor}}" >
<
view class = "btn" > 按钮 < /view> < /
view >
1
2
3
4
2
3
4
wxss:
/* 主题颜色设定 */
.btn {
background: var(--primary)
}
1
2
3
4
2
3
4
# 组件级
# 自定义组件
只要页面级有设置颜色,子组件也能拿到,只要在样式文件里设置颜色即可。建议小程序每个页面只有一个父节点,通过设置最上层等父节点即可实现子孙节点获取到动态颜色的操作。
# switch/radio等组件
需要直接在页面中使用颜色变量,
<
switch color = '{{primaryTheme}}' / >
1
2
2