
上滑隐藏底部下滑展开底部HTML模板
演示截图
模板下载
https://21sqw.lanzous.com/ij7k8fb1l4h
演示截图
模板下载
https://21sqw.lanzous.com/ij7k8fb1l4h

webview会自动铺满,解决占领手机状态栏
在webview的page页面中,created()生命周期中,
// #ifdef APP-PLUS
var currentWebview = this.$mp.page.$getAppWebview(); //获取当前web-view
setTimeout(function() {
var wv = currentWebview.children()[0];
wv.setStyle({ //设置web-view距离顶部的距离以及自己的高度,单位为px
top: uni.getSystemInfoSync().statusBarHeight,
})
}, 1000);
// #endif
在webview的page页面中,created()生命周期中,
// #ifdef APP-PLUS
var currentWebview = this.$mp.page.$getAppWebview(); //获取当前web-view
setTimeout(function() {
var wv = currentWebview.children()[0];
wv.setStyle({ //设置web-view距离顶部的距离以及自己的高度,单位为px
top: uni.getSystemInfoSync().statusBarHeight,
})
}, 1000);
// #endif

热更新
//APP更新
import httpUtil from "./HttpUtils.js"
import Urls from "./Urls.js"
var update = function(callback) {
uni.showToast({
title: '开始检查更新',
mask: false,
duration: 5000,
icon: "none"
});
uni.getSystemInfo({
success: (res) => {
console.log(res)
CheckUpdate(res.platform, callback);
}
})
function autoUpdateRes(url) {
//#ifdef APP-PLUS
const dtask = plus.downloader.createDownload(url, {
},
function(d, status) {
// 下载完成
if (status == 200) {
// var files = plus.io.convertLocalFileSystemURL(d.filename);
//下载成功,d.filename是文件在保存在本地的相对路径,使用下面的API可转为平台绝对路径
//var fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename);
// plus.runtime.openFile(d.filename); //选择软件打开文件
plus.nativeUI.showWaiting("安装wgt文件...");
plus.runtime.install(d.filename, {}, function() {
plus.nativeUI.closeWaiting();
console.log("安装wgt文件成功!");
plus.nativeUI.alert("应用资源更新完成!", function() {
plus.runtime.restart();
});
}, function(e) {
plus.nativeUI.closeWaiting();
console.log("安装wgt文件失败[" + e.code + "]:" + e.message);
plus.nativeUI.alert("安装wgt文件失败[" + e.code + "]:" + e.message);
});
} else {
uni.showToast({
title: '更新失败' + status,
mask: false,
duration: 1500
});
//下载失败
plus.downloader.clear(); //清除下载任务
}
});
dtask.start();
//#endif
};
// 自动更新
function CheckUpdate(platform, callback) {
httpUtil.httpUtil(Urls.URLDATA.UPDATE_VERSION, {
'platform': platform
}, function(res) {
console.log(res)
if (res.data.data && (res.data.data.number > plus.runtime.version)) {
/* if (plus.networkinfo.getCurrentType() != 3) {
uni.showToast({
title: '有新的版本发布,检测到您目前非Wifi连接,为节约您的流量,程序已停止自动更新,将在您连接WIFI之后重新检测更新。',
mask: false,
duration: 5000,
icon: "none"
});
return;
} */
if (res.data.data.type < 3) {
uni.showModal({
title: '新版本提示',
content: res.data.data.desc,
success: function(re) {
if (re.confirm) {
if (res.data.data.type == 1) { // 热更新
autoUpdateRes(res.data.data.path);
} else {
downloadFile(res.data.data.path, callback);
}
} else if (re.cancel) {
uni.showToast({
title: '已取消更新',
mask: false,
duration: 5000,
icon: "none"
});
}
}
});
} else {
// 强制更新
if (res.data.data.type == 3) { // 热更新
autoUpdateRes(res.data.data.path);
} else {
downloadFile(res.data.data.path, callback);
}
}
} else {
uni.showToast({
title: '当前已是最新版',
mask: false,
duration: 5000,
icon: "none"
});
}
})
}
//整包更新
function packageDownload(downloadUrl) {
plus.runtime.openURL(downloadUrl) //整包下载
}
function downloadFile(url, callback) {
//#ifdef APP-PLUS
const dtask = plus.downloader.createDownload(url, {},
function(d, status) {
// 下载完成
if (status == 200) {
// plus.runtime.openFile(d.filename); //选择软件打开文件
plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename), {}, function(e) {
uni.showToast({
title: '更新成功,需要重启' + JSON.stringify(e),
mask: false,
duration: 1000
});
uni.removeSavedFile({
filePath: plus.io.convertLocalFileSystemURL(d.filename),
complete: function(res) {
console.log(res);
}
});
plus.runtime.restart();
}, function(error) {
uni.showToast({
title: '安装失败' + error.message,
mask: false,
duration: 1000
});
uni.removeSavedFile({
filePath: plus.io.convertLocalFileSystemURL(d.filename),
complete: function(res) {
console.log(res);
}
});
})
} else {
uni.showToast({
title: '更新失败' + status,
mask: false,
duration: 1000
});
//下载失败
plus.downloader.clear(); //清除下载任务
}
});
dtask.addEventListener('statechanged', (task) => {
if (callback) {
callback(task);
}
});
dtask.start();
//#endif
}
}
module.exports = {
update
}
//APP更新
import httpUtil from "./HttpUtils.js"
import Urls from "./Urls.js"
var update = function(callback) {
uni.showToast({
title: '开始检查更新',
mask: false,
duration: 5000,
icon: "none"
});
uni.getSystemInfo({
success: (res) => {
console.log(res)
CheckUpdate(res.platform, callback);
}
})
function autoUpdateRes(url) {
//#ifdef APP-PLUS
const dtask = plus.downloader.createDownload(url, {
},
function(d, status) {
// 下载完成
if (status == 200) {
// var files = plus.io.convertLocalFileSystemURL(d.filename);
//下载成功,d.filename是文件在保存在本地的相对路径,使用下面的API可转为平台绝对路径
//var fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename);
// plus.runtime.openFile(d.filename); //选择软件打开文件
plus.nativeUI.showWaiting("安装wgt文件...");
plus.runtime.install(d.filename, {}, function() {
plus.nativeUI.closeWaiting();
console.log("安装wgt文件成功!");
plus.nativeUI.alert("应用资源更新完成!", function() {
plus.runtime.restart();
});
}, function(e) {
plus.nativeUI.closeWaiting();
console.log("安装wgt文件失败[" + e.code + "]:" + e.message);
plus.nativeUI.alert("安装wgt文件失败[" + e.code + "]:" + e.message);
});
} else {
uni.showToast({
title: '更新失败' + status,
mask: false,
duration: 1500
});
//下载失败
plus.downloader.clear(); //清除下载任务
}
});
dtask.start();
//#endif
};
// 自动更新
function CheckUpdate(platform, callback) {
httpUtil.httpUtil(Urls.URLDATA.UPDATE_VERSION, {
'platform': platform
}, function(res) {
console.log(res)
if (res.data.data && (res.data.data.number > plus.runtime.version)) {
/* if (plus.networkinfo.getCurrentType() != 3) {
uni.showToast({
title: '有新的版本发布,检测到您目前非Wifi连接,为节约您的流量,程序已停止自动更新,将在您连接WIFI之后重新检测更新。',
mask: false,
duration: 5000,
icon: "none"
});
return;
} */
if (res.data.data.type < 3) {
uni.showModal({
title: '新版本提示',
content: res.data.data.desc,
success: function(re) {
if (re.confirm) {
if (res.data.data.type == 1) { // 热更新
autoUpdateRes(res.data.data.path);
} else {
downloadFile(res.data.data.path, callback);
}
} else if (re.cancel) {
uni.showToast({
title: '已取消更新',
mask: false,
duration: 5000,
icon: "none"
});
}
}
});
} else {
// 强制更新
if (res.data.data.type == 3) { // 热更新
autoUpdateRes(res.data.data.path);
} else {
downloadFile(res.data.data.path, callback);
}
}
} else {
uni.showToast({
title: '当前已是最新版',
mask: false,
duration: 5000,
icon: "none"
});
}
})
}
//整包更新
function packageDownload(downloadUrl) {
plus.runtime.openURL(downloadUrl) //整包下载
}
function downloadFile(url, callback) {
//#ifdef APP-PLUS
const dtask = plus.downloader.createDownload(url, {},
function(d, status) {
// 下载完成
if (status == 200) {
// plus.runtime.openFile(d.filename); //选择软件打开文件
plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename), {}, function(e) {
uni.showToast({
title: '更新成功,需要重启' + JSON.stringify(e),
mask: false,
duration: 1000
});
uni.removeSavedFile({
filePath: plus.io.convertLocalFileSystemURL(d.filename),
complete: function(res) {
console.log(res);
}
});
plus.runtime.restart();
}, function(error) {
uni.showToast({
title: '安装失败' + error.message,
mask: false,
duration: 1000
});
uni.removeSavedFile({
filePath: plus.io.convertLocalFileSystemURL(d.filename),
complete: function(res) {
console.log(res);
}
});
})
} else {
uni.showToast({
title: '更新失败' + status,
mask: false,
duration: 1000
});
//下载失败
plus.downloader.clear(); //清除下载任务
}
});
dtask.addEventListener('statechanged', (task) => {
if (callback) {
callback(task);
}
});
dtask.start();
//#endif
}
}
module.exports = {
update
}
收起阅读 »

