HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

App 下载视频到本地相册

const downloadTask = uni.downloadFile({  
                        url: url,  // 视频的下载地址  
                        success: (data) => {  
                            if (data.statusCode === 200) {  
                                 uni.saveImageToPhotosAlbum({ // 需要保存到相册 如果是下载文件 用uni.saveFile()  
                                      filePath: data.tempFilePath, // 视频的本地临时地址  
                                      success: function (res) {  
                                          console.log('下载成功')  
                                        uni.showToast({  
                                            title: '下载完成,请到相册查看',  
                                            position: 'center',  
                                            icon: 'none',  
                                            duration: 2000  
                                        });  
                                      },  
                                      fail: () => {  
                                        uni.showToast({  
                                            title: '下载视频失败请重试',  
                                            position: 'center',  
                                            icon: 'none',  
                                            duration: 2000  
                                        });  
                                      }  
                                    });  
                            }  
                        },  
                        fail: (err)=>{  
                            this.downText = '下载视频'  
                            uni.hideLoading()  
                            uni.showToast({  
                                title: err,  
                                position: 'center',  
                                icon: 'none',  
                                duration: 2000  
                            });  
                        },  
                        complete: ()=>{  
                            this.downText ='下载视频'  
                        }  
                    });  

                    downloadTask.onProgressUpdate((res) => { // 下载进度  
                        this.downText = `已下载${res.progress}%`  
                        if(res.progress == 100){  
                            this.downText = '下载视频'  

                        }  
                    });
继续阅读 »
const downloadTask = uni.downloadFile({  
                        url: url,  // 视频的下载地址  
                        success: (data) => {  
                            if (data.statusCode === 200) {  
                                 uni.saveImageToPhotosAlbum({ // 需要保存到相册 如果是下载文件 用uni.saveFile()  
                                      filePath: data.tempFilePath, // 视频的本地临时地址  
                                      success: function (res) {  
                                          console.log('下载成功')  
                                        uni.showToast({  
                                            title: '下载完成,请到相册查看',  
                                            position: 'center',  
                                            icon: 'none',  
                                            duration: 2000  
                                        });  
                                      },  
                                      fail: () => {  
                                        uni.showToast({  
                                            title: '下载视频失败请重试',  
                                            position: 'center',  
                                            icon: 'none',  
                                            duration: 2000  
                                        });  
                                      }  
                                    });  
                            }  
                        },  
                        fail: (err)=>{  
                            this.downText = '下载视频'  
                            uni.hideLoading()  
                            uni.showToast({  
                                title: err,  
                                position: 'center',  
                                icon: 'none',  
                                duration: 2000  
                            });  
                        },  
                        complete: ()=>{  
                            this.downText ='下载视频'  
                        }  
                    });  

                    downloadTask.onProgressUpdate((res) => { // 下载进度  
                        this.downText = `已下载${res.progress}%`  
                        if(res.progress == 100){  
                            this.downText = '下载视频'  

                        }  
                    });
收起阅读 »

微信支付商户平台app支付开通方法详解

微信h5 微信支付 微信app

一、创建移动应用

1、创建移动应用之前,必须得有微信开放平台的认证账号,如无可查阅“网创商盟”历史消息进行申请认证操作。

2、登录微信开放平台创建移动应用,按照页面填写一下信息,包括应用名称、应用简介、应用官网、应用图片(2828和108108的PNG格式各一张)、APP运行流程图、申请说明、应用签名、应用包名等。

资料填写完毕,直接提交审核等待通过即可,如有不明白之处,可以查阅“网创联盟”来公众号获取更多信息。

二、微信商户app支付的开通详解

1、登录微信商户平台,直接扫码登录,如果没有商户号,需要先去申请一个商户号;

2、点击产品中心,找到APP支付并点击进入

按照app支付产品设置页面,分别填写移动应用的App ID(需要在步骤一中审核通过后的应用中获取)、APP页面截图信息等。资料填写完毕,直接提交申请等待审核,等待审核通过后即可

继续阅读 »

一、创建移动应用

1、创建移动应用之前,必须得有微信开放平台的认证账号,如无可查阅“网创商盟”历史消息进行申请认证操作。

2、登录微信开放平台创建移动应用,按照页面填写一下信息,包括应用名称、应用简介、应用官网、应用图片(2828和108108的PNG格式各一张)、APP运行流程图、申请说明、应用签名、应用包名等。

资料填写完毕,直接提交审核等待通过即可,如有不明白之处,可以查阅“网创联盟”来公众号获取更多信息。

