
iOS打包提示没有推送权限解决办法
如果开启了推送插件,但打包使用的iOS证书没有开通推送权限,则无法打包,需要到苹果开发者账号开启相关推送权限重新申请iOS证书再打包
推送权限只有付费的开发者才能开启。
1、首先打开开发者中心https://developer.apple.com/account,进入证书页面。
如果之前创建过appid,进去修改添加下推送服务就行了,不用重新创建。
2、点击证书、ID及配件文件,进入设置。
在identifiers项找到之前添加的需要修改相关权限的应用id点进去!
点击你要修改的应用id,然后勾选需要开通的相关推送权限保存,保存后需要重新申请描述文件证书!
注意:证书p12不用重新申请,描述文件要重新申请!(修改了权限之前的描述文件会失效)
详细的推送功能制作请看下面文档
如果开启了推送插件,但打包使用的iOS证书没有开通推送权限,则无法打包,需要到苹果开发者账号开启相关推送权限重新申请iOS证书再打包
推送权限只有付费的开发者才能开启。
1、首先打开开发者中心https://developer.apple.com/account,进入证书页面。
如果之前创建过appid,进去修改添加下推送服务就行了,不用重新创建。
2、点击证书、ID及配件文件,进入设置。
在identifiers项找到之前添加的需要修改相关权限的应用id点进去!
点击你要修改的应用id,然后勾选需要开通的相关推送权限保存,保存后需要重新申请描述文件证书!
注意:证书p12不用重新申请,描述文件要重新申请!(修改了权限之前的描述文件会失效)
详细的推送功能制作请看下面文档
收起阅读 »
Android webview隐藏后跳转新页面input输入卡顿与白屏渲染慢的问题说明及修复方案
关于此问题的说明:
Android System WebView 内核的bug:当webview页面中存在持续渲染(如跑马灯效果。banner轮播等)。页面被隐藏后会导致JS阻塞影响页面渲染效率。从66.0.3359.126版本到最新都存在此问题。
注意:
- 此问题必须是页面隐藏hide后,并且当前页面包含持续渲染(如跑马灯效果。banner轮播等)时才会触发此问题。如果你的页面不会隐藏、没有持续渲染逻辑可忽略此问题。
- 一般新窗体进入盖住老窗体,不会调用webview的hide方法,不会引发此问题。此问题常见于tabbar的切换,不同tab的webview页面只有一个是显示的,其他是hide的。或者开发者手动调用了plus.webview对象的hide方法。
解决方案:
方案1: 我们推荐开发者在页面被hide后,主动停用持续操作ui的js或css。
在隐藏的页面持续操作视图本身也不合理,影响性能。
在uni-app中,基础组件swiper和扩展uni ui的跑马灯,组件内部会判断,如果当前页面已经不再前台显示,会停止轮播。所以正常使用这些组件也不会遇到问题。
如果开发者引用了未做判断的三方组件,或者自己编写了持续操作视图的代码,则应该注意编写判断代码,在页面hide时,停止这些js或css。然后在恢复显示时,重新启用它们。
在uniapp中实现方案1的代码
//组件内监听webview隐藏停止动画(即将新增组件所在页面的生命周期,可以监听页面隐藏来停止动画)
mounted() {
// #ifdef APP-PLUS
const pages = getCurrentPages();
let currentWebview = pages[pages.length - 1].$getAppWebview();
currentWebview.addEventListener('hide', () => {
// webview隐藏,停止动画
})
currentWebview.addEventListener('show', () => {
// webview显示,开启动画
})
// #endif
},
//页面内监听页面隐藏停止动画
onShow() {
// 页面显示,开启动画
},
onHide() {
// 页面隐藏,停止动画
}
方案2: 当页面被隐藏时主动调用webview的pause方法,暂停这个webview里的所有js和css动画的运行
首先需要升级HBuilderX 2.3.8或更高版本。(如发现版本没更新请等待更新后再操作)
5+提供了新的API ,WebviewObject对象添加pause、resume方法。
- void pause() 暂停Webview对象,停止js执行、DOM渲染
- void resume() 恢复Webview对象,恢复js执行、DOM渲染
- boolean isPause() 是否暂停,暂停则返回ture,否则返回false
uniapp用户:
nvue页面无此问题。忽略即可。
vue页面:
在页面存在持续渲染(如跑马灯效果。banner轮播等)的情况下。可在页面周期onShow、onHide分别调用webview的resume、pause方法即可
onShow() {
const w = this.$mp.page.$getAppWebview();
if(w.isPause()){
w.resume();
}
},
onHide() {
const w = this.$mp.page.$getAppWebview();
w.pause();
},
5+用户:
可以通过WebviewObject对象控制管理方式规避问题。当调用WebviewObject的show、hide方法时主动调用相关页面的pause、resume方法。
//创建页面 此页面包含持续渲染(如跑马灯效果。banner轮播等)的逻辑存在。
var a = plus.webview.open('list.html','list');
//当a页面要隐藏时可调用如下代码
var a = plus.webview.getWebviewById('list');
a.hide('none');
a.pause();
//当a页面显示时调用如下代码
var a = plus.webview.getWebviewById('list');
if(a.isPause()) {
a.resume();
}
关于此问题的说明:
Android System WebView 内核的bug:当webview页面中存在持续渲染(如跑马灯效果。banner轮播等)。页面被隐藏后会导致JS阻塞影响页面渲染效率。从66.0.3359.126版本到最新都存在此问题。
注意:
- 此问题必须是页面隐藏hide后,并且当前页面包含持续渲染(如跑马灯效果。banner轮播等)时才会触发此问题。如果你的页面不会隐藏、没有持续渲染逻辑可忽略此问题。
- 一般新窗体进入盖住老窗体,不会调用webview的hide方法,不会引发此问题。此问题常见于tabbar的切换,不同tab的webview页面只有一个是显示的,其他是hide的。或者开发者手动调用了plus.webview对象的hide方法。
解决方案:
方案1: 我们推荐开发者在页面被hide后,主动停用持续操作ui的js或css。
在隐藏的页面持续操作视图本身也不合理,影响性能。
在uni-app中,基础组件swiper和扩展uni ui的跑马灯,组件内部会判断,如果当前页面已经不再前台显示,会停止轮播。所以正常使用这些组件也不会遇到问题。
如果开发者引用了未做判断的三方组件,或者自己编写了持续操作视图的代码,则应该注意编写判断代码,在页面hide时,停止这些js或css。然后在恢复显示时,重新启用它们。
在uniapp中实现方案1的代码
//组件内监听webview隐藏停止动画(即将新增组件所在页面的生命周期,可以监听页面隐藏来停止动画)
mounted() {
// #ifdef APP-PLUS
const pages = getCurrentPages();
let currentWebview = pages[pages.length - 1].$getAppWebview();
currentWebview.addEventListener('hide', () => {
// webview隐藏,停止动画
})
currentWebview.addEventListener('show', () => {
// webview显示,开启动画
})
// #endif
},
//页面内监听页面隐藏停止动画
onShow() {
// 页面显示,开启动画
},
onHide() {
// 页面隐藏,停止动画
}
方案2: 当页面被隐藏时主动调用webview的pause方法,暂停这个webview里的所有js和css动画的运行
首先需要升级HBuilderX 2.3.8或更高版本。(如发现版本没更新请等待更新后再操作)
5+提供了新的API ,WebviewObject对象添加pause、resume方法。
- void pause() 暂停Webview对象,停止js执行、DOM渲染
- void resume() 恢复Webview对象,恢复js执行、DOM渲染
- boolean isPause() 是否暂停,暂停则返回ture,否则返回false
uniapp用户:
nvue页面无此问题。忽略即可。
vue页面:
在页面存在持续渲染(如跑马灯效果。banner轮播等)的情况下。可在页面周期onShow、onHide分别调用webview的resume、pause方法即可
onShow() {
const w = this.$mp.page.$getAppWebview();
if(w.isPause()){
w.resume();
}
},
onHide() {
const w = this.$mp.page.$getAppWebview();
w.pause();
},
5+用户:
可以通过WebviewObject对象控制管理方式规避问题。当调用WebviewObject的show、hide方法时主动调用相关页面的pause、resume方法。
//创建页面 此页面包含持续渲染(如跑马灯效果。banner轮播等)的逻辑存在。
var a = plus.webview.open('list.html','list');
//当a页面要隐藏时可调用如下代码
var a = plus.webview.getWebviewById('list');
a.hide('none');
a.pause();
//当a页面显示时调用如下代码
var a = plus.webview.getWebviewById('list');
if(a.isPause()) {
a.resume();
}
收起阅读 »

