uni-app主题色的BUG

uni-app主题色的BUG
解决步骤
给App添加主题色的缓存标识
新建 __uniappview.html 文件
引入 copy-webpack-plugin 依赖
创建 vue.config.js 文件
状态栏颜色不稳定
结论
主题切换采用的方案是 css 变量,但此方案理论上可以解决任何因为切换主题而引起的闪屏
使用的编译版本是 3.1.X (也就是HBuilderx的版本号)
2.6.X 之后禁止在js内动态引入css。因为2.6.X之后好像默认都是V3版本编译,所以这是一条死路
问题初探:
uni-app 使用非nvue模式进行编译App,会使用 web-view进行渲染。调试过程中发现,在进行加载静态资源的时候会首先读取默认的配置文件,并进行App主题的初始化,并且在加载其它页面的时候也会去重载默认的配置文件,然后再以加载我们正常的业务页面,在渲染业务页面之前的这段时间内,主题色会一直保持manifest.json内默认的配置色,或在main.js文件中预先加载的主题色。所以以这个思路去处理一下加载的静态文件,以处理切换主题色后闪屏的问题。

解决步骤
给App添加主题色的缓存标识
plus.storage.setItem(“theme”, this.color)
1
这段代码是通过 HTML5+的Api,为App添加主题标识的缓存。最佳放置位置为业务页面中,切换主题色的函数内(点击按钮切换主题时触发的函数内)。

新建 __uniappview.html 文件
__uniappview.html 文件是uni-app App 模式的入口页,所以在这里修改比较合理

__uniappview.html 源文件:github

新建:__uniappview.html (建议放至 [ assets ] 目录下,默认是没有这个目录)

<head>
	<meta charset="UTF-8" />
	<script>
		var __UniViewStartTime__ = Date.now();
		var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
			CSS.supports('top: constant(a)'))
		document.write(
			'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
			(coverSupport ? ', viewport-fit=cover' : '') + '" />')
	</script>
	<title>View</title>

	<script type="text/javascript">
		function PlusReady() {

			if (typeof PlusReady.instance === 'object') {
				return PlusReady.instance
			}

			// 获取app缓存的主题类型
			this.color = plus.storage.getItem('theme')
			this.cssPath = ''
			// 根节点,用于保存页面根样式,防止切换页面闪屏的样式
			this.style = document.createElement('style')
			this.link = document.createElement('link')
			// dom 是否更新过
			this.domStatus = false

			this.setTheme = function() {
				// 依据主题类型初始化主题相关值
				if (this.color == 'black') {
					plus.navigator.setStatusBarStyle('light') // 设置原生bar主题为浅色
					this.cssPath = "static/css/black.css" // 加载深色主题
					this.style.innerText =
						`
				        body, html, #app, page {
				          background: #1E1E1E !important;
				        }
				      ` // 设置根节点为深色,防止切换页面闪白
				} else {
					plus.navigator.setStatusBarStyle("dark") // 设置原生bar主题为深色
					this.cssPath = "static/css/white.css" // 加载浅色主题
					this.style.innerText =
						`
				        body, html, #app, page {
				          background: #FFFFFF !important;
				        }
				      ` // 设置根节点为浅色,防止切换页面闪黑
				}
				// 初始化link
				this.link.type = 'text/css';
				this.link.rel = 'stylesheet';
				this.link.href = this.cssPath;
			}

			this.pushHead = function() {
				// 节点载入head
				document.head.appendChild(this.link)
				document.head.appendChild(this.style)
			}

			return PlusReady.instance = this
		}
		function plusReadyTheme (str) {
			let plusReady = new PlusReady()
			plusReady.color = plus.storage.getItem("theme")
			plusReady.setTheme()
		}
		if (window.plus) {
			let plusReady = new PlusReady()
			plusReady.setTheme()
			plusReady.pushHead()
		} else {
			// h5+ 加载后,初始化参数并添加dom到head
			document.addEventListener('plusready', function() {
				let plusReady = new PlusReady()
				plusReady.setTheme()
				if (!plusReady.domStatus) {
					plusReady.pushHead()
				}
			}, false);
		}
	</script>
	<link rel="stylesheet" href="view.css" />
</head>

<body>
	<div id="app"></div>
	<script src="__uniappes6.js"></script>
	<script src="view.umd.min.js"></script>
	<script src="app-view.js"></script>
</body>

在调试过程中发现,首先加载的是这个HTML,所以把设置主题色的代码放在了这个HTML
。这个HTML是在编译过程中导入的入口文件,每次离线打包后也可看到这个文件。

引入 copy-webpack-plugin 依赖
项目内使用的是:5.0.0 版本

npm install -S copy-webpack-plugin

1
创建 vue.config.js 文件
const path = require(‘path’)
const CopyWebpackPlugin = require(‘copy-webpack-plugin’)

module.exports = {
configureWebpack: {
plugins: [
new CopyWebpackPlugin([
{
from: path.join(__dirname, ‘assets’), // 项目内把 __uniappview.html 文件放在了 assets 目录下
force: true // 强制覆盖
}
])
]
}
}
状态栏颜色不稳定
这个问题也是默认配置的坑,初步观察的原理很简单,就是页面已经渲染出来了,但是又做了跳转当前页面动作、之类的动作,导致页面没有重新加载,但是配置重新加载了~ 所以uni-app的壳就把状态栏主题色恢复为默认了。
解决办法就是只要当前页面栈已经存在某个页面,就不做跳转之类的动作!

结论
以上方案,可解决闪屏问题,但是有一个小问题。就是在切换主题色后,切换的第一个页面还会闪一下。业务至此,接着搬下一块砖!!! 有更好的解决方案,或谁把这个遗留问题解决了下方评论,万分感激~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值