二、微信商户app支付的开通详解

1、登录微信商户平台,直接扫码登录,如果没有商户号,需要先去申请一个商户号;

2、点击产品中心,找到APP支付并点击进入

按照app支付产品设置页面,分别填写移动应用的App ID(需要在步骤一中审核通过后的应用中获取)、APP页面截图信息等。资料填写完毕,直接提交申请等待审核,等待审核通过后即可

收起阅读 »

Android uni-app实现音视频通话

webrtc Android uniapp

前言

上一篇讲解了怎么实现Android uni-app封装原生插件,这篇讲解一下,把anyRTC的RTC(音视频通讯)封装uni-app 实现音视频通话。

不了解anyRTC的小伙伴,可以点击下面链接:

开发者官网

1.效果图

先上图,后讲解!

1.1 首页

1.2 游客界面

1.3 主播界面

2.GitHub地址

uni-app demo: 点击下载

3.demo下载:

下载地址:点击下载

扫码下载:

4.代码

4.1 集成插件

const RtcModule = uni.requireNativePlugin('AR-RtcModule');
  • AR-RtcModule:插件名称,首页集成插件

4.2 初始事件回调

//callback 接收  
callbackFn() {  
    RtcModule.setCallBack((res) => {  
        switch (res.engineEvent) {  
            case "onWarning":  
                this.promptFn("warn", res.warningCode);  
                break;  
            case "onError":  
                res.errorCode != 18 ? this.promptFn("error", res.errorCode) : '';  
                break;  
            case "onJoinChannelSuccess": //用户加入成功  
                uni.hideLoading();  
                this.role == 1 ? this.PeerVideoUser.push(res.uid) : "";  
                this.videoShow = true;  
                setTimeout(() => {  
                    // this.videoShowBg = false;  
                    this.promptText = ""  
                    //扬声器  
                    RtcModule.setEnableSpeakerphone({  
                        "enabled": true  
                    }, (res) => {})  
                    setTimeout(() => {  
                        // 启用视频模块。  
                        this.role == 1 ? this.setupLocalVideoFn() : RtcModule.enableVideo((res) => {});  
                    }, 200)  
                }, 2000)  
                break;  
            case "onLeaveChannel": //离开频道回调  
                setTimeout(() => {  
                    this.closeAll()  
                }, 500)  
                break;  
            case "onUserJoined": //远端用户加入当前频道回调。  
                // this.promptFn("info", "远端用户加入当前频道回调");  
                this.PeerVideoUser.push(res.uid);  
                break;  
            case "onUserOffline": //远端用户离开当前频道回调。  
                this.PeerVideoUser = this.PeerVideoUser.filter((x) => x !== res.uid);  
                break;  

            case "onFirstLocalAudioFrame": //已发送本地音频首帧的回调。(页面上添加音频)  
                break;  
            case "onFirstLocalVideoFrame": //已显示本地视频首帧的回调。(页面添加本地视频)  
                // this.promptFn("error", "已显示本地视频首帧的回调");  
                break;  
            case "onFirstRemoteVideoDecoded": //已完成远端视频首帧解码回调。(页面添加远端视频)  
                // this.promptFn("info", "已完成远端视频首帧解码回调");  
                this.promptText = "请稍等。。。"  
                let uid = []  
                uid.push(res.uid)  
                setTimeout(() => {  
                    this.promptText = "";  
                    // this.videoShowBg = false; //设置背景开关  
                    setTimeout(() => {  
                        uid.map(item => {  
                            this.$refs[`popup${item}`][0].setupRemoteVideo({  
                                "renderMode": 1,  
                                "channelId": this.chanel,  
                                "uid": item,  
                                "mirrorMode": 0  
                            }, (res) => {})  
                            //预览  
                            RtcModule.startPreview((res) => {});  
                        })  
                    }, 500)  

                }, 2000)  
                break;  
        }  

    })  
},  
  • res.engineEvent:接收各种回调,加入频道成功,离开频道,错误码等。

4.3 创建实例

await RtcModule.create({  
    "appId": this.appid  //anyRTC 为 App 开发者签发的 App ID。每个项目都应该有一个独一无二的 App ID。如果你的开发包里没有 App ID,请从anyRTC官网(https://www.anyrtc.io)申请一个新的 App ID  
}, (res) => {});  

4.4 设置角色

