starmusic-pc
1/**
2 * 外观混入(主题色 + 自定义背景图)
3 *
4 * 用法:
5 * import themeMixin from '../../common/theme-mixin.js'
6 * export default { mixins: [themeMixin], ... }
7 * <view class="page" :style="themeStyle">
8 * <view v-if="bgStyle" class="bg-image" :style="bgStyle" />
9 *
10 * 提供:
11 * - themeStyle:注入页面根元素的 CSS 变量(主题色 + 背景图启用时的内容层透明变量)
12 * - themeColor:当前主题主色,供无法用 CSS 变量的场景使用(如 slider activeColor)
13 * - bgStyle:自定义背景图样式;未启用时为 null,页面据此决定是否渲染背景层
14 * 主题或背景图设置变化时自动刷新。
15 */
16import { buildThemeStyle, getTheme, applyTabBarTheme } from './theme.js'
17import { buildBgStyle, buildBgVars } from './background.js'
18import event from './event.js'
19
20/** 页面根元素样式:主题变量 + 背景图透明变量(未启用背景图时后者为空) */
21const buildPageStyle = () => ({ ...buildThemeStyle(), ...buildBgVars() })
22
23export default {
24 data() {
25 return {
26 themeStyle: buildPageStyle(),
27 themeColor: getTheme().color,
28 bgStyle: buildBgStyle(),
29 }
30 },
31 created() {
32 this._offTheme = event.on('settingUpdated', (keys) => {
33 if (!keys || keys.indexOf('common.theme') >= 0) this.refreshTheme()
34 if (!keys || keys.some((key) => key.indexOf('common.bgImage') === 0)) this.refreshBackground()
35 })
36 },
37 onShow() {
38 // tabBar 页面显示时同步原生 tabBar(覆盖启动阶段引擎未就绪、主题刚切换等场景)
39 applyTabBarTheme()
40 // 广播「页面已显示」:手机端自绘导航栏据此重算当前路由来刷新高亮。
41 // 不能只在组件 mounted 时读路由 —— App 端新建页面在 mounted 阶段还不是栈顶,
42 // getCurrentPages() 读到的仍是上一个页面,表现为切 tab 后高亮停在原来的 tab 上,
43 // 要再点一次才对齐。onShow 时页面已是栈顶,读到的路由才是正确的。
44 // 桌面端没有自绘导航栏(tabBar API 为空实现),保持与手机端同一份代码。
45 event.emit('pageShow')
46 },
47 beforeUnmount() {
48 if (this._offTheme) {
49 this._offTheme()
50 this._offTheme = null
51 }
52 },
53 methods: {
54 /** 主题变化:刷新主色与页面变量 */
55 refreshTheme() {
56 this.themeColor = getTheme().color
57 this.refreshPageStyle()
58 },
59 /** 背景图变化:刷新背景层样式与内容层透明变量 */
60 refreshBackground() {
61 this.bgStyle = buildBgStyle()
62 this.refreshPageStyle()
63 },
64 /** 重新合并页面根元素样式 */
65 refreshPageStyle() {
66 this.themeStyle = buildPageStyle()
67 },
68 },
69}