1.解决uni-app打包H5后会自动请求shadow-grey.png
index.html页面设置样式
body::after { content: none; }
2.修改手机返回键弹出再按一次退出应用文案
// #ifdef APP-PLUS
let main = plus.android.runtimeMainActivity();
//为了防止快速点按返回键导致程序退出重写quit方法改为隐藏至后台
plus.runtime.quit = function(){
main.moveTaskToBack(false);
};
//重写toast方法如果内容为 ‘再按一次退出应用’ 就隐藏应用,其他正常toast
plus.nativeUI.toast = (function(str){
if(str == '再按一次退出应用'){
main.moveTaskToBack(false);
return false;
}else{
uni.showToast({
title:str,
icon:'none',
})
}
});
// #endif
3.解决Vuex-在F5刷新页面后数据不见
store.js页面设置vuex相关
安装
npm install vuex-persistedstate --save
引⼊及配置 在store下的index.js
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
})
默认存储到localStorage 想要存储到sessionStorage,配置如下
import createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage
})]
})
想使⽤cookie同理 默认持久化所有state 指定需要持久化的state,配置如下
mport createPersistedState from "vuex-persistedstate"
const store = new Vuex.Store({
// ...
plugins: [createPersistedState({
storage: window.sessionStorage,
reducer(val) {
return {
// 只储存state中的assessmentData
assessmentData: val.assessmentData
}
}
})
4.局部样式
一般都是使用 scoped 方案:
<style lang="scss" scoped>
...
</style>
5.场景:uniapp webview src参数重新赋值时H5会重定向,多次点击才能返回上一页。
解决方案:src赋值前先对src进行src=>null处理
6. 项目中H5环境 blur和click事件冲突
click事件改成mousedown事件,mousedown事件优于blur事件
@click => @mousedown.native
7.input number如何禁止输入e和小数点等数学符号
onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))"
demo:
<input type="number" onKeypress="return (/[\d]/.test(String.fromCharCode(event.keyCode)))">
8. Uniapp开发h5页面输入框软键盘被顶起
问题:当使用uniapp的input时,真机上软键盘将页面顶起的解决方案:
第一步:给input添加class=“uni-input” cursor-spacing=“10”(uniapp文档也有说明)
第二步:pages配置文件对应的页面模块添加**“softinputMode”: “adjustResize”**(uniapp文档也有说明)
"style": {
"app-plus": {
//"titleNView": false,
"softinputMode": "adjustResize"
}
}
9. 关闭安卓打包提示弹框基座不对应
manifest.json文件添加compatible属性:
"app-plus" : {
"compatible" : {
"ignoreVersion" : true
}
}
10. uniapp中数字串不换行问题
white-space: normal; // 规定段落中的文本不进行换行
//让数字串换行问题 word-break: break-all; // 允许单词中换行,在容器的最右边进行断开不会浪费控件
word-wrap: break-word; // 防止长单词溢出,单词内部短句
自动换行 word-break:break-all和word-wrap:break-word
word-break:break-all和word-wrap:break-word都是能使其容器如DIV的内容自动换行。 1,word-break:break-all 例如div宽200px,它的内容就会到200px自动换行,如果该行末端有个英文单词很长(congratulation等),它会把单词截断,变成该行末端为conra(congratulation的前端部分),下一行为tulation(conguatulation)的后端部分了。 2,word-wrap:break-word 例子与上面一样,但区别就是它会把congratulation整个单词看成一个整体,如果该行末端宽度不够显示整个单词,它会自动把整个单词放到下一行,而不会把单词截断掉的。
11.app设置webview位置 this.getAppWebview()延迟性解决
1、onReady调用this.getAppWebview()
onReady() {
// #ifdef APP-PLUS
var currentWebview = this.$scope.$getAppWebview() || this.$parent.$scope.$getAppWebview() //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效,非v3编译模式使用this.$mp.page.$getAppWebview()
// 处理currentWebview获取延时问题
this.getWebview(currentWebview);
// #endif
},
2、methods里面利用递归函数直至获取到currentWebview.children()[0]
methods:{
getWebview(currentWebview){
let that = this;
// console.log("currentWebview.children()[0]",currentWebview.children()[0])
if(currentWebview&¤tWebview.children()[0]){
wv = currentWebview.children()[0]
wv.setStyle({top:155,bottom:80})
}else{
setTimeout(function() {
// 递归函数直到获取到currentWebview.children()[0]
that.getWebview(currentWebview)
}, 200);
}
},
}
11 uni-app 限制输入两位小数点
<template>
<view>
<input v-model="money" type="number" @input="check" placeholder="金额(元)" />
</view>
</template>
<script>
export default {
data() {
return {
money:''
}
},
methods: {
check: function(e) {
//正则表达试
e.target.value = (e.target.value.match(/^\d*(\.?\d{0,2})/g)[0]) || null
//重新赋值给input
this.$nextTick(() => {
this.money= e.target.value
})
},
},
}
</script>
<style>
</style>
12、 base64转图片
- 创建一个base.js文件
const fsm = wx.getFileSystemManager();
const FILE_BASE_NAME = 'tmp_base64src'; //自定义文件名
function base64src(base64data, cb) {
const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || [];
if (!format) {
return (new Error('ERROR_BASE64SRC_PARSE'));
}
const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`;
const buffer = wx.base64ToArrayBuffer(bodyData);
fsm.writeFile({
filePath,
data: buffer,
encoding: 'binary',
success() {
cb(filePath);
},
fail() {
return (new Error('ERROR_BASE64SRC_WRITE'));
},
});
};
module.exports = base64src;
- 在要用的页面引入
var base64src = require('../../js/base64.js')
var shareQrImg=`data:image/jpg;base64,iVBORw0KGgoAAAANSUhEUgAAAQwAAAErCAYAAAArJb0dAAAgAElEQVR4nNS92Y9l2XXm9zvjPXceY.....`; // base64编码省略号代替,太长了
注意:data:image/jpg,jpg也可以是其他图片格式,例如:png,看后端给你返回什么
console.log(shareQrImg)
base64src(shareQrImg, resCurrent => {
console.log(resCurrent) // 返回图片地址,直接赋值到image标签即可(此图片只是本地图片)
})
// 网络图片转base64编码(此方法没试,留在这里备用)
let base64 = wx.arrayBufferToBase64(网图地址);
let userImageBase64 = 'data:image/jpg;base64,' + base64;
console.log(userImageBase64); // 打印base64格式图片
13、 uni-app弹窗列表滚动, 蒙层下面也跟随滚动解决方案
1.弹窗组件代码,需要在最外层的view中加入@touchmove.stop.prevent="moveHandle",且弹窗中需要滚动的列表要使用scroll-view标签包裹起来,且scroll-y 属性不能忘记加。
<view class="uni-mask" @touchmove.stop.prevent="moveHandle" v-if="showModelLine" @click="hideModelLine">
<scroll-view :scroll-y="true" class="txt">
</scroll-view>
</view>
methods: {
moveHandle() {
return;
},
},
14、uni-app打包H5出现“网络不给力,点击屏幕重试”
uni-app默认在弱网或者断网的情况下反馈出来的。可以在manifest.json中延长时间来解决问题。
可参考官方文档:uniapp.dcloud.io/collocation…
"h5": {
"title": "演示", //页面标题,默认使用 manifest.json 的 name
"template": "index.html", //index.html模板路径,相对于应用根目录,可定制生成的 html 代码
"router": {
"mode": "history", //路由跳转模式,支持 hash|history ,默认 hash
"base": "/hello/" //应用基础路径,例如,如果整个单页应用服务在 /app/ 下,然后 base 就应该设为 "/app/"
},
"async": { //页面js异步加载配置
"loading": "AsyncLoading", //页面js加载时使用的组件(需注册为全局组件)
"error": "AsyncError", //页面js加载失败时使用的组件(需注册为全局组件)
"delay": 200, //展示 loading 加载组件的延时时间(页面 js 若在 delay 时间内加载完成,则不会显示 loading 组件)
"timeout": 3000 //页面js加载超时时间(超时后展示 error 对应的组件)
}
},
"networkTimeout": {
"request": 6000 //uni.request的settimeout
}
15、 uniapp设置强制竖屏wgt包强制竖屏uniapp锁定屏幕竖直方向
分为三步
-
第一步
uniapp 根目录下pages.json 文件中追加下面四项
"globalStyle": {
"pageOrientation": "portrait", //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape
"rpxCalcMaxDeviceWidth": 960,
"rpxCalcBaseDeviceWidth": 375,
"rpxCalcIncludeWidth": 750
}
-
第二步
uniapp 根目录下mainfest.json文件中追加如下配置
distribute" : {
"orientation" : ["portrait-primary" ] //重力感应、横竖屏配置
}
-
第三步
在你想强制横竖屏的页面的vue文件中的 onLoad 或者onShow的生命周期里面 加上如下代码即可
//#ifdef APP-PLUS
plus.screen.lockOrientation('portrait-primary');
//#endif
16、 uni-app H5解决IOS音频不能自动播放的问题
先看uniapp的uni.createInnerAudioContext() 接口示例
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.src = 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3';
innerAudioContext.onPlay(() => {
console.log('开始播放');
});
innerAudioContext.onError((res) => {
console.log(res.errMsg);
console.log(res.errCode);
});
示例在pc和安卓微信客户端是可以自动播放的,IOS就不行了。
所以得通过集成微信JS-SDK验证来解决
通过npm安装方式
npm install jweixin-module --save
然后再引用jweixin-module,可以在main.js上定义或者在单独页面上,首页引用:
<script>
var jweixin = require('jweixin-module');
export default {
components: {},
data() {
return {}
},
onLoad: function (option) {
// this.creatAudio();
},
created(){
},
mounted() {
this.creatAudio();
},
methods: {
creatAudio(){
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;
innerAudioContext.src = 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3';
innerAudioContext.onPlay(() => {
console.log('开始播放');
});
innerAudioContext.onError((res) => {
console.log(res);
});
jweixin.config({});// 不做任何签名验证都可以
jweixin.ready(function(){
WeixinJSBridge.invoke('getNetworkType', {}, function(e){
innerAudioContext.play();
})
})
},
}
}
</script>
17、uniapp 播放音频
//../../static/image/login_bg.png
console.log("=====testClick=====");
let src = '../../static/voice/test.mp3';
//实例化声音
const Audio = uni.createInnerAudioContext();
Audio.autoplay = true;
Audio.src = src; //音频地址
Audio.play(); //执行播放
Audio.onError((res) => {
console.log(res.errMsg);
console.log(res.errCode);
});
Audio.onPause(function() {
console.log('end');
Audio.destroy();
});
18、 uniapp APP端使用指纹
使用插件指纹模板:
ext.dcloud.net.cn/plugin?id=3…
Fingerprint模块管理指纹识别
要使用指纹识别功能需要具备条件:
- 确认当前设备环境是否支持指纹识别,
- 当前设备是否设置密码锁屏,
- 当前设备是否已经录入指纹。
(Android平台6.0及以上系统支持,只识别标准Android的指纹API,仅适配Google官方指纹识别的标准接口的设备)
以上条件都要满足才可以使用识别功能,识别功能,指的是与手机中已录入的指纹进行比对检测,也就是说,只要与手机中录入任意指纹比对成功,便可进入成功回调。
首先需要获取得到权限:
在 manifest.json文件中配置(指纹识别)
目前市场上还是有很多设备不支持指纹,所以要先使用 plus.fingerprint.isSupport() 方法判断(以下三个方法均返回值为Boolean类型)
// #ifdef APP-PLUS
if (!plus.fingerprint.isSupport()) {
plus.nativeUI.toast('此设备不支持指纹识别');
console.log('此设备不支持指纹识别')
}
// #endif
再使用 ****plus.fingerprint.isKeyguardSecure() 判断是否开启密码锁屏
// #ifdef APP-PLUS
if (!plus.fingerprint.isKeyguardSecure()) {
plus.nativeUI.toast('此设备未设置密码锁屏');
console.log('此设备未设置密码锁屏')
}
// #endif
再然后使用 plus.fingerprint.isEnrolledFingerprints() 判断是否录入指纹
// #ifdef APP-PLUS
if (!plus.fingerprint.isEnrolledFingerprints()) {
plus.nativeUI.toast('此设备未录入指纹');
console.log('此设备未录入指纹')
}
// #endif
总结:指纹识别封装为一个方法
fingerprint: function() {
// #ifdef APP-PLUS
plus.fingerprint.authenticate(function() {
console.log('匹配成功');
}, function(e) {
switch (e.code) {
case e.AUTHENTICATE_MISMATCH:
plus.nativeUI.toast('指纹匹配失败,请重新输入');
break;
case e.AUTHENTICATE_OVERLIMIT:
plus.nativeUI.closeWaiting(); //兼容Android平台关闭等待框
plus.nativeUI.toast('指纹识别失败次数超出限制,请使用其它方式进行认证');
break;
case e.CANCEL:
plus.nativeUI.toast('已取消识别');
break;
default:
plus.nativeUI.closeWaiting(); //兼容Android平台关闭等待框
plus.nativeUI.toast('指纹识别失败,请重试');
break;
}
});
// #endif
},
指纹识别demo:
<template>
<view>
<button class="button_fin" @tap="fingerprint()" :disabled="disabled">按下开始识别指纹</button>
</view>
</template>
<script>
export default {
data() {
return {
disabled: true
}
},
onLoad() {
// #ifdef APP-PLUS
if (!plus.fingerprint.isSupport()) {
uni.showToast({
title: '此设备不支持指纹识别',
icon: 'none',
duration: 2000
});
// alert("此设备不支持指纹识别")
this.disabled = true;
} else if (!plus.fingerprint.isKeyguardSecure()) {
uni.showToast({
title: '此设备未设置密码锁屏,无法使用指纹识别',
icon: 'none',
duration: 2000
});
this.disabled = true;
} else if (!plus.fingerprint.isEnrolledFingerprints()) {
uni.showToast({
title: '此设备未录入指纹,请到设置中开启',
icon: 'none',
duration: 2000
});
this.disabled = true;
} else {
// this.disabled=true
this.disabled = false;
}
// #endif
// #ifdef MP-WEIXIN
this.disabled = false;
uni.showToast({
title: '请在微信真机中使用,模拟器不支持',
icon: 'none',
duration: 2000
});
// #endif
// #ifndef APP-PLUS || MP-WEIXIN
uni.showToast({
title: '此平台不支持指纹识别',
icon: 'none',
duration: 2000
});
// #endif
// 初次调用指纹
// this.fingerprint()
},
methods: {
fingerprint: function() {
// #ifdef APP-PLUS
plus.fingerprint.authenticate(function() {
plus.nativeUI.closeWaiting(); //兼容Android平台关闭等待框
// plus.nativeUI.alert('指纹识别成功');
// plus.nativeUI.alert("指纹识别成功", function(){
// console.log("指纹识别成功");
// }, "指纹验证", "确定");
uni.showToast({
title: '指纹识别成功',
// icon: 'none',
mask:true,
image:"/static/FingerprintBlue.png",
duration: 2000
});
// uni.showModal({
// title: '友情提示',
// content: '指纹识别成功',
// success: function(res) {
// if (res.confirm) {
// console.log('用户点击确定');
// } else if (res.cancel) {
// console.log('用户点击取消');
// }
// }
// });
}, function(e) {
switch (e.code) {
case e.AUTHENTICATE_MISMATCH:
plus.nativeUI.toast('指纹匹配失败,请重新输入');
break;
case e.AUTHENTICATE_OVERLIMIT:
plus.nativeUI.closeWaiting(); //兼容Android平台关闭等待框
plus.nativeUI.alert('指纹识别失败次数超出限制,请使用其它方式进行认证');
break;
case e.CANCEL:
plus.nativeUI.toast('已取消识别');
break;
default:
plus.nativeUI.closeWaiting(); //兼容Android平台关闭等待框
plus.nativeUI.alert('指纹识别失败,请重试');
break;
}
});
// Android平台手动弹出等待提示框
if ('Android' == plus.os.name) {
// var opt = '{"width":"150px","height":"150px","style": "white", "color": "#1d8079"}';
// plus.nativeUI.showWaiting('指纹识别中...', JSON.parse(opt)).onclose = function() {
// plus.fingerprint.cancel();
// }
var wt=plus.nativeUI.showWaiting("请验证指纹",{
width:"200px",
height:"200px",
color: "#1d8079",
mask:true,
background:"#ffffff",
loading:{
icon:"/static/Fingerprint.png"
}
});
wt.onclose=function(){
plus.fingerprint.cancel();
}
}
// #endif
// #ifdef MP-WEIXIN
wx.startSoterAuthentication({
requestAuthModes: ['fingerPrint'],
challenge: '123456',
authContent: '请用指纹解锁',
success(res) {
uni.showToast({
title: '识别成功',
mask: false,
duration: 1500
});
}
})
// #endif
}
}
}
</script>
<style>
.button_fin{
background-color: #00BBB1;
border-radius: 5px ;
width: 80%;
color: #D1E9E9;
}
</style>
19、 通过HbuilderX 新建项目创建的uniapp项目如何关闭sockjs-node/info
HBuilderX安装目录下
\plugins\uniapp-cli\node_modules\sockjs-client\dist\sockjs.js
找到代码的 1605行
try {
// self.xhr.send(payload); 把这里注掉
} catch (e) {
self.emit('finish', 0, '');
self._cleanup(false);
}
20、uniapp_vue_更改数据后_页面组件的值未刷新
可能原因:可能是对象层数太深了
通用解决办法:控制未刷新组件,先不显示,再显示
1、组件添加v-if控制显示
<view v-for="(item,index) in dataArr" :key="index">
<hx-number-box v-if="showNumberBox" v-mode="item.name"></hx-number-box>
</view>
2、刷新方法
// 修改组件双向绑定的数据
this.dataArr[i].name = 3;
//刷新显示
let that = this;
that.showNumberBox = false;
that.$nextTick(()=>{
that.showNumberBox = true;
})
nextTick会等待下一个时间片执行,即等上面的数据修改完成后。
解决方法2:组件的数据绑定对象,换成一个浅一点的对象
ask.dcloud.net.cn/article/378…
21、 uniapp 输入框防抖节流_函数的节流(throttle)与防抖(debounce)
一、函数节流(throttle)
- 理解:
在函数需要频繁触发时: 函数执行一次后,只有大于设定的执行周期后才会执行第二次 适合多次事件按时间做平均分配触发
- 场景:
窗口调整(resize) 页面滚动(scroll) DOM 元素的拖拽功能实现(mousemove) - 抢购疯狂点击(click) 抢购疯狂点击(click)
二、函数防抖(debounce)
- 理解:
在函数需要频繁触发时: 在规定时间内,只让最后一次生效,前面的不生效。 适合多次事件一次响应的情况 2. 场景:
输入框实时搜索联想(keyup/input)
三、封装
- 函数节流-封装
/*
用来返回节流函数的工具函数
*/
function throttle(callback, delay) {
let pre = 0 // 默认值不要是Date.now() ==> 第1次事件立即调用
return function (event) { // 节流函数/真正的事件回调函数 this是发生事件的标签
const current = Date.now()
if (current - pre > delay) { // 只有离上一次调用callback的时间差大于delay
// 调用真正处理事件的函数, this是事件源, 参数是event
callback.call(this, event)
// 记录此次调用的时间
pre = current
}
}
}
// 使用封装的节流函数
document.addEventListener('scroll',throttle(function() {
console.log('这是带有大量计算的函数')
},2000))
2. 函数防抖-封装
/*
用来返回防抖函数的工具函数
*/
function debounce(callback, delay) {
return function (event) {
// 如果上次事件还没有真正处理, 取消它
// if (callback.timeoutId) { // 会查找原型链
if (callback.hasOwnProperty('timeId')) { // 不会查找原型链
// 清除
clearTimeout(callback.timeId)
}
// 发事件发生指定事件后才调用处理事件的回调函数
// 启动定时器, 只是准备真正处理
callback.timeId = setTimeout(() => {
// 正在处理事件
callback.call(this, event)
// 删除准备处理的标记
delete callback.timeId
}, delay)
}
}
// 使用封装的防抖函数
document.querySelector('.input').addEventListener('input',debounce((e)=>{
console.log(e.target.value)
},1000))
四、直接使用
1. 函数节流-直接使用
// 定义一个记录时间的变量
let flagTime = Date.now()
// 直接使用函数节流
document.addEventListener('scroll',function(e) {
let current = Date.now()
// 表示1000毫秒执行一次
if(current-flagTime<1000) return
// 执行代码
console.log('我是带有大量计算的函数')
// 最后修改原来的时间
flagTime = current
})
2.函数防抖-直接使用
document.querySelector('.input').addEventListener('input',function(e) {
// 判断this.timeId是否有值
if(this.timeId) {
// 有就清除定时器
clearInterval(this.timeId)
}
// 为 this.timeId赋值,定时器表示1000毫秒内触发了input事件就不执行,只有超过了1000毫秒才执行
this.timeId = setTimeout(()=>{
console.log(e.target.value)
},1000)
})
22、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();
}
23、uniapp与webview之间的相互传值
1.uni-app 如何发送数据到 H5? 其实很接单、在 web-view 中只需要通过 URL 就可以向 H5 进行传参 例如在 uni-app 中:
<template>
<view class="advertisement" style="width: 100%;">
<web-view :src="url" @message="message"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
url:'/hybrid/html/local.html?data='
};
},
onLoad(data) {
//这里对要传入到webview中的参数进行encodeURIComponent编码否则中文乱码
this.url+=encodeURIComponent(data.data)
},
mounted() {},
methods: {
message(event){
console.log(event.detail.data);
},
}
};
</script>
<style scoped="scoped" lang="scss">
@import './advertisement.scss';
</style>
在 H5 中是接收值
console.log(getQuery('data')); //获取 uni-app 传来的值
//取url中的参数值
function getQuery(name) {
// 正则:[找寻'&' + 'url参数名字' = '值' + '&']('&'可以不存在)
let reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
let r = window.location.search.substr(1).match(reg);
console.log(r);
if(r != null) {
// 对参数值进行解码
return decodeURIComponent(r[2]);
}
return null;
}
2.webview向uniapp传值
<script>
document.addEventListener('UniAppJSBridgeReady', function() {
//向uniapp传值
uni.postMessage({
data: {
action: 'message'
}
});
uni.getEnv(function(res) {
console.log('当前环境:' + JSON.stringify(res));
});
});
</script>
uniapp接受返回值
//message接受方法
<template>
<view class="advertisement" style="width: 100%;">
<web-view :src="url" @message="message"></web-view>
</view>
</template>
24、uniapp H5刷新页面问题解决
//#ifndef H5
let pages = getCurrentPages();
for(let i = 0; i < pages.length; i ++){
let tmppg = pages[i];
if(tmppg.route == "pages/user/user"){
tmppg.onLoad();
}
// console.log('tmppg:' + tmppg)
// console.log('tmppg.route:' + tmppg.route)
}
//#endif
//#ifdef H5
window.location.reload();
//#endif
25、在uniapp或者vue中,单行文字或者数字无法换行导致后面内容无法展示问题的解决方案
view {
white-space: normal; // 规定段落中的文本不进行换行
// 数字换行字符串截断换行
word-break: break-all; // 允许单词中换行,在容器的最右边进行断开不会浪费控件
// 数字换行字符串不截断换行
word-wrap: break-word; // 防止长单词溢出,单词内部短句
}
26、uni-app h5端双标题解决方法
H5端双标题栏
由于APP端和小程序端都有原生的标题栏可以使用,H5端页面没提供一个可以隐藏标题的方法,在移动端访问的时候会出现双标题,一个是微信浏览器的标题,加上运行到H5项目模拟的标题栏,如图:
解决思路:
在发布到H5端时不渲染这个标题栏。然后观察到最后这个标题栏在发布时会渲染成一个<uni-page-head>元素,在全局的css中如下设置
uni-page-head {
display: none;
}
标题栏去掉之后的效果:
但是去掉标题栏后会导致页面主体部分,H5中渲染为<uni-page-wrapper>的标签高度计算错误,可以加上下面的代码重新计算高度(好像高度不对并不会影响显示效果,哈哈哈)
uni-page-wrapper {
height: calc(100% - 50px - env(safe-area-inset-bottom)) !important;
}
//50px为底部导航栏的高度
H5端标题自动修改
解决了标题栏的显示问题,还有个令人头疼的问题就是pages.json中给每个页面设置的标题,在页面切换的时候其实改得是模拟的标题栏,我们把模拟的标题栏隐藏以后,标题就不会变化了,所以我们用到document.title来修改页面的标题。
已知两种修改标题的情况,一种是固定标题,还有一种是动态标题,比如***商品详情。 封装了一个修改标题的方法,在项目的main.js中对Vue的mixin中添加一个onShow
Vue.mixin({
onShow() {
let { title } = this //在固定标题的页面data中设置title
if (this.$mp.query) { //整个app的onShow也会触发,这时$mp中没有query属性
let setTitle = this.$mp.query.title || title //在进入页面的query中没有title属性时会取data中的title
if (setTitle) {
uni.setNavigationBarTitle({ //uni-app 的修改title接口
title: setTitle
})
//以下为H5平台差异写法
// #ifdef H5
document.title = setTitle
// #endif
}
}
}
})
这样每个页面在onShow的时候就会自动修改页面的标题了。
27、uni-app框架的switch组件的checked属性值动态绑定不生效
1.原因分析:可能是变量层级太深的原因:
this.$set(this.checkoutInfo.goods_list[0].goods[index2], "integralSelf", false)
2.解决方案:
在switch组件外层添加一个变量isShowEle做if判断,先隐藏组件后显示,这样switch组件就会重新渲染数据了,唯一的缺点是按钮会有闪烁,这个闪烁时间可自行调节(我在代码设置了默认100毫秒),建议还是要做个定时器,毕竟页面加载需要耗时可能会导致switch按钮还是没生效。
<view class="value" v-if="!goodsItem.isShowEle">
<switch :checked="goodsItem.integralSelf" @change="integralSelfHandle" />
</view>
this.$set(this.checkoutInfo.goods_list[0].goods[index2], "isShowEle", true) //先隐藏switch组件
this.$set(this.checkoutInfo.goods_list[0].goods[index2], "integralSelf", false) //修改checked绑定的变量值
this.$nextTick(()=>{
setTimeout(()=>{
this.$set(this.checkoutInfo.goods_list[0].goods[index2], "isShowEle", false) //显示switch组件
this.$forceUpdate() //强制更新
},100)
})
28、uniapp小程序禁止遮罩弹窗下的页面滚动
<template>
<view class="container" :style="showMsk ? 'height: 100vh' : ''">
<!-- 滚动列表 -->
<scroll-view scroll-y="true">
</scroll-view>
<!-- 自定义弹窗 -->
<view v-if="showMsk" class="msk"
@touchmove.stop.prevent="moveHandle">
</view>
</view>
<template>
<script>
...
data() {
return {
showMsk: false,
};
},
methods: {
moveHandle: {
return;
}
}
...
</script
29、mui的APP和uni-app的程序对于提示安卓9不兼容、无响应等问题的解决方法
1、开启相关权限:
"ssl": {
"untrustedca": "accept" //安卓9屏蔽了非https的访问,在这里设置允许非https的请求
},
与 "orientation"同级,写入后保存即可
2、设置API等级高于24,建议使用26
"targetSdkVersion" : 26, //API等级设置
30、uni-app打包H5跟小程序后会自动请求shadow-grey.png的问题
问题分析:
这个图片是导航栏底边阴影效果预加载加速显示用的。
2.解决方案:
如果不需要参考下面的配置:
H5 平台:在起始页 html 文件中添加下面代码,参考 manifest H5 index.html 模板配置
body::after { content: none; }
有需要的可以进行下面的替换。\
使用方法
background-image:url(https://cdn.dcloud.net.cn/img/shadow-blue.png);
替换为:
background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURb7T9ezy/MbY9t/p tHg Pf6/gmQWsMAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==)
下面是各个颜色的Base64编码,需要对css文件逐个替换 cdn.dcloud.net.cn/img/shadow-…
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURb7T9ezy/MbY9t/p+tHg+Pf6/gmQWsMAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==
cdn.dcloud.net.cn/img/shadow-…
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURb71vuz87Mb2xt/639H40ff+98iMtmEAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==
cdn.dcloud.net.cn/img/shadow-…
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURdnZ2fT09N7e3uzs7OTk5Pr6+vVa4lkAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==
cdn.dcloud.net.cn/img/shadow-…
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURfXTvvzy7PbYxvrp3/jg0f7692in75UAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==
cdn.dcloud.net.cn/img/shadow-…
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURfW+yvzs7/bG0Prf5PjR2v73+TToEXgAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==
cdn.dcloud.net.cn/img/shadow-…
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAGBAMAAADwPukCAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAASUExURfXvvvz67Pbxxvr33/j00f7997nVB7sAAAAUSURBVAjXY2BgUGBwYDBgEGAIAAAEXADx8btKYQAAAABJRU5ErkJggg==
31、uniapp图片加载不出来的解决方案
分为两种
1.第一种
<image :src="require('../../static/picture')"> //使用v-bind + require
2.第二种
第一种可以解决99%的问题,若有1%的没解决,可以使用background-image属性
background-image:url(../../static/picture.png);
总结:使用图片的最好是,本地图片使用背景图,万无一失,网络图片使用image src。