setClientRole(num) {  
    this.role = num;  
    //设置直播场景下的用户角色  
    RtcModule.setClientRole({  
        "role": Number(num) //1:为主播,2:游客  
    }, (ret) => {});  
},  

4.5 加入频道

await RtcModule.joinChannel({  
    "token": "",  
    "channelId": this.channel,  
    "uid": this.uid  
}, (res) => {})  
  • token: 注册不开启token验证,可以为空着。
  • channelId: 你需要加入的频道ID。
  • uid: 每个用户分配唯一UID,不能重复。

4.6 离开销毁

RtcModule.leaveChannel((res) => {}); //离开频道  
RtcModule.destroyRtc((res) => {});    //销毁频道  

5.总结

基本重要的接口,在这里就基本上介绍完啦,如果大家还有什么疑问,可以在评论区留言!

作者:anyRTC-东慕雨

点击查看原

继续阅读 »

前言

上一篇讲解了怎么实现Android uni-app封装原生插件,这篇讲解一下,把anyRTC的RTC(音视频通讯)封装uni-app 实现音视频通话。

不了解anyRTC的小伙伴,可以点击下面链接:

开发者官网

1.效果图

先上图,后讲解!

1.1 首页

1.2 游客界面

1.3 主播界面

2.GitHub地址

uni-app demo: 点击下载

3.demo下载:

下载地址:点击下载

扫码下载:

4.代码

4.1 集成插件

const RtcModule = uni.requireNativePlugin('AR-RtcModule');
  • AR-RtcModule:插件名称,首页集成插件

4.2 初始事件回调

//callback 接收  
callbackFn() {  
    RtcModule.setCallBack((res) => {  
        switch (res.engineEvent) {  
            case "onWarning":  
                this.promptFn("warn", res.warningCode);  
                break;  
            case "onError":  
                res.errorCode != 18 ? this.promptFn("error", res.errorCode) : '';  
                break;  
            case "onJoinChannelSuccess": //用户加入成功  
                uni.hideLoading();  
                this.role == 1 ? this.PeerVideoUser.push(res.uid) : "";  
                this.videoShow = true;  
                setTimeout(() => {  
                    // this.videoShowBg = false;  
                    this.promptText = ""  
                    //扬声器  
                    RtcModule.setEnableSpeakerphone({  
                        "enabled": true  
                    }, (res) => {})  
                    setTimeout(() => {  
                        // 启用视频模块。  
                        this.role == 1 ? this.setupLocalVideoFn() : RtcModule.enableVideo((res) => {});  
                    }, 200)  
                }, 2000)  
                break;  
            case "onLeaveChannel": //离开频道回调  
                setTimeout(() => {  
                    this.closeAll()  
                }, 500)  
                break;  
            case "onUserJoined": //远端用户加入当前频道回调。  
                // this.promptFn("info", "远端用户加入当前频道回调");  
                this.PeerVideoUser.push(res.uid);  
                break;  
            case "onUserOffline": //远端用户离开当前频道回调。  
                this.PeerVideoUser = this.PeerVideoUser.filter((x) => x !== res.uid);  
                break;  

            case "onFirstLocalAudioFrame": //已发送本地音频首帧的回调。(页面上添加音频)  
                break;  
            case "onFirstLocalVideoFrame": //已显示本地视频首帧的回调。(页面添加本地视频)  
                // this.promptFn("error", "已显示本地视频首帧的回调");  
                break;  
            case "onFirstRemoteVideoDecoded": //已完成远端视频首帧解码回调。(页面添加远端视频)  
                // this.promptFn("info", "已完成远端视频首帧解码回调");  
                this.promptText = "请稍等。。。"  
                let uid = []  
                uid.push(res.uid)  
                setTimeout(() => {  
                    this.promptText = "";  
                    // this.videoShowBg = false; //设置背景开关  
                    setTimeout(() => {  
                        uid.map(item => {  
                            this.$refs[`popup${item}`][0].setupRemoteVideo({  
                                "renderMode": 1,  
                                "channelId": this.chanel,  
                                "uid": item,  
                                "mirrorMode": 0  
                            }, (res) => {})  
                            //预览  
                            RtcModule.startPreview((res) => {});  
                        })  
                    }, 500)  

                }, 2000)  
                break;  
        }  

    })  
},  
  • res.engineEvent:接收各种回调,加入频道成功,离开频道,错误码等。

4.3 创建实例

