ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

解决方案:uni-app非nvue模式下切换主题后,App端闪屏、闪白、闪黑、状态栏主题色不稳定

2021-03-20 17:06:08  阅读:591  来源: 互联网

标签:__ 闪白 nvue plusReady app 主题 页面 加载


uni-app主题色的BUG

  • 主题切换采用的方案是 css 变量
  • 使用的编译版本是 3.1.X (也就是HBuilderx的版本号)
  • 2.6.X 之后静止在js内动态引入css,所以这是一条死路

问题初探:
uni-app 使用非nvue模式进行编译App,会使用 web-view进行渲染。调试过程中发现,在进行加载静态资源的时候会首先读取默认的配置文件,并进行App主题的初始化,并且在加载其它页面的时候也会去重载默认的配置文件,然后再以加载我们正常的业务页面,在渲染业务页面之前的这段时间内,主题色会一直保持manifest.json内默认的配置色,或在main.js文件中预先加载的主题色。所以以这个思路去处理一下加载的静态文件,以处理切换主题色后闪屏的问题。

解决步骤

给App添加主题色的缓存标识

	plus.storage.setItem("theme", this.color)

这段代码是通过 HTML5+的Api,为App添加主题标识的缓存。

新建 __uniappview.html 文件

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

__uniappview.html 源文件:github

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

<!DOCTYPE html>
<html lang="zh-CN">

	<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
。这个HTML是在编译过程中导入的入口文件,每次离线打包后也可看到这个文件。

引入 copy-webpack-plugin 依赖

项目内使用的是:5.0.0 版本

	npm install -S copy-webpack-plugin

创建 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的壳就把状态栏主题色恢复为默认了。
解决办法就是只要当前页面栈已经存在某个页面,就不做跳转之类的动作!

结论

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

标签:__,闪白,nvue,plusReady,app,主题,页面,加载
来源: https://blog.csdn.net/h_midnight/article/details/115028510

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有