uni.requestSubscribeMessage 没响应的问题
1、微信调试基础库 调到2.8.2以上
2、uni 的button 不论是@click 还是@tap ,微信小程序都识别不了,都说要bindtap 绑定来触发
解决方法 : 利用uni.showmodal 来触发 就OK了
1、微信调试基础库 调到2.8.2以上
2、uni 的button 不论是@click 还是@tap ,微信小程序都识别不了,都说要bindtap 绑定来触发
解决方法 : 利用uni.showmodal 来触发 就OK了

uni-app清除定时器
export default {
data() {
return {
timer: null,
}
},
methods: {
timeUp() {
clearInterval(this.timer)
},
this.timer = setInterval(() => {
uni.navigateTo({
url: '../index/index'
});
this.timeUp()
}, 2000)
}
}
export default {
data() {
return {
timer: null,
}
},
methods: {
timeUp() {
clearInterval(this.timer)
},
this.timer = setInterval(() => {
uni.navigateTo({
url: '../index/index'
});
this.timeUp()
}, 2000)
}
}

uni app使用mobx | uni app状态管理mobx
使用mobx的响应函数autorun监听状态变化进行赋值和运行函数,页面onLoad时执行所有autorun,页面onUnload时销毁所有autorun
以下是ts代码模板
<template>
<div class="${NAME}">
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from "vue-property-decorator";
import {autorun, observe, toJS} from "mobx";
import _ from 'lodash';
import {store} from '@/utils/store'
@Component
export default class ${NAME} extends Vue {
/*创建监听*/
createDisposer() {
//观察状态变化
this.disposer.push(autorun(() => {
//this.step3 = store.step
}))
}
//映射监听
createDisposerMap(obj: any) {
const _this = this
_.forOwn(obj, (v, k) => {
_this.disposer.push(autorun(() => {
if (_.isArray(obj)) {
_this[v] = toJS(store[v])
} else {
_this[k] = toJS(store[v])
}
}))
})
}
//销毁监听
destroyDisposer() {
this.disposer.map(x => x())
this.disposer.length = 0
}
//监听列表
disposer: Function[] = []
onUnload() {
this.destroyDisposer()
}
onLoad(evt?: any) {
this.createDisposer()
//this.createDisposerMap(['step'])
//this.createDisposerMap({step2: 'step'})
}
}
</script>
<style scoped lang="stylus">
.${NAME}
padding 0
</style>
使用mobx的响应函数autorun监听状态变化进行赋值和运行函数,页面onLoad时执行所有autorun,页面onUnload时销毁所有autorun
以下是ts代码模板
<template>
<div class="${NAME}">
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from "vue-property-decorator";
import {autorun, observe, toJS} from "mobx";
import _ from 'lodash';
import {store} from '@/utils/store'
@Component
export default class ${NAME} extends Vue {
/*创建监听*/
createDisposer() {
//观察状态变化
this.disposer.push(autorun(() => {
//this.step3 = store.step
}))
}
//映射监听
createDisposerMap(obj: any) {
const _this = this
_.forOwn(obj, (v, k) => {
_this.disposer.push(autorun(() => {
if (_.isArray(obj)) {
_this[v] = toJS(store[v])
} else {
_this[k] = toJS(store[v])
}
}))
})
}
//销毁监听
destroyDisposer() {
this.disposer.map(x => x())
this.disposer.length = 0
}
//监听列表
disposer: Function[] = []
onUnload() {
this.destroyDisposer()
}
onLoad(evt?: any) {
this.createDisposer()
//this.createDisposerMap(['step'])
//this.createDisposerMap({step2: 'step'})
}
}
</script>
<style scoped lang="stylus">
.${NAME}
padding 0
</style>
收起阅读 »