await RtcModule.create({  
    "appId": this.appid  //anyRTC 为 App 开发者签发的 App ID。每个项目都应该有一个独一无二的 App ID。如果你的开发包里没有 App ID,请从anyRTC官网(https://www.anyrtc.io)申请一个新的 App ID  
}, (res) => {});  

4.4 设置角色

setClientRole(num) {  
    this.role = num;  
    //设置直播场景下的用户角色  
    RtcModule.setClientRole({  
        "role": Number(num) //1:为主播,2:游客  
    }, (ret) => {});  
},  

4.5 加入频道

await RtcModule.joinChannel({  
    "token": "",  
    "channelId": this.channel,  
    "uid": this.uid  
}, (res) => {})  
  • token: 注册不开启token验证,可以为空着。
  • channelId: 你需要加入的频道ID。
  • uid: 每个用户分配唯一UID,不能重复。

4.6 离开销毁

RtcModule.leaveChannel((res) => {}); //离开频道  
RtcModule.destroyRtc((res) => {});    //销毁频道  

5.总结

基本重要的接口,在这里就基本上介绍完啦,如果大家还有什么疑问,可以在评论区留言!

作者:anyRTC-东慕雨

点击查看原

收起阅读 »

支付宝APP支付开通教程

支付宝 支付宝小程序

一、如何开通支付宝app支付
正常来说,按照官方的指引要求填写相关资料,即可开通支付宝app支付。但是,更多的时候我们的申请都会碰到一些阻力,常见的阻力就是“系统综合评估签约条件不满足,谢谢您的支持”或者“经系统检测您的账户不符合国家相关法律法规或《支付宝用户服务协议》约定,暂时无法签约当前产品”!

二、如何过风险,签约支付宝App支付呢?为此我们找到了以下方法来进行解决!
①支付宝账户是否通过实名认证。
②申请主体是否是企业或个体工商户,因为纯个人不能申请。
③提供的营业执照,与支付宝账户名称是否属于同一主体。
④账户初次申请成功便申请支付,系统认定账号不安全,需修改支付宝密码(很大部分是此原因)。
⑤企业是否曾受过行政类处罚;账号是否绑定独立手机、邮箱是否绑定过其他支付宝。
⑥法人是否曾有失信记录。
⑦方法是有了,但是有些账户完全按照上面的解决方案操作了之后,仍旧提示“系统综合评估签约条件不满足,谢谢您的支持”或者“经系统检测您的账户不符合国家相关法律法规或《支付宝用户服务协议》约定,暂时无法签约当前产品”!那么,你就需要进入公_众_号“网创商盟”获取更多信息,才能过签约开通支付宝APP支付产品权限。
三、开通案例展示

继续阅读 »

一、如何开通支付宝app支付
正常来说,按照官方的指引要求填写相关资料,即可开通支付宝app支付。但是,更多的时候我们的申请都会碰到一些阻力,常见的阻力就是“系统综合评估签约条件不满足,谢谢您的支持”或者“经系统检测您的账户不符合国家相关法律法规或《支付宝用户服务协议》约定,暂时无法签约当前产品”!

二、如何过风险,签约支付宝App支付呢?为此我们找到了以下方法来进行解决!
①支付宝账户是否通过实名认证。
②申请主体是否是企业或个体工商户,因为纯个人不能申请。
③提供的营业执照,与支付宝账户名称是否属于同一主体。
④账户初次申请成功便申请支付,系统认定账号不安全,需修改支付宝密码(很大部分是此原因)。
⑤企业是否曾受过行政类处罚;账号是否绑定独立手机、邮箱是否绑定过其他支付宝。
⑥法人是否曾有失信记录。
⑦方法是有了,但是有些账户完全按照上面的解决方案操作了之后,仍旧提示“系统综合评估签约条件不满足,谢谢您的支持”或者“经系统检测您的账户不符合国家相关法律法规或《支付宝用户服务协议》约定,暂时无法签约当前产品”!那么,你就需要进入公_众_号“网创商盟”获取更多信息,才能过签约开通支付宝APP支付产品权限。
三、开通案例展示

收起阅读 »

nvue实现全局挂载

vuex 全局变量

前言
nvue的无法手动扩展vue.prototype导致有时想用全局挂载就无从下手。

实现思路
由于nvue中的全局变量我们能找到的比较好的就是store和globalData,所以考虑在这两个上挂载。

globaldata
每次初始化时直接getApp({allowdefault:true})然后扩展一堆方法,使用时,页面内直接get出来用就好,我这里是作为全局请求api方法,实现类似vue项目中的 this.$api.getlist().then().catch()类似的效果,使用时就是getApp().api.login.getXX().then().catch();

