HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

iOS wkwebview h5拉起支付宝支付方案

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(我是前端,我找服务端合作人)

2.7.9版本升级时不能成功的bug解决

升级更新

2.7.9升级到最新版时会一直失败,貌似卡在更新php插件那一步。
然后安装了php插件就可以正常升级了。

2.7.9升级到最新版时会一直失败,貌似卡在更新php插件那一步。
然后安装了php插件就可以正常升级了。

uniapp接入环信SDK(NVUE)

环信

最近公司开发及时通讯用到了环信,虽然官方有相关SDK(与微信小程序通用)BUT,在uniapp上面并不好使,收不到消息,那岂不是没有用???
详见D友发布的文章:https://ask.dcloud.net.cn/question/96293
网上查阅资料然而并无解决方案,官方似乎对此也并没有太大关注。只能自己搞了,经过简单改造后可以正常使用在APP端(NVUE),Android&ios均可正常使用,其他平台没有测试,暂时没有发现问题。

需要的筒子们下载附件中改造后的SDK即可。使用方法参考官方微信小程序接入方法。
https://www.easemob.com/download/im

继续阅读 »

最近公司开发及时通讯用到了环信,虽然官方有相关SDK(与微信小程序通用)BUT,在uniapp上面并不好使,收不到消息,那岂不是没有用???
详见D友发布的文章:https://ask.dcloud.net.cn/question/96293
网上查阅资料然而并无解决方案,官方似乎对此也并没有太大关注。只能自己搞了,经过简单改造后可以正常使用在APP端(NVUE),Android&ios均可正常使用,其他平台没有测试,暂时没有发现问题。

需要的筒子们下载附件中改造后的SDK即可。使用方法参考官方微信小程序接入方法。
https://www.easemob.com/download/im

收起阅读 »

前端人找资源(外包),熟悉uni、vue开发

外包

前端人找资源(外包),熟悉uni、vue开发。APP、小程序、H5、PC端网站都可以做,找资源(外包),找有资源的服务端开发都行,有的话加微信13192733603。

前端人找资源(外包),熟悉uni、vue开发。APP、小程序、H5、PC端网站都可以做,找资源(外包),找有资源的服务端开发都行,有的话加微信13192733603。

【分享】uniapp环境开H5端打开微信小程序,解决苹果端首次进入页面显示异常