魔改MUI离线打包app解决拔插扫描枪重启app问题及指定App的mainactivity
MUI这套H5应用框架非常值得肯定, 但也许它的应用少有涉及工业,activity一旦发生usb外接输入设备(如扫描枪)的排插就会导致重启, 这对于用家来讲是个不好的体现, 这个问题我已经在dcloud上反映过, https://ask.dcloud.net.cn/question/81362, 后来在群里有个小哥可能认识mui公司的人才有人理会解决, 但回复说要等hbuildx版本升级才行.
为了不影响进度, 经过若干试验,发现原来的主Activity为PandoraEntryActivity, 那么我新建一个MyMainActivity extends它并在activity的configChanges里面加上 keyboard即可:
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
新开一个MainActivity的好处还有, 可以在app启动的时候开自己的后台服务, app结束的时候打扫现场.
原app并不是一开始就以PandoraEntryActivity为启动activity,而是由一个临时的activity启动, 根据传入的参数is_stream_app加以判断,从而启动WebAppActivity或PandoraEntryActivity,为了完美接入, 也写了一个启动activity,在原本启动PandoraEntryActivity的地方换成MyMainActivity.
/
com.freestyle.android.h5plugin
Created by rocklee , 2019/3/8
/
public class MyStartActivity extends Activity {
@Override
protected void onCreate(Bundle var1) {
super.onCreate(var1);
Intent var2 = this.getIntent();
boolean var3 = false;
try {
var3 = var2.getBooleanExtra("is_stream_app", var3);
} catch (Exception var5) {
var5.printStackTrace();
this.finish();
return;
}
if (var3) {
var2.setClass(this, WebAppActivity.class);
var2.putExtra("is_stream_app", true);
} else {
var2.putExtra("short_cut_class_name", PandoraEntry.class.getName());
var2.setClass(this, MyMainActivity.class);
}
this.startActivity(var2);
(new Handler()).postDelayed(new Runnable() {
public void run() {
MyStartActivity.this.finish();
}
}, 20L);
}
}
最后贴上MyMainActivity的代码
/
com.freestyle.android.h5plugin
Created by rocklee , 2019/11/1
/
public class MyMainActivity extends PandoraEntryActivity {
//private Bridge mBridge;
private Handler mUIHandler;
@Override
protected void onStart(){
super.onStart();
mUIHandler.postDelayed(()->{
WebView.setWebContentsDebuggingEnabled(true);
},3000);
}
private void patchApplication(){
}
@Override
public void onDestroy(){
FRPlugins.quit();
super.onDestroy();
}
@Override
public void onCreate(Bundle var1) {
super.onCreate(var1);
patchApplication();
mUIHandler=new Handler(getMainLooper());
//mBridge=new Bridge(this);
FRPlugins.init(this);
Config.init(this);
}
}
————————————————
版权声明:本文为CSDN博主「OK_boom」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rocklee/article/details/102852575
MUI这套H5应用框架非常值得肯定, 但也许它的应用少有涉及工业,activity一旦发生usb外接输入设备(如扫描枪)的排插就会导致重启, 这对于用家来讲是个不好的体现, 这个问题我已经在dcloud上反映过, https://ask.dcloud.net.cn/question/81362, 后来在群里有个小哥可能认识mui公司的人才有人理会解决, 但回复说要等hbuildx版本升级才行.
为了不影响进度, 经过若干试验,发现原来的主Activity为PandoraEntryActivity, 那么我新建一个MyMainActivity extends它并在activity的configChanges里面加上 keyboard即可:
android:configChanges="orientation|keyboardHidden|keyboard|navigation"
新开一个MainActivity的好处还有, 可以在app启动的时候开自己的后台服务, app结束的时候打扫现场.
原app并不是一开始就以PandoraEntryActivity为启动activity,而是由一个临时的activity启动, 根据传入的参数is_stream_app加以判断,从而启动WebAppActivity或PandoraEntryActivity,为了完美接入, 也写了一个启动activity,在原本启动PandoraEntryActivity的地方换成MyMainActivity.
/
com.freestyle.android.h5plugin
Created by rocklee , 2019/3/8
/
public class MyStartActivity extends Activity {
@Override
protected void onCreate(Bundle var1) {
super.onCreate(var1);
Intent var2 = this.getIntent();
boolean var3 = false;
try {
var3 = var2.getBooleanExtra("is_stream_app", var3);
} catch (Exception var5) {
var5.printStackTrace();
this.finish();
return;
}
if (var3) {
var2.setClass(this, WebAppActivity.class);
var2.putExtra("is_stream_app", true);
} else {
var2.putExtra("short_cut_class_name", PandoraEntry.class.getName());
var2.setClass(this, MyMainActivity.class);
}
this.startActivity(var2);
(new Handler()).postDelayed(new Runnable() {
public void run() {
MyStartActivity.this.finish();
}
}, 20L);
}
}
最后贴上MyMainActivity的代码
/
com.freestyle.android.h5plugin
Created by rocklee , 2019/11/1
/
public class MyMainActivity extends PandoraEntryActivity {
//private Bridge mBridge;
private Handler mUIHandler;
@Override
protected void onStart(){
super.onStart();
mUIHandler.postDelayed(()->{
WebView.setWebContentsDebuggingEnabled(true);
},3000);
}
private void patchApplication(){
}
@Override
public void onDestroy(){
FRPlugins.quit();
super.onDestroy();
}
@Override
public void onCreate(Bundle var1) {
super.onCreate(var1);
patchApplication();
mUIHandler=new Handler(getMainLooper());
//mBridge=new Bridge(this);
FRPlugins.init(this);
Config.init(this);
}
}
————————————————
版权声明:本文为CSDN博主「OK_boom」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rocklee/article/details/102852575