store
同样的,直接在state上挂载静态方法在nvue中是完全没有问题的,this.$store.state.test.gettttt().then().catch(); 依然好用。

反思
目前使用这两种方法都可以实现,但是仔细想想稍有不妥。
store作为状态管理我们管理了静态方法,是不是用偏了;globaldata每次使用必须getApp获取整个app实例,getapp()...的链式写法未免有些奇怪;再globaldata是否有大小限制,或者我们挂载的东西太多会不会影响到app实例;store和globaldata我使用哪个比较合适呢?

请问有谁实现过或者在这方面有经验,帮我解答最后这几个问题!!!

merry christmas 收到下边兄弟的回复,才发现uni本身就是一个全局的对象,使用uni.XXX = function(){};然后页面中随处使用,确实好用。

那么问题又来了,我现在想需要一个可配置的接口地址,使用什么方案比较合适呢?个人还是觉得store比较好直接使用action请求配置服务器,更换每一个接口的地址就可以了。

继续阅读 »

前言
nvue的无法手动扩展vue.prototype导致有时想用全局挂载就无从下手。

实现思路
由于nvue中的全局变量我们能找到的比较好的就是store和globalData,所以考虑在这两个上挂载。

globaldata
每次初始化时直接getApp({allowdefault:true})然后扩展一堆方法,使用时,页面内直接get出来用就好,我这里是作为全局请求api方法,实现类似vue项目中的 this.$api.getlist().then().catch()类似的效果,使用时就是getApp().api.login.getXX().then().catch();

store
同样的,直接在state上挂载静态方法在nvue中是完全没有问题的,this.$store.state.test.gettttt().then().catch(); 依然好用。

反思
目前使用这两种方法都可以实现,但是仔细想想稍有不妥。
store作为状态管理我们管理了静态方法,是不是用偏了;globaldata每次使用必须getApp获取整个app实例,getapp()...的链式写法未免有些奇怪;再globaldata是否有大小限制,或者我们挂载的东西太多会不会影响到app实例;store和globaldata我使用哪个比较合适呢?

请问有谁实现过或者在这方面有经验,帮我解答最后这几个问题!!!

merry christmas 收到下边兄弟的回复,才发现uni本身就是一个全局的对象,使用uni.XXX = function(){};然后页面中随处使用,确实好用。

那么问题又来了,我现在想需要一个可配置的接口地址,使用什么方案比较合适呢?个人还是觉得store比较好直接使用action请求配置服务器,更换每一个接口的地址就可以了。

收起阅读 »

uniapp 调用echarts 占用内存过大不释放问题终于解决了 移动端支持echarts 5.0

uniapp 调用echarts 这个问题整了四天终于过了
总结下经验:
最开始做图表本来想用以前flutter上那款,结果没发现vue版本,最后退而求其次选echarts,什么uchart这些根本就没入法眼,界面没得echarts好看二个功能上没得这个强,那就开干

  1. 最开始信了官方的鬼话用renderjs,说性能有多强大,调是调了,也显出来了,最后发现一个重大问题,renderjs操作dom元素会不释放内存,就算调了disponse方法也没用,只把实例给剁了,加载到页面上的那个js文件还在内存中没得到释放,这个东东起码搞了我两天,最后放弃renderjs

  2. 下来又找,最后发现mpvue-echarts 这个东东试了还可以,内存也能及时回收,速度也够快, 不过这个东东停止维护了,示例上边的echarts.js文件有点老还是个simple的阉割版,样式没有5.0好看,官方下了个5.0上来,一来就报一堆错,以为不兼容新版,又找结果还真有改进版的,拿上去还是不对,版本从3.7一直下到5.0全试了一个遍,还是没对,晚上下搞到早上8点过才搞通,最后才发现原来echarts官方那个在线定制功能惹的祸,那个编译出来的包拿这上边根本过不了.最后下了个5.0整个项目包,dist目录下的文件拿过来一试就OK.

苹果7真机上边app测试完美通过,
H5上边报错 需要把echarts的js文件中 两处操作dom元素的
addEventListener语句删除
因为这个不是直接操作dom元素而是cavnas画板渲染,不需要这两处监听

两处分别为:
&& !!window.addEventListener
el.addEventListener(name, handler, opt); 压缩版 t.addEventListener(n,e,i)改为null