海康(HIKVISION)视频监控,实时视频预览、录像回放
海康(HIKVISION)视频监控,实时视频预览、录像回放:https://ext.dcloud.net.cn/plugin?id=2403
海康(HIKVISION)视频监控,实时视频预览、录像回放:https://ext.dcloud.net.cn/plugin?id=2403

SQLITE 用plus.io操作www目录移植doc目录异常的问题和操作www目录报错的问题。
首先 www 不支持写入操作的,所以一些东西我们需要有移到doc操作
但是用plus.io操作操作www目录时就会报 “执行错误” 或者 ”路径不存在“。
首先说明下原因:那是因为没有权限造成的。
没有权限之前的目录定位在> /storage/emulated/下的APP包名中,
这种情况下www目录是不存在的,所以也就没有资源,路径什么的也就不正确了。
设置权限以后则定为到> /data/user/目录下APP包名中,
这个目录下找到对应的APP就有之前打包的所有资源。
可以通过以下的操作来完成配置权限。
打开 manifest 选择 App权限配置 再右侧权限列表中 勾选
<uses-permission android:name=\"android.permission.WRITE_PROFILE\"/>
重新打包就可以了,
首先 www 不支持写入操作的,所以一些东西我们需要有移到doc操作
但是用plus.io操作操作www目录时就会报 “执行错误” 或者 ”路径不存在“。
首先说明下原因:那是因为没有权限造成的。
没有权限之前的目录定位在> /storage/emulated/下的APP包名中,
这种情况下www目录是不存在的,所以也就没有资源,路径什么的也就不正确了。
设置权限以后则定为到> /data/user/目录下APP包名中,
这个目录下找到对应的APP就有之前打包的所有资源。
可以通过以下的操作来完成配置权限。
打开 manifest 选择 App权限配置 再右侧权限列表中 勾选
<uses-permission android:name=\"android.permission.WRITE_PROFILE\"/>
重新打包就可以了,
收起阅读 »
iOS wkwebview h5拉起支付宝支付方案
经研究,使用wkwebview时,h5页面无法拉起部分支付宝支付,新版h5支付可以打开,旧版不行,应该是alipay://私有协议无法打开,这个情况下思路是拦截alipay协议,通过plus.runtime.openURL实现打开;这个思路没问题,实操的时候有个bug,那就是overrideUrlLoading拦截无法拦截非https http ftp外的链接,导致无法获知支付宝的alipay私有协议具体内容,业务无法实现。
特别说明:新版支付宝h5链接直接打开可以调起支付宝,旧版不行,本方案仅适用于旧版支付宝H5。
重点:支付宝的js代码,有一个全局变量window._data,里面保存了调用支付宝需要的参数,invokeAlipayData,使用该参数,拼接支付宝协议可实现支付宝调用
最终思路:wkwebview调用支付宝H5,overrideUrlLoading拦截所有链接,通过注入一个js,获取到invokeAlipayData,通过window.location.href进行跳转,由拦截器进行处理,拦截器得到三种链接:1.经过注入js处理的带有支付宝参数的链接(处理);2.支付宝自有H5继续支付链接(忽略);3.支付成功回调链接(处理)
示例代码如下(仅提供思路,具体业务请自行完善)
<template>
<view></view>
</template>
<script>
var wv;//计划创建的webview
var currentWebview
export default {
data() {
return {
oid:''
}
},
onLoad(op) {
wv = plus.webview.create("","custom-webview",{
plusrequire:"none", //禁止远程网页使用plus的API,有些使用mui制作的网页可能会监听plus.key,造成关闭页面混乱,可以通过这种方式禁止
'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
top:uni.getSystemInfoSync().statusBarHeight+44 //放置在titleNView下方。如果还想在webview上方加个地址栏的什么的,可以继续降低TOP值
})
currentWebview = this.$scope.$getAppWebview();
this.oid = op.oid
this.takePayemnt()
},
onShow(){
},
onReady(){
},
methods: {
/*发起支付宝支付*/
takePayemnt(){
let params ={}
params['oid'] = this.oid
params['way'] = 1
let that = this
this.fetch.post("***", params , true)//我司接口,获取支付宝的支付form
.then(res => {
wv.loadData(res.result)//加载后端返回的form片段
currentWebview.append(wv);
setTimeout(()=>{
/*关键代码:注入js,点击按钮时获取window._data.data.invokeAlipayData数据,跳转到指定链接拦截(私有协议无法拦截),该数据可拉起支付宝支付*/
wv.evalJS('$(document).on("click", "a", function(event){window.location.href="https://fuckyou.com?params="+JSON.stringify(window._data.data.invokeAlipayData);});');
let sb = currentWebview.children()[0]
// 监听拦截,拦截所有页面跳转
sb.overrideUrlLoading({mode: 'reject',match:''}, function(e) {
console.log('reject url: ' + e.url);
/*检查拦截的url是否注入的js跳转链接,是的话通过plus.runtime.openURL打开该链接*/
if(e.url.search("fuckyou") != -1){
let params = e.url.substring(28)
let url = 'alipay://alipayclient/?' + params
plus.runtime.openURL(url, function(res) {
console.log(res);
});
}else{
/*非注入js引导链接,一般为支付成功的跳转*/
let oid = that.getQueryVariable('out_trade_no',e.url)
if(oid){
uni.redirectTo({
url:'alipaySuccess?out_trade_no='+oid
})
}
}
});
},500)
}).catch(function (error) {
});
},
getQueryVariable(variable,url)
{
var query = url.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
}
}
</script>
<style lang="scss" scoped>
.page-view{
min-height: 100vh;
}
.result{
text-align: center;
padding-top:150rpx;
}
.tips{
font-weight: bold;
font-size: 40rpx;
margin:100rpx 0;
}
.btn{
margin:50rpx 80rpx;
}
</style>
经研究,使用wkwebview时,h5页面无法拉起部分支付宝支付,新版h5支付可以打开,旧版不行,应该是alipay://私有协议无法打开,这个情况下思路是拦截alipay协议,通过plus.runtime.openURL实现打开;这个思路没问题,实操的时候有个bug,那就是overrideUrlLoading拦截无法拦截非https http ftp外的链接,导致无法获知支付宝的alipay私有协议具体内容,业务无法实现。
特别说明:新版支付宝h5链接直接打开可以调起支付宝,旧版不行,本方案仅适用于旧版支付宝H5。
重点:支付宝的js代码,有一个全局变量window._data,里面保存了调用支付宝需要的参数,invokeAlipayData,使用该参数,拼接支付宝协议可实现支付宝调用
最终思路:wkwebview调用支付宝H5,overrideUrlLoading拦截所有链接,通过注入一个js,获取到invokeAlipayData,通过window.location.href进行跳转,由拦截器进行处理,拦截器得到三种链接:1.经过注入js处理的带有支付宝参数的链接(处理);2.支付宝自有H5继续支付链接(忽略);3.支付成功回调链接(处理)
示例代码如下(仅提供思路,具体业务请自行完善)
<template>
<view></view>
</template>
<script>
var wv;//计划创建的webview
var currentWebview
export default {
data() {
return {
oid:''
}
},
onLoad(op) {
wv = plus.webview.create("","custom-webview",{
plusrequire:"none", //禁止远程网页使用plus的API,有些使用mui制作的网页可能会监听plus.key,造成关闭页面混乱,可以通过这种方式禁止
'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
top:uni.getSystemInfoSync().statusBarHeight+44 //放置在titleNView下方。如果还想在webview上方加个地址栏的什么的,可以继续降低TOP值
})
currentWebview = this.$scope.$getAppWebview();
this.oid = op.oid
this.takePayemnt()
},
onShow(){
},
onReady(){
},
methods: {
/*发起支付宝支付*/
takePayemnt(){
let params ={}
params['oid'] = this.oid
params['way'] = 1
let that = this
this.fetch.post("***", params , true)//我司接口,获取支付宝的支付form
.then(res => {
wv.loadData(res.result)//加载后端返回的form片段
currentWebview.append(wv);
setTimeout(()=>{
/*关键代码:注入js,点击按钮时获取window._data.data.invokeAlipayData数据,跳转到指定链接拦截(私有协议无法拦截),该数据可拉起支付宝支付*/
wv.evalJS('$(document).on("click", "a", function(event){window.location.href="https://fuckyou.com?params="+JSON.stringify(window._data.data.invokeAlipayData);});');
let sb = currentWebview.children()[0]
// 监听拦截,拦截所有页面跳转
sb.overrideUrlLoading({mode: 'reject',match:''}, function(e) {
console.log('reject url: ' + e.url);
/*检查拦截的url是否注入的js跳转链接,是的话通过plus.runtime.openURL打开该链接*/
if(e.url.search("fuckyou") != -1){
let params = e.url.substring(28)
let url = 'alipay://alipayclient/?' + params
plus.runtime.openURL(url, function(res) {
console.log(res);
});
}else{
/*非注入js引导链接,一般为支付成功的跳转*/
let oid = that.getQueryVariable('out_trade_no',e.url)
if(oid){
uni.redirectTo({
url:'alipaySuccess?out_trade_no='+oid
})
}
}
});
},500)
}).catch(function (error) {
});
},
getQueryVariable(variable,url)
{
var query = url.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
}
}
</script>
<style lang="scss" scoped>
.page-view{
min-height: 100vh;
}
.result{
text-align: center;
padding-top:150rpx;
}
.tips{
font-weight: bold;
font-size: 40rpx;
margin:100rpx 0;
}
.btn{
margin:50rpx 80rpx;
}
</style>
收起阅读 »

承接前端H5、小程序、APP、PC端网站等外包
承接前端H5、小程序、APP、PC端网站等外包,主要技术栈为vue、uni-app,有意请加微信:13192733603(我是前端,我找服务端合作人)
承接前端H5、小程序、APP、PC端网站等外包,主要技术栈为vue、uni-app,有意请加微信:13192733603(我是前端,我找服务端合作人)