HBuilderX 无MAC系统IOS云打包+蒲公英发布测试版
记录一下流程,免得后面的人重复摸索
-
申请苹果开发者账号
-
在开发者中心, 新建APP ID
Certificates, Identifiers & Profiles
》 All Identifiers
》Register a New Identifier
选择 创建APP IDs,
****注意此处的Bundle ID也就是APP ID, 是你自己起的, 格式: com.domainname.appname (Bundle ID在提交云打包时需要填入) -
在香蕉云编(https://www.yunedit.com/createcert)上 创建 csr文件
-
在苹果开发者中心, 创建Certificates, 过程中会要求上传前一步生成的csr, 创建成功可以下载为cer文件
****Type 有 iOS Distribution和iOS Development两种, 如果是像我一样想丢到蒲公英上给别人测试, 选择【 iOS Distribution】 -
在香蕉云编 上传下载的cer文件, 生成p12文件并下载, 会提示你输入密码(p12文件和密码在提交云打包时需要填入)
-
在开发者中心,添加测试手机的设备编号,设备编号 可以用手机访问https://www.pgyer.com/tools/udid获取
Certificates, Identifiers & Profiles
》 Devices 》Add -
在开发者中心, 创建Profiles, 需要上传前面生成的p12文件, 如果时发布测试版, 创建时一定要选择 Distribution》Ad Hoc
Certificates, Identifiers & Profiles
》 Profiles 》Add -
下载创建好的 profile, 连同前面生成的 appid, p12文件, 以及p12文件对应的密码, 填入到HbuilderX云打包的参数里, 打包
-
将打包好的ipa文件上传到蒲公英上, 已加入uuid的设备可以打开发布后的网页点击安装。
记录一下流程,免得后面的人重复摸索
-
申请苹果开发者账号
-
在开发者中心, 新建APP ID
Certificates, Identifiers & Profiles
》 All Identifiers
》Register a New Identifier
选择 创建APP IDs,
****注意此处的Bundle ID也就是APP ID, 是你自己起的, 格式: com.domainname.appname (Bundle ID在提交云打包时需要填入) -
在香蕉云编(https://www.yunedit.com/createcert)上 创建 csr文件
-
在苹果开发者中心, 创建Certificates, 过程中会要求上传前一步生成的csr, 创建成功可以下载为cer文件
****Type 有 iOS Distribution和iOS Development两种, 如果是像我一样想丢到蒲公英上给别人测试, 选择【 iOS Distribution】 -
在香蕉云编 上传下载的cer文件, 生成p12文件并下载, 会提示你输入密码(p12文件和密码在提交云打包时需要填入)
-
在开发者中心,添加测试手机的设备编号,设备编号 可以用手机访问https://www.pgyer.com/tools/udid获取
Certificates, Identifiers & Profiles
》 Devices 》Add -
在开发者中心, 创建Profiles, 需要上传前面生成的p12文件, 如果时发布测试版, 创建时一定要选择 Distribution》Ad Hoc
Certificates, Identifiers & Profiles
》 Profiles 》Add -
下载创建好的 profile, 连同前面生成的 appid, p12文件, 以及p12文件对应的密码, 填入到HbuilderX云打包的参数里, 打包
-
将打包好的ipa文件上传到蒲公英上, 已加入uuid的设备可以打开发布后的网页点击安装。

微信开放平台申请接口应用签名的获取方式
在微信开放平台申请相关应用接口的时候,要求一个应用签名的东西!
还有在一些平台申请相关服务也需要,比如在个推在推送配置!
下面介绍获取方法
1、首先下载安装安卓应用签名获取的APK
https://share.weiyun.com/55MsELw
2、找到需要获取的那个APP进去查看复制(需要获取应用签名的APP要先安装到手机)
像微信那边的就是需要证书指纹(MD5)这个值,复制填写即可!
在微信开放平台申请相关应用接口的时候,要求一个应用签名的东西!
还有在一些平台申请相关服务也需要,比如在个推在推送配置!
下面介绍获取方法
1、首先下载安装安卓应用签名获取的APK
https://share.weiyun.com/55MsELw
2、找到需要获取的那个APP进去查看复制(需要获取应用签名的APP要先安装到手机)
像微信那边的就是需要证书指纹(MD5)这个值,复制填写即可!

HBuilderX eslint一键修复功能使用说明(适用于HBuilderX 2.6.8之前的版本)
eslint-js插件下载地址
eslint-vue插件下载地址
特别说明
本文所述功能,仅对2.2.0和2.6.8之间的版本生效,2.6.9+版本请参考:https://ask.dcloud.net.cn/article/37070
1. eslint一键修复功能说明
- eslint一键修复功能,仅支持
cli
项目,不支持普通web项目 cli
项目,需要安装eslint库,并配置eslint规则- HBuilderX需要安装eslint插件。进入菜单【工具】【插件安装】,安装
eslint-js
、eslint-vue
两个插件 - 若满足上述条件,当编写完代码,保存时,若代码中存在错误,可使用
eslint一键修复
功能。 如下图:
2. eslint一键修复功能说明
一键修复功能,跟项目下配置的eslint规则
有关。
本文不再罗列eslint如何配置规则, 请自行搜索。
特别说明: eslint一键修复功能,并不能修复所有的语法错误。比如定义了某个变量,但未使用,eslint校验保存,一键修复功能并不能修复此类错误。
3. 保存文件时,自动修复语法错误
- 点击菜单【帮助】【插件配置】,找到
eslint-js
、eslint-vue
插件 - 点击插件下的
package.json
文件 - 如下图,修改两处(注意id),然后
重启HBuilderX
(注意:必须重启HBuilderX)
eslint-js插件下载地址
eslint-vue插件下载地址
特别说明
本文所述功能,仅对2.2.0和2.6.8之间的版本生效,2.6.9+版本请参考:https://ask.dcloud.net.cn/article/37070
1. eslint一键修复功能说明
- eslint一键修复功能,仅支持
cli
项目,不支持普通web项目 cli
项目,需要安装eslint库,并配置eslint规则- HBuilderX需要安装eslint插件。进入菜单【工具】【插件安装】,安装
eslint-js
、eslint-vue
两个插件 - 若满足上述条件,当编写完代码,保存时,若代码中存在错误,可使用
eslint一键修复
功能。 如下图:
2. eslint一键修复功能说明
一键修复功能,跟项目下配置的eslint规则
有关。
本文不再罗列eslint如何配置规则, 请自行搜索。
特别说明: eslint一键修复功能,并不能修复所有的语法错误。比如定义了某个变量,但未使用,eslint校验保存,一键修复功能并不能修复此类错误。
3. 保存文件时,自动修复语法错误
- 点击菜单【帮助】【插件配置】,找到
eslint-js
、eslint-vue
插件 - 点击插件下的
package.json
文件 - 如下图,修改两处(注意id),然后
重启HBuilderX
(注意:必须重启HBuilderX)

Uparse修复版的说明
举例有这样一段代码
<div>
<span>1243 5346</span>
</div>
uparse文件执行顺序简单说明
parse.vue插件入口文件 → 调用lib/html2json.js → 返回nodes对象 (这里得到一个html节点解析后的json对象)
↓↑
调用wxDiscode(例:把&nbsp;转成字符),htmlparser
parse.vue把nodes输入到wxParseTemplate0.vue
首先会处理最外层的 div,就变成了
<view>
nodes
<view/>
nodes = '<span>1243 5346</span>'
再把新的nodes再次输入到wxParseTemplate0.vue(小程序是wxParseTemplate1.vue)
这样就得到一个递归调用的模板,直到输出所有节点
wxParseTemplate里面遇到table,img,video,audio,标签时会分别调用自定义组件(更多的可以直接看源码)
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
import wxParseTable from './wxParseTable';
下面说说优化了哪些地方.优化的同时也存在些问题.希望大家提出好的解决方案.
0.去掉了标签在递归过程中多出来的标签,解决导致内联元素没有内联的问题
1.table标签很简单目前是用的rich-text
https://uniapp.dcloud.io/component/rich-text
没有找到更好的处理方法,问题是,标签内部的非文字节点,,可能会有问题
2.wxDiscode相对于原版做了一些处理
// 例:
str = str.replace(/ /g, " ");
改为
str = str.replace(/ | | /g, "<span class='spaceshow'> </span>");
3.parse.vue文件的getWidth方法原版获取的是屏幕的宽度,实际上应该获取组件的宽度,该方法获取的宽度主要是用于计算image的图片宽度.(组件可能有边距,边距不应该用于计算图片的宽度).
有兴趣的可以去看看image的处理,,目前是有些问题的,,因为官方的图片插件必须要设置一个宽高覆盖掉默认的宽高,做百分比计算感觉比较复杂.目前我也没什么好的处理方式.
另外还要吐槽一下uni.createSelectorQuery(),之前在处理时,各个小程序的兼容情况好像并不是很好,所以用的条件编译.有报错可以自行处理一下
4.parse.vue文件的setHtml方法
this.nodes = results.nodes;
// 改为
this.nodes = [];
results.nodes.forEach((item) => {
setTimeout(() => {
this.nodes.push(item)
}, 0);
})
这段代码可以异步的加载根节点,,
像这样:
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
但是如果用div标签包裹起来就不是异步加载了,
像这样
<div>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
</div>
目前还没想好如何异步加载所有节点,,有想到如何处理的可以留言或私信我谢谢.之前有尝试,但是性能反降.遂放弃
实际上是分段渲染的结果,让人感觉好像渲染速度加快,,实际上并没快多少
5.parse.vue文件的 navigate方法
原方法是只能获取href的内容,,有人提出需求需要获取onclick的内容,所以增加了attr,
6.对br标签的处理{wxDiscode应该处理"<",">"字符,避免转码后输出br标签,br再转换行的问题,暂时还没改}
<!--br类型-->
<!-- #ifndef H5 -->
<text v-else-if="node.tag == 'br'">\n</text>
<!-- #endif -->
<!-- #ifdef H5 -->
<br v-else-if="node.tag == 'br'">
<!-- #endif -->
7.wxParse.css文件我就不说了但是需要在APP.vue文件中引入,
目前就想到这么多了.
举例有这样一段代码
<div>
<span>1243 5346</span>
</div>
uparse文件执行顺序简单说明
parse.vue插件入口文件 → 调用lib/html2json.js → 返回nodes对象 (这里得到一个html节点解析后的json对象)
↓↑
调用wxDiscode(例:把&nbsp;转成字符),htmlparser
parse.vue把nodes输入到wxParseTemplate0.vue
首先会处理最外层的 div,就变成了
<view>
nodes
<view/>
nodes = '<span>1243 5346</span>'
再把新的nodes再次输入到wxParseTemplate0.vue(小程序是wxParseTemplate1.vue)
这样就得到一个递归调用的模板,直到输出所有节点
wxParseTemplate里面遇到table,img,video,audio,标签时会分别调用自定义组件(更多的可以直接看源码)
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
import wxParseTable from './wxParseTable';
下面说说优化了哪些地方.优化的同时也存在些问题.希望大家提出好的解决方案.
0.去掉了标签在递归过程中多出来的标签,解决导致内联元素没有内联的问题
1.table标签很简单目前是用的rich-text
https://uniapp.dcloud.io/component/rich-text
没有找到更好的处理方法,问题是,标签内部的非文字节点,,可能会有问题
2.wxDiscode相对于原版做了一些处理
// 例:
str = str.replace(/ /g, " ");
改为
str = str.replace(/ | | /g, "<span class='spaceshow'> </span>");
3.parse.vue文件的getWidth方法原版获取的是屏幕的宽度,实际上应该获取组件的宽度,该方法获取的宽度主要是用于计算image的图片宽度.(组件可能有边距,边距不应该用于计算图片的宽度).
有兴趣的可以去看看image的处理,,目前是有些问题的,,因为官方的图片插件必须要设置一个宽高覆盖掉默认的宽高,做百分比计算感觉比较复杂.目前我也没什么好的处理方式.
另外还要吐槽一下uni.createSelectorQuery(),之前在处理时,各个小程序的兼容情况好像并不是很好,所以用的条件编译.有报错可以自行处理一下
4.parse.vue文件的setHtml方法
this.nodes = results.nodes;
// 改为
this.nodes = [];
results.nodes.forEach((item) => {
setTimeout(() => {
this.nodes.push(item)
}, 0);
})
这段代码可以异步的加载根节点,,
像这样:
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
但是如果用div标签包裹起来就不是异步加载了,
像这样
<div>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
<p>这里是<span>段落</span></p>
</div>
目前还没想好如何异步加载所有节点,,有想到如何处理的可以留言或私信我谢谢.之前有尝试,但是性能反降.遂放弃
实际上是分段渲染的结果,让人感觉好像渲染速度加快,,实际上并没快多少
5.parse.vue文件的 navigate方法
原方法是只能获取href的内容,,有人提出需求需要获取onclick的内容,所以增加了attr,
6.对br标签的处理{wxDiscode应该处理"<",">"字符,避免转码后输出br标签,br再转换行的问题,暂时还没改}
<!--br类型-->
<!-- #ifndef H5 -->
<text v-else-if="node.tag == 'br'">\n</text>
<!-- #endif -->
<!-- #ifdef H5 -->
<br v-else-if="node.tag == 'br'">
<!-- #endif -->
7.wxParse.css文件我就不说了但是需要在APP.vue文件中引入,
目前就想到这么多了.
收起阅读 »
【申精】 uni-simple-router H5强化路由篇
uni-simple-router@1.3.5 H5路由强化篇
<br/>
很高兴能为开源项目做一些贡献,uni-simple-router@1.3.5已经在群内测了。今天啥口水话都不说,直接上代码。
<br/>
一直以来uni-app在路由上做的都是比较简洁了,特别是在h5端对url的美观、拦截、动态路由等都是比较欠缺的。而今天你看到了这个文章 说明有望了? 哈哈!! 截止1.2.5以前的版本只是在做一些基本的功能,没有对端进行强化。1.3.5这个版本是对H5的强化
<br/>
更新内容
太多了现在就说了,以后文档上见 现在把以前的文档进行重新整理。换正式点。
<br/>
强化内容如下
1.能完全使用vue-router进行开发
2.动态导入组件作为页面
3.完全拦截uni-app自带的所有跳转
4.自定义路由表。通配、404、子路由。嵌套路由 废弃pages.json中的配置
(#31)
5.提供3中开发模式:1.读取pages.json中的配置开发,2.不使用pages.json中的配置进行开发,开发者直接用component动态导入组件。3.完全使用vue-router开发
6.自定义加载样式,可追加、可替换、可隐藏
(#24)
7.全权使用vue-router配置,必须使用vue-router开发才行
8.传递参数方式新增为两种模式,开发者可自行切换
(#25,#28)
9.动态路由 addRoutes TODO
<br/>
先睹为快
使用了自定义路径的url,依然使用pages.json的配置
uni-app原始配置
404捕捉页面,依然使用pages.json中的配置
自定义加载样式
完全使用vue-router开发
<br/>
结束语
下一篇 为uni-simple-router之H5拦截uni-app自带tabbar篇
uni-simple-router@1.3.5 H5路由强化篇
<br/>
很高兴能为开源项目做一些贡献,uni-simple-router@1.3.5已经在群内测了。今天啥口水话都不说,直接上代码。
<br/>
一直以来uni-app在路由上做的都是比较简洁了,特别是在h5端对url的美观、拦截、动态路由等都是比较欠缺的。而今天你看到了这个文章 说明有望了? 哈哈!! 截止1.2.5以前的版本只是在做一些基本的功能,没有对端进行强化。1.3.5这个版本是对H5的强化
<br/>
更新内容
太多了现在就说了,以后文档上见 现在把以前的文档进行重新整理。换正式点。
<br/>
强化内容如下
1.能完全使用vue-router进行开发
2.动态导入组件作为页面
3.完全拦截uni-app自带的所有跳转
4.自定义路由表。通配、404、子路由。嵌套路由 废弃pages.json中的配置
(#31)
5.提供3中开发模式:1.读取pages.json中的配置开发,2.不使用pages.json中的配置进行开发,开发者直接用component动态导入组件。3.完全使用vue-router开发
6.自定义加载样式,可追加、可替换、可隐藏
(#24)
7.全权使用vue-router配置,必须使用vue-router开发才行
8.传递参数方式新增为两种模式,开发者可自行切换
(#25,#28)
9.动态路由 addRoutes TODO
<br/>
先睹为快
使用了自定义路径的url,依然使用pages.json的配置
uni-app原始配置
404捕捉页面,依然使用pages.json中的配置
自定义加载样式
完全使用vue-router开发
<br/>
结束语
下一篇 为uni-simple-router之H5拦截uni-app自带tabbar篇
收起阅读 »
HBuilderX 格式化操作、及格式化插件配置说明
本帖文档已集成到: hx产品文档
1. HBuilderX的格式化插件说明
插件名称 | 对应插件配置中的名称 | 是否内置 | 可格式化的文件 | 插件市场 |
---|---|---|---|---|
js-beautify | format | 内置插件 | vue、html、js、css、json | |
prettier | format-prettier | 非内置,需要下载 | less、sass、vue、stylus(vue内嵌)、ts、yaml | 下载地址 |
stylus-supremacy | format-stylus-supremacy | 非内置,需要下载 | 格式化单独stylus文件 | 下载地址 |
特别说明:
- 当同时存在
js-beautify
和format-prettier
插件是,格式化vue
文件,调用的是format-prettier
插件 stylus-supremacy
只支持格式化独立的stylus文件,如需格式化vue文件内的stylus代码,需要同时安装prettier插件- 本地插件目录:HBuilderX所有的插件,都存放于本地
plugins
目录下
2. 格式化插件配置
点击菜单【工具】【设置 -> 插件配置】,选择相应插件, 点击配置文件
进行配置。
在格式化插件配置文件
内,每项配置均有说明(或阅读插件中README.MD
文件); 无说明文档的请参考插件官网配置说明。
插件配置中格式化插件 | 配置文件 | 插件官网 |
---|---|---|
format | format/jsbeautifyrc.js | 官网 |
format-prettier | formator-prettier/prettier.config.js | 官网 |
format-stylus-supremacy | formator-stylus-supremacy/supremacy.config.js | 官网 |
3. 格式化快捷键
格式化菜单:【右键菜单】-->【重排代码格式】
格式化快捷键, win:ctrl + K
; mac: command + K
自定义格式化快捷键: 点击菜单【工具】【自定义快捷键】,在【用户设置】中,拷贝如下代码, key
为您要定义的快捷键
{"key":"ctrl+k","command":"editor.action.format"}
4. 格式化风格
格式化时, 使用的缩进方式,是读取的菜单【工具 --> 设置】中的配置
特别说明:
editorconfig
配置会覆盖HBuilderX编辑器配置;当项目下存在.editorconfig
文件时,格式化时,读取的是此配置文件。
.editorconfig使用说明文档
5. 保存文件时,自动格式化
部分小伙伴反馈, 如何实现保存文件时,自动格式化? 答: 不支持。
- 普通web项目
不支持
保存文件的同时,自动格式化。 - vue-cli项目,可通过配置
eslint
,通过eslint自动校验修复
的功能,来实现相同的效果。
例如:保存时,去除分号等。
6. estlint自动修复、实时校验
本帖文档已集成到: hx产品文档
1. HBuilderX的格式化插件说明
插件名称 | 对应插件配置中的名称 | 是否内置 | 可格式化的文件 | 插件市场 |
---|---|---|---|---|
js-beautify | format | 内置插件 | vue、html、js、css、json | |
prettier | format-prettier | 非内置,需要下载 | less、sass、vue、stylus(vue内嵌)、ts、yaml | 下载地址 |
stylus-supremacy | format-stylus-supremacy | 非内置,需要下载 | 格式化单独stylus文件 | 下载地址 |
特别说明:
- 当同时存在
js-beautify
和format-prettier
插件是,格式化vue
文件,调用的是format-prettier
插件 stylus-supremacy
只支持格式化独立的stylus文件,如需格式化vue文件内的stylus代码,需要同时安装prettier插件- 本地插件目录:HBuilderX所有的插件,都存放于本地
plugins
目录下
2. 格式化插件配置
点击菜单【工具】【设置 -> 插件配置】,选择相应插件, 点击配置文件
进行配置。
在格式化插件配置文件
内,每项配置均有说明(或阅读插件中README.MD
文件); 无说明文档的请参考插件官网配置说明。
插件配置中格式化插件 | 配置文件 | 插件官网 |
---|---|---|
format | format/jsbeautifyrc.js | 官网 |
format-prettier | formator-prettier/prettier.config.js | 官网 |
format-stylus-supremacy | formator-stylus-supremacy/supremacy.config.js | 官网 |
3. 格式化快捷键
格式化菜单:【右键菜单】-->【重排代码格式】
格式化快捷键, win:ctrl + K
; mac: command + K
自定义格式化快捷键: 点击菜单【工具】【自定义快捷键】,在【用户设置】中,拷贝如下代码, key
为您要定义的快捷键
{"key":"ctrl+k","command":"editor.action.format"}
4. 格式化风格
格式化时, 使用的缩进方式,是读取的菜单【工具 --> 设置】中的配置
特别说明:
editorconfig
配置会覆盖HBuilderX编辑器配置;当项目下存在.editorconfig
文件时,格式化时,读取的是此配置文件。
.editorconfig使用说明文档
5. 保存文件时,自动格式化
部分小伙伴反馈, 如何实现保存文件时,自动格式化? 答: 不支持。
- 普通web项目
不支持
保存文件的同时,自动格式化。 - vue-cli项目,可通过配置
eslint
,通过eslint自动校验修复
的功能,来实现相同的效果。
例如:保存时,去除分号等。
6. estlint自动修复、实时校验
eslint-js自动修复功能
eslint-vue自动修复功能

uniapp开发支付宝小程序中碰到的事项
1.支付宝小程序的本地存储我使用的是 该模式
const storageSet = (key, value) => { // 设置本地存储 set
uni.setStorage({
key,
value
});
}
const storageGet = (key) => { // 获取本地存储 get
uni.getStorage({
key: 'storage_key',
success: function (res) {
return res.data
}
});
}
const storageRemove = (key) => { // 获取本地存储 get
uni.removeStorage({
key
});
}
2.如果涉及到了扫普通二维码进入小程序,如“http://****.com?pid=1&cid=2&did=4”
无法在page页面的onLoad(options)中拿到指定的参数,
只能在app.vue中onLaunch(options)中拿到数据
并且这里是拿到 完整的 普通二维码地址 “http://****.com?pid=1&cid=2&did=4”,并不是对象形式,所以这里需要转为对象
我这边是采用的vuex中存起来,在page页面自行调用
顺便提供转码方法
export function getUrlAli(url){
let scan_url = url; // 解码
scan_url = scan_url.substring(scan_url.indexOf('?')+1);
let obj ={},arr = scan_url.split('&');// 存参数
if(url.includes('token')) { // 判断是否是支付宝小程序开发,体验版
arr.pop()
}
arr.map((item,index)=>{
let subArr = arr[index].split('=');
let key = subArr[0];
let value = subArr[1];
obj[key] = value;
})
return obj
}
【以上都是个人的做法,如果有更好的做法,欢迎一起交流!】
1.支付宝小程序的本地存储我使用的是 该模式
const storageSet = (key, value) => { // 设置本地存储 set
uni.setStorage({
key,
value
});
}
const storageGet = (key) => { // 获取本地存储 get
uni.getStorage({
key: 'storage_key',
success: function (res) {
return res.data
}
});
}
const storageRemove = (key) => { // 获取本地存储 get
uni.removeStorage({
key
});
}
2.如果涉及到了扫普通二维码进入小程序,如“http://****.com?pid=1&cid=2&did=4”
无法在page页面的onLoad(options)中拿到指定的参数,
只能在app.vue中onLaunch(options)中拿到数据
并且这里是拿到 完整的 普通二维码地址 “http://****.com?pid=1&cid=2&did=4”,并不是对象形式,所以这里需要转为对象
我这边是采用的vuex中存起来,在page页面自行调用
顺便提供转码方法
export function getUrlAli(url){
let scan_url = url; // 解码
scan_url = scan_url.substring(scan_url.indexOf('?')+1);
let obj ={},arr = scan_url.split('&');// 存参数
if(url.includes('token')) { // 判断是否是支付宝小程序开发,体验版
arr.pop()
}
arr.map((item,index)=>{
let subArr = arr[index].split('=');
let key = subArr[0];
let value = subArr[1];
obj[key] = value;
})
return obj
}
【以上都是个人的做法,如果有更好的做法,欢迎一起交流!】