基本操作就是:
https://github.com/dcloudio/hello-uniapp/blob/master/components/mpvue-echarts/src/echarts.vue 上边拿 mpvue-echarts 目录下src下边两个文件
echarts.vue 要做点小修改:
删除error事件
删除mounted 和 onReady 的H5条件编译 不然手机显示白屏

上代码:

<template>  
    <view class="content">  
        <mpvue-echarts class="ec-canvas"   
    @onInit="lineInit" canvasId="line" ref="lineChart" />  
    </view>  
</template>  
<script>  
import * as echarts from '../../components/mpvue-echarts/echarts.min.js';   //官方下载的5.0库  
import mpvueEcharts from '../../components/mpvue-echarts/echarts.vue';  
//-------------------------------------------------------------  
 //官方演示option,这个地方方便从官方上拷示例把 let隔了一行  
let   

option = {  
    title: {  
        text: '某地区蒸发量和降水量',  
        subtext: '纯属虚构'  
    },  
    tooltip: {  
        trigger: 'axis'  
    },  
    legend: {  
        data: ['蒸发量', '降水量']  
    },  
    toolbox: {  
        show: true,  
        feature: {  
            dataView: {show: true, readOnly: false},  
            magicType: {show: true, type: ['line', 'bar']},  
            restore: {show: true},  
            saveAsImage: {show: true}  
        }  
    },  
    calculable: true,  
    xAxis: [  
        {  
            type: 'category',  
            data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']  
        }  
    ],  
    yAxis: [  
        {  
            type: 'value'  
        }  
    ],  
    series: [  
        {  
            name: '蒸发量',  
            type: 'bar',  
            data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],  
            markPoint: {  
                data: [  
                    {type: 'max', name: '最大值'},  
                    {type: 'min', name: '最小值'}  
                ]  
            },  
            markLine: {  
                data: [  
                    {type: 'average', name: '平均值'}  
                ]  
            }  
        },  
        {  
            name: '降水量',  
            type: 'bar',  
            data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],  
            markPoint: {  
                data: [  
                    {name: '年最高', value: 182.2, xAxis: 7, yAxis: 183},  
                    {name: '年最低', value: 2.3, xAxis: 11, yAxis: 3}  
                ]  
            },  
            markLine: {  
                data: [  
                    {type: 'average', name: '平均值'}  
                ]  
            }  
        }  
    ]  
};  

//------------------------------------------  

export default {  
    //导入mpvue的mpvueEcharts组件。  
    components: {  
        mpvueEcharts  
    },  
    data() {  
        return {};  
    },  
    onLoad() {},  
    methods: {  
        lineInit(e) {  
            let { width, height } = e;  
            let canvas = this.$refs.lineChart.canvas;  
            echarts.setCanvasCreator(() => canvas);  
                        //这步很关键能拿到对象就万事大吉  
            let lineChart = echarts.init(canvas, null, {  
                width: width,  
                height: height  
            });  
            canvas.setChart(lineChart);  
            lineChart.setOption(option);  
            this.$refs.lineChart.setChart(lineChart);  
        }  
    }  
};  
</script>  

<style>  
//容器必须设高度宽度否则无法显示  
.content {  
    height: 1200rpx;  
    width: 100%;  
}  
//画板宽高  
.ec-canvas{  
    height: 1200rpx;  
    width: 100%;  
}  
</style>
继续阅读 »

uniapp 调用echarts 这个问题整了四天终于过了
总结下经验:
最开始做图表本来想用以前flutter上那款,结果没发现vue版本,最后退而求其次选echarts,什么uchart这些根本就没入法眼,界面没得echarts好看二个功能上没得这个强,那就开干

  1. 最开始信了官方的鬼话用renderjs,说性能有多强大,调是调了,也显出来了,最后发现一个重大问题,renderjs操作dom元素会不释放内存,就算调了disponse方法也没用,只把实例给剁了,加载到页面上的那个js文件还在内存中没得到释放,这个东东起码搞了我两天,最后放弃renderjs

  2. 下来又找,最后发现mpvue-echarts 这个东东试了还可以,内存也能及时回收,速度也够快, 不过这个东东停止维护了,示例上边的echarts.js文件有点老还是个simple的阉割版,样式没有5.0好看,官方下了个5.0上来,一来就报一堆错,以为不兼容新版,又找结果还真有改进版的,拿上去还是不对,版本从3.7一直下到5.0全试了一个遍,还是没对,晚上下搞到早上8点过才搞通,最后才发现原来echarts官方那个在线定制功能惹的祸,那个编译出来的包拿这上边根本过不了.最后下了个5.0整个项目包,dist目录下的文件拿过来一试就OK.