<wx-open-launch-weapp path="pages/card/visit_card.html?id=19" id="launch-wxapp" username="gh_abc199886dfa">  
        <script type="text/wxtag-template">  
            <style>  
                .btn-open-weapp{  
                    background: linear-gradient(to right, #ffd52e 0%, #ffef93 50%, #ffd52e 100%);  
                    border: 0;  
                    color: #424242;  
                    text-shadow: 0px 1px 1px #fff;  
                    border-radius: 50px;  
                    text-align: center;  
                    width: 120px;  
                    height: 35px;  
                    line-height: 35px;  
                    outline:none;  
                }  
            </style>  
            <button class="btn-open-weapp">进店逛逛</button >  
        <script>  
</wx-open-launch-weapp>`  

原来直接这样子用,发现有问题,安卓端正常,但苹果端首次进入H5页面显示不了按钮,只有刷新才能显示,于是折腾一翻,因为H5端支持v-html,测试了下一切正常

下面这种方式,微信开发者工具也能看到按钮哦

<!-- #ifdef H5 -->  
    <view v-html="wxOpenTags"></view>  
<!-- #endif --> 
//#ifdef H5  
    setTimeout(()=>{  
        this.wxOpenTags=`<wx-open-launch-weapp path="pages/card/visit_card.html?id=19" id="launch-wxapp" username="gh_abc199886dfa">  
            <template>  
                <style>  
                .btn-open-weapp{  
                    background: linear-gradient(to right, #ffd52e 0%, #ffef93 50%, #ffd52e 100%);  
                    border: 0;  
                    color: #424242;  
                    text-shadow: 0px 1px 1px #fff;  
                    border-radius: 50px;  
                    text-align: center;  
                    width: 120px;  
                    height: 35px;  
                    line-height: 35px;  
                    outline:none;  
                }  
                </style>  
                <button class="btn-open-weapp">进店逛逛</button >  
            </template>  
        </wx-open-launch-weapp>`;  
    },1000);  
//#endif

wx-open-launch-app也用v-html的方式

继续阅读 »
<wx-open-launch-weapp path="pages/card/visit_card.html?id=19" id="launch-wxapp" username="gh_abc199886dfa">  
        <script type="text/wxtag-template">  
            <style>  
                .btn-open-weapp{  
                    background: linear-gradient(to right, #ffd52e 0%, #ffef93 50%, #ffd52e 100%);  
                    border: 0;  
                    color: #424242;  
                    text-shadow: 0px 1px 1px #fff;  
                    border-radius: 50px;  
                    text-align: center;  
                    width: 120px;  
                    height: 35px;  
                    line-height: 35px;  
                    outline:none;  
                }  
            </style>  
            <button class="btn-open-weapp">进店逛逛</button >  
        <script>  
</wx-open-launch-weapp>`  

原来直接这样子用,发现有问题,安卓端正常,但苹果端首次进入H5页面显示不了按钮,只有刷新才能显示,于是折腾一翻,因为H5端支持v-html,测试了下一切正常

下面这种方式,微信开发者工具也能看到按钮哦

<!-- #ifdef H5 -->  
    <view v-html="wxOpenTags"></view>  
<!-- #endif --> 
//#ifdef H5  
    setTimeout(()=>{  
        this.wxOpenTags=`<wx-open-launch-weapp path="pages/card/visit_card.html?id=19" id="launch-wxapp" username="gh_abc199886dfa">  
            <template>  
                <style>  
                .btn-open-weapp{  
                    background: linear-gradient(to right, #ffd52e 0%, #ffef93 50%, #ffd52e 100%);  
                    border: 0;  
                    color: #424242;  
                    text-shadow: 0px 1px 1px #fff;  
                    border-radius: 50px;  
                    text-align: center;  
                    width: 120px;  
                    height: 35px;  
                    line-height: 35px;  
                    outline:none;  
                }  
                </style>  
                <button class="btn-open-weapp">进店逛逛</button >  
            </template>  
        </wx-open-launch-weapp>`;  
    },1000);  
//#endif

wx-open-launch-app也用v-html的方式

收起阅读 »

最新版本的编辑器,云打包报这个错误

HBuilderX升级 HBuilder X

最新版本的编辑器,云打包报这个错误。麻烦官方大佬 解决下

最新版本的编辑器,云打包报这个错误。麻烦官方大佬 解决下

有关自定义底部导航栏 / 自定义tabbar的一些经验

自定义 tabbar

在开发的过程中,我们经常会遇到一些设计的很好看的底部导航栏,最常见的比如下面这种的


中间会有凸起的一部分,这个时候我们再次使用常规的做法显然已经不再合适了,在pages.json中如何配置都无法达到我们的这个需求,这个时候我们需要自定义底部导航栏,那么究竟该如何自定义呢,我看了众多的博客插件,他们的做法基本上如初一辙,写上一个自定义的导航栏,然后通过索引值判断去不断的用v-if去进行组件的切换,虽然也能实现,但是此做法存在较为严重的性能问题,我下面提供的这个做法,大家可以一试!
1.我们依然在pages.json中去配置底部导航栏,只是我们只用去配置pagePath即可,如下

"tabBar": {  
        "list": [{  
                "pagePath": "pages/tabbar/index/index" // 页面文件路径  
            },  
            {  
                "pagePath": "pages/tabbar/user/user" // 页面文件路径  
            }  
        ]  
    }

2.上方配置完成后,我们可以在app.vue 中的onLaunch周期中,写入 uni.hideTabBar() ,此作用是隐藏底部导航,特别注意,因为此api不兼容字节跳动的小程序,所以,想要在字节跳动小程序内使用需要写入tt.hideTabBar()

  1. 然后我们就可以去写上一个底部导航栏的组件,这个就是一个组件,我想大家应该都会写的,下面是我项目中写的一份


4.把此组件引入在底部导航栏的页面就可以了,这样就能较为完美的解决底部导航栏这一问题,有兴趣的开发者可以一试,至少本人写自定义导航栏一直都是这么写的,嘿嘿
当然,我依然还是推荐原生的写法,不要整那么多花里胡哨的,除了好看,一无是处,只要是自定义底部导航栏总会有那么几个性能的问题,所以建议还是要给经理,客户,老板提提建议,这样我们开发人员也能省点劲

翻看大厂的微信小程序都是原生配置的底部导航栏,为什么老板总觉得不好看,我觉得还可以啊0.0,脑壳疼

继续阅读 »

在开发的过程中,我们经常会遇到一些设计的很好看的底部导航栏,最常见的比如下面这种的


中间会有凸起的一部分,这个时候我们再次使用常规的做法显然已经不再合适了,在pages.json中如何配置都无法达到我们的这个需求,这个时候我们需要自定义底部导航栏,那么究竟该如何自定义呢,我看了众多的博客插件,他们的做法基本上如初一辙,写上一个自定义的导航栏,然后通过索引值判断去不断的用v-if去进行组件的切换,虽然也能实现,但是此做法存在较为严重的性能问题,我下面提供的这个做法,大家可以一试!
1.我们依然在pages.json中去配置底部导航栏,只是我们只用去配置pagePath即可,如下

"tabBar": {  
        "list": [{  
                "pagePath": "pages/tabbar/index/index" // 页面文件路径  
            },  
            {  
                "pagePath": "pages/tabbar/user/user" // 页面文件路径  
            }  
        ]  
    }

2.上方配置完成后,我们可以在app.vue 中的onLaunch周期中,写入 uni.hideTabBar() ,此作用是隐藏底部导航,特别注意,因为此api不兼容字节跳动的小程序,所以,想要在字节跳动小程序内使用需要写入tt.hideTabBar()

  1. 然后我们就可以去写上一个底部导航栏的组件,这个就是一个组件,我想大家应该都会写的,下面是我项目中写的一份


4.把此组件引入在底部导航栏的页面就可以了,这样就能较为完美的解决底部导航栏这一问题,有兴趣的开发者可以一试,至少本人写自定义导航栏一直都是这么写的,嘿嘿
当然,我依然还是推荐原生的写法,不要整那么多花里胡哨的,除了好看,一无是处,只要是自定义底部导航栏总会有那么几个性能的问题,所以建议还是要给经理,客户,老板提提建议,这样我们开发人员也能省点劲

翻看大厂的微信小程序都是原生配置的底部导航栏,为什么老板总觉得不好看,我觉得还可以啊0.0,脑壳疼

收起阅读 »

v3编译遇到的问题

v3

一开始如图中疯狂报错cid unmatched [object Object] at view.umd.min.js:1
10:21:33.673 TypeError: Invalid attempt to destructure non-iterable instance.
10:21:33.693 In order to be iterable, non-array objects must have a [Symbol.iterator]() method. at view.umd.min.js:1,找不出原因,然后网上百度到的内容说循环遍历出了问题,由于我的app其他列表是好的就这一个出问题,然后我就与其他列表做对比,发现写循环时一开始是这么写的<station v-for="station in stationList" :station="station" :key="station.id" />
而其他列表中则是<station v-for="station in stationList" :station="station" :key="station.stationId" />更改完之后问题就解决了

继续阅读 »

一开始如图中疯狂报错cid unmatched [object Object] at view.umd.min.js:1
10:21:33.673 TypeError: Invalid attempt to destructure non-iterable instance.
10:21:33.693 In order to be iterable, non-array objects must have a [Symbol.iterator]() method. at view.umd.min.js:1,找不出原因,然后网上百度到的内容说循环遍历出了问题,由于我的app其他列表是好的就这一个出问题,然后我就与其他列表做对比,发现写循环时一开始是这么写的<station v-for="station in stationList" :station="station" :key="station.id" />
而其他列表中则是<station v-for="station in stationList" :station="station" :key="station.stationId" />更改完之后问题就解决了

收起阅读 »

在调用的时候就知道API对不同平台的支持

HBuilder X

现在遇到一个特别麻烦的事情,uni-app混合了H5、小程序、uni-app自己的语言,很多时候不知道H5不能在app端用,写完之后发现不能用来回调试。

能否让HBuilderX工具更智能一些,调用的时候就告诉这个API能在哪个平台使用,可以为开发者节约很多的时间。

继续阅读 »

现在遇到一个特别麻烦的事情,uni-app混合了H5、小程序、uni-app自己的语言,很多时候不知道H5不能在app端用,写完之后发现不能用来回调试。

能否让HBuilderX工具更智能一些,调用的时候就告诉这个API能在哪个平台使用,可以为开发者节约很多的时间。

收起阅读 »

app进入后台,多任务管理器,界面变毛玻璃高斯模糊、透明效果

app进入后台毛玻璃高斯模糊效果(ios):https://ext.dcloud.net.cn/plugin?id=2373
app进入后台透明效果、应用内禁止截屏(andorid):https://ext.dcloud.net.cn/plugin?id=2379

继续阅读 »

app进入后台毛玻璃高斯模糊效果(ios):https://ext.dcloud.net.cn/plugin?id=2373
app进入后台透明效果、应用内禁止截屏(andorid):https://ext.dcloud.net.cn/plugin?id=2379

收起阅读 »