苹果7真机上边app测试完美通过,
H5上边报错 需要把echarts的js文件中 两处操作dom元素的
addEventListener语句删除
因为这个不是直接操作dom元素而是cavnas画板渲染,不需要这两处监听

两处分别为:
&& !!window.addEventListener
el.addEventListener(name, handler, opt); 压缩版 t.addEventListener(n,e,i)改为null

基本操作就是:
https://github.com/dcloudio/hello-uniapp/blob/master/components/mpvue-echarts/src/echarts.vue 上边拿 mpvue-echarts 目录下src下边两个文件
echarts.vue 要做点小修改:
删除error事件
删除mounted 和 onReady 的H5条件编译 不然手机显示白屏

上代码:

<template>  
    <view class="content">  
        <mpvue-echarts class="ec-canvas"   
    @onInit="lineInit" canvasId="line" ref="lineChart" />  
    </view>  
</template>  
<script>  
import * as echarts from '../../components/mpvue-echarts/echarts.min.js';   //官方下载的5.0库  
import mpvueEcharts from '../../components/mpvue-echarts/echarts.vue';  
//-------------------------------------------------------------  
 //官方演示option,这个地方方便从官方上拷示例把 let隔了一行  
let   

option = {  
    title: {  
        text: '某地区蒸发量和降水量',  
        subtext: '纯属虚构'  
    },  
    tooltip: {  
        trigger: 'axis'  
    },  
    legend: {  
        data: ['蒸发量', '降水量']  
    },  
    toolbox: {  
        show: true,  
        feature: {  
            dataView: {show: true, readOnly: false},  
            magicType: {show: true, type: ['line', 'bar']},  
            restore: {show: true},  
            saveAsImage: {show: true}  
        }  
    },  
    calculable: true,  
    xAxis: [  
        {  
            type: 'category',  
            data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']  
        }  
    ],  
    yAxis: [  
        {  
            type: 'value'  
        }  
    ],  
    series: [  
        {  
            name: '蒸发量',  
            type: 'bar',  
            data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],  
            markPoint: {  
                data: [  
                    {type: 'max', name: '最大值'},  
                    {type: 'min', name: '最小值'}  
                ]  
            },  
            markLine: {  
                data: [  
                    {type: 'average', name: '平均值'}  
                ]  
            }  
        },  
        {  
            name: '降水量',  
            type: 'bar',  
            data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],  
            markPoint: {  
                data: [  
                    {name: '年最高', value: 182.2, xAxis: 7, yAxis: 183},  
                    {name: '年最低', value: 2.3, xAxis: 11, yAxis: 3}  
                ]  
            },  
            markLine: {  
                data: [  
                    {type: 'average', name: '平均值'}  
                ]  
            }  
        }  
    ]  
};  

//------------------------------------------  

export default {  
    //导入mpvue的mpvueEcharts组件。  
    components: {  
        mpvueEcharts  
    },  
    data() {  
        return {};  
    },  
    onLoad() {},  
    methods: {  
        lineInit(e) {  
            let { width, height } = e;  
            let canvas = this.$refs.lineChart.canvas;  
            echarts.setCanvasCreator(() => canvas);  
                        //这步很关键能拿到对象就万事大吉  
            let lineChart = echarts.init(canvas, null, {  
                width: width,  
                height: height  
            });  
            canvas.setChart(lineChart);  
            lineChart.setOption(option);  
            this.$refs.lineChart.setChart(lineChart);  
        }  
    }  
};  
</script>  

<style>  
//容器必须设高度宽度否则无法显示  
.content {  
    height: 1200rpx;  
    width: 100%;  
}  
//画板宽高  
.ec-canvas{  
    height: 1200rpx;  
    width: 100%;  
}  
</style>
收起阅读 »

小团队承接H5、小程序、APP等外包。

外包 微信小程序 h5 移动APP

经验丰富,做过多种类型项目,有案例可看;
开发流程、目录搭建、代码都很规范(二次开发也很容易上手);
整个项目外包可以找我(小团队接单,面向客户、产品);
只需要前端部分也可以找我(个人接单,面向服务端合作伙伴);
wechat、tel(13995636759);

继续阅读 »

经验丰富,做过多种类型项目,有案例可看;
开发流程、目录搭建、代码都很规范(二次开发也很容易上手);
整个项目外包可以找我(小团队接单,面向客户、产品);
只需要前端部分也可以找我(个人接单,面向服务端合作伙伴);
wechat、tel(13995636759);

收起阅读 »

关于UNIAPP缓存存储获取失效问题

缓存

uni.setStorageSync官方标注不能存储对象类型
但是IOS可以存储对象类型,亲测有效
就是因为测试有效导致好多问题,MMP。。。。。。
安卓存储对象类型无效确如官方所说!
所以有小伙伴遇到IOS可以存储数据,安卓无效的时候可以考虑一下是否存储的是对象类型

继续阅读 »

uni.setStorageSync官方标注不能存储对象类型
但是IOS可以存储对象类型,亲测有效
就是因为测试有效导致好多问题,MMP。。。。。。
安卓存储对象类型无效确如官方所说!
所以有小伙伴遇到IOS可以存储数据,安卓无效的时候可以考虑一下是否存储的是对象类型

收起阅读 »

KeyChain(钥匙串),保存的信息不会因App被删除而丢失(ios)

KeyChain(钥匙串),保存的信息不会因App被删除而丢失(ios):https://ext.dcloud.net.cn/plugin?id=3708

KeyChain(钥匙串),保存的信息不会因App被删除而丢失(ios):https://ext.dcloud.net.cn/plugin?id=3708

个人承接vue、uniapp项目,有案例,联系vx:web9688,不接受外地工作,可付费提供技术支持。添加vx时务必备注来意以及添加渠道,渠道可以写:`uniapp`

vue.js uniapp插件 uni_app uniapp

个人承接vue、uniapp项目,有案例,联系vx:web9688,不接受外地工作,可付费提供技术支持。添加vx时务必备注来意以及添加渠道,渠道可以写:uniapp

个人承接vue、uniapp项目,有案例,联系vx:web9688,不接受外地工作,可付费提供技术支持。添加vx时务必备注来意以及添加渠道,渠道可以写:uniapp

adb.exe1.0.31实测可用(测试机:meizu x8)解决真机运行检测不到手机的问题

adb下载:https://wwe.lanzous.com/ilOAPjld4da 密码:co6d

使用:
手机对adb的版本有特定要求(遇到一些魅族手机有此问题),此时需要更换HBuilder的adb版本。

替换版本前,将默认版本的adb.exe备份下。
然后把1.0.31版的adb.exe拷贝出来替换主目录下的exe。

HBuilder的adb目录位置:tools/adbs目录(MAC下为HBuilder.app/Contents/tools/adbs目录)

HBuilderX的adb目录位置:plugins/launcher/tools/adbs目录(MAC下为/Applications/HBuilderX-Alpha.app/Contents/HBuilderX/plugins/launcher/tools/adbs目录)

HBuilder安装目录下带了多个版本的adb。
(补充:HBuiderX版本一般只有一个版本的adb)
以上参考了深井冰_01发布于2014-11-07 22:35 的《HBuilderX真机运行、手机运行、真机联调常见问题》
链接:https://ask.dcloud.net.cn/article/97

继续阅读 »

adb下载:https://wwe.lanzous.com/ilOAPjld4da 密码:co6d

使用:
手机对adb的版本有特定要求(遇到一些魅族手机有此问题),此时需要更换HBuilder的adb版本。

替换版本前,将默认版本的adb.exe备份下。
然后把1.0.31版的adb.exe拷贝出来替换主目录下的exe。

HBuilder的adb目录位置:tools/adbs目录(MAC下为HBuilder.app/Contents/tools/adbs目录)

HBuilderX的adb目录位置:plugins/launcher/tools/adbs目录(MAC下为/Applications/HBuilderX-Alpha.app/Contents/HBuilderX/plugins/launcher/tools/adbs目录)

HBuilder安装目录下带了多个版本的adb。
(补充:HBuiderX版本一般只有一个版本的adb)
以上参考了深井冰_01发布于2014-11-07 22:35 的《HBuilderX真机运行、手机运行、真机联调常见问题》
链接:https://ask.dcloud.net.cn/article/97

收起阅读 »

长期提供uniapp 插件/组件/页面定制开发

iOS Android nvue uniapp插件

长期提供uniapp 插件/组件/页面定制,vue/nvue均可。请看更多插件

欢迎各位老板进群叨扰 1091229222,加群请备注: uniapp社区

长期提供uniapp 插件/组件/页面定制,vue/nvue均可。请看更多插件

欢迎各位老板进群叨扰 1091229222,加群请备注: uniapp社区