文件io操作中的moveTo和copyTo的坑
moveTo和copyTo的第二个参数,文档中说明的是可选,我自己实际操作,如果不给这个参数,永远都不成功,这两个参数给了就成功了。分享一下
moveTo和copyTo的第二个参数,文档中说明的是可选,我自己实际操作,如果不给这个参数,永远都不成功,这两个参数给了就成功了。分享一下
uniCloud.deleteFile相关
试了一下uniCloud.deleteFile删除的方法,发现第一种未删除成功,第二种就删除成功了。有人知道啥原因嘛
试了一下uniCloud.deleteFile删除的方法,发现第一种未删除成功,第二种就删除成功了。有人知道啥原因嘛
HBuilderX必装的插件
排名不分先后
HBuilderX主题插件
HBuilderX自定义主题辅助工具, 可以轻松定制漂亮主题。同时内置多套主题,并支持从浏览器安装主题。下载地址
eslint-js 语法校验插件
用于校验js和html中的js代码,且支持eslint 实时校验、自动修复错误。下载地址
Git源代码管理工具: easy-git
vscode源代码管理工具风格。
HBuilderX内唯一的图形化Git工具, 支持克隆、提交/更新/拉取、分支/tag管理、日志、文件对比、储藏等操作。
并且支持通过命令面板操作git相关操作。
彩虹屁老婆
虚拟程序员鼓励师老婆陪你敲代码哟。在你编程时给你爱的鼓励!下载地址
便捷翻译插件
全语种翻译(含拼音)插件 下载地址
es6代码块
常用的es6代码块 下载地址
Formator-Prettier 格式化插件
用于格式化less、sass、vue、stylus、ts、yaml代码。下载地址
compile-node-sass
compile-node-sass: scss/sass编译插件, 可以编译sass为css。下载地址
compile-less
compile-less: less插件用于less文件编译,编译less为css。下载地址
排名不分先后
HBuilderX主题插件
HBuilderX自定义主题辅助工具, 可以轻松定制漂亮主题。同时内置多套主题,并支持从浏览器安装主题。下载地址
eslint-js 语法校验插件
用于校验js和html中的js代码,且支持eslint 实时校验、自动修复错误。下载地址
Git源代码管理工具: easy-git
vscode源代码管理工具风格。
HBuilderX内唯一的图形化Git工具, 支持克隆、提交/更新/拉取、分支/tag管理、日志、文件对比、储藏等操作。
并且支持通过命令面板操作git相关操作。
彩虹屁老婆
虚拟程序员鼓励师老婆陪你敲代码哟。在你编程时给你爱的鼓励!下载地址
便捷翻译插件
全语种翻译(含拼音)插件 下载地址
es6代码块
常用的es6代码块 下载地址
Formator-Prettier 格式化插件
用于格式化less、sass、vue、stylus、ts、yaml代码。下载地址
compile-node-sass
compile-node-sass: scss/sass编译插件, 可以编译sass为css。下载地址
compile-less
compile-less: less插件用于less文件编译,编译less为css。下载地址
收起阅读 »
mac 开发h5 web浏览器 报错
There is no Internet connection
There is something wrong with the proxy server, or the address is incorrect.
Try:
Contacting the system admin
Checking the proxy address
ERR_PROXY_CONNECTION_FAILED
If you use a proxy server…
Check your proxy settings or contact your network administrator to make sure the proxy server is working. If you don't believe you should be using a proxy server: Go to Applications > System Preferences > Network > Advanced > Proxies and deselect any proxies that have been selected.
那位大咖,麻烦给我参考一下 mac代理设置
There is no Internet connection
There is something wrong with the proxy server, or the address is incorrect.
Try:
Contacting the system admin
Checking the proxy address
ERR_PROXY_CONNECTION_FAILED
If you use a proxy server…
Check your proxy settings or contact your network administrator to make sure the proxy server is working. If you don't believe you should be using a proxy server: Go to Applications > System Preferences > Network > Advanced > Proxies and deselect any proxies that have been selected.
那位大咖,麻烦给我参考一下 mac代理设置
收起阅读 »刚从apicloud转过来,分享一下看法吧
非职业码农,算是爱好
apicloud有一个优点就是更简单,文档更易阅读。
过来这边因为我没有用小程序的需求,而且对自由性要求比较高,所以没用uni-app
目前看到的就是这边api更多,但是文档写得不好(一般吧)。
很多东西不需要重新打包。例如:改为沉浸式状态栏或非沉浸式。直接更新后重启一下就行了。apicloud那边app还得重新编译一下
APP启动速度超级快,我这边的程序0.6s就可以启动完毕,那边要3s
不过apicloud的扩展性也还行,绝大多数功能都有模块供你使用
转过来的原因是因为那边吃相太难看。APP安装量大于5w,月活大于1w就需要开通商业服务。5999元以上。以后人越多还越贵。最多是2w多(大概)
当然收费并非不行,主要是页面上根本没有告诉你后续需要开通商业服务。你得经常浏览他们的论坛才能知道。真恶心人
非职业码农,算是爱好
apicloud有一个优点就是更简单,文档更易阅读。
过来这边因为我没有用小程序的需求,而且对自由性要求比较高,所以没用uni-app
目前看到的就是这边api更多,但是文档写得不好(一般吧)。
很多东西不需要重新打包。例如:改为沉浸式状态栏或非沉浸式。直接更新后重启一下就行了。apicloud那边app还得重新编译一下
APP启动速度超级快,我这边的程序0.6s就可以启动完毕,那边要3s
不过apicloud的扩展性也还行,绝大多数功能都有模块供你使用
转过来的原因是因为那边吃相太难看。APP安装量大于5w,月活大于1w就需要开通商业服务。5999元以上。以后人越多还越贵。最多是2w多(大概)
当然收费并非不行,主要是页面上根本没有告诉你后续需要开通商业服务。你得经常浏览他们的论坛才能知道。真恶心人
UniApp 中发现一个小BUG
tabbar上边做四个页面 每个页面显示标题栏 标题栏上边有个图标 图标事件弹出Drawer抽屉
如果页面里边什么都不放只放一个Drawer抽屉 先切第二个页面 弹出Drawer抽屉 再切第三个页面 弹出Drawer抽屉 然后切回第一个页面 第一个页面的tabbar不会响应onTabItemTap事件,也弹不出第一个页面的Drawer抽屉
页面里有内容就不会有这个现象
tabbar上边做四个页面 每个页面显示标题栏 标题栏上边有个图标 图标事件弹出Drawer抽屉
如果页面里边什么都不放只放一个Drawer抽屉 先切第二个页面 弹出Drawer抽屉 再切第三个页面 弹出Drawer抽屉 然后切回第一个页面 第一个页面的tabbar不会响应onTabItemTap事件,也弹不出第一个页面的Drawer抽屉
页面里有内容就不会有这个现象
Vue.js自定义PC版模态框组件|vue layer弹层
介绍
vlayer 一款基于vue.js构建的桌面端弹框组件。集合了 alert|dialog|modal|msg|notify|popover|toast|actionsheet 等多种功能于一身。
快速上手
在main.js中全局引入vlayer组件。
import VLayer from './components/vlayer';
Vue.use(VLayer);
标签式写法
<v-layer
v-model="isConfirm"
title="标题内容"
content="<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>"
xclose
z-index="2002"
lockScroll="false"
resize
dragOut
:btns="[
{text: '取消', click: () => isConfirm=false},
{text: '确定', style: 'color:#f90;', click: handleFn},
]"
/>
函数式写法
let $el = this.$vlayer({
title: '标题内容',
content: '<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>',
xclose: true,
zIndex: 2002,
lockScroll: false,
resize: true,
dragOut: true,
btns: [
{text: '取消', click: () => { $el.close(); }},
{text: '确定', click: () => this.handleFn()},
]
});
效果预览
配置参数
vlayer默认支持30+种参数任意搭配。
@@默认参数
v-model 当前组件是否显示
title 标题
content 内容(支持自定义插槽内容)
type 弹窗类型(toast | footer | actionsheet | android/ios | contextmenu | drawer | iframe | message/notify/popover)
layerStyle 自定义弹窗样式
icon toast图标(loading | success | fail)
shade 是否显示遮罩层
shadeClose 是否点击遮罩时关闭弹窗
lockScroll 是否弹窗出现时将 body 滚动锁定
opacity 遮罩层透明度
xclose 是否显示关闭图标
xposition 关闭图标位置(left | right | top | bottom)
xcolor 关闭图标颜色
anim 弹窗动画(scaleIn | fadeIn | footer | fadeInUp | fadeInDown | fadeInLeft | fadeInRight)
position 弹出位置(auto | ['100px','50px'] | t | r | b | l | lt | rt | lb | rb)
drawer 抽屉弹窗(top | right | bottom | left)
follow 跟随元素定位弹窗(支持元素.kk #kk 或 [e.clientX, e.clientY])
time 弹窗自动关闭秒数(1、2、3)
zIndex 弹窗层叠(默认8080)
topmost 置顶当前窗口(默认false)
area 弹窗宽高(默认auto)设置宽度area: '300px' 设置高度area:['', '200px'] 设置宽高area:['350px', '150px']
maxWidth 弹窗最大宽度(只有当area:'auto'时,maxWidth的设定才有效)
maximize 是否显示最大化按钮(默认false)
fullscreen 全屏弹窗(默认false)
fixed 弹窗是否固定
drag 拖拽元素(可定义选择器drag:'.xxx' | 禁止拖拽drag:false)
dragOut 是否允许拖拽到窗口外(默认false)
resize 是否允许拉伸尺寸(默认false)
btns 弹窗按钮(参数:text|style|disabled|click)
------------------------------------------
@@组件式事件
open 打开弹出层时触发(@open="xxx")
close 关闭弹出层时触发(@close="xxx")
------------------------------------------
@@函数式事件
onOpen 打开弹窗回调
onClose 关闭弹窗回调
vlayer.vue模板
<template>
<div v-show="opened" class="vui__layer" :class="{'vui__layer-closed': closeCls}" :id="vlayerId">
<div v-if="JSON.parse(shade)" class="vlayer__overlay" @click="shadeClicked" :style="{opacity}"></div>
<div class="vlayer__wrap" :class="[''+anim, type&&'popui__'+type, drawer&&'popui'+drawer, xclose&&'vlayer-closable', tipArrow]" :style="layerStyle">
<div v-if="title" class="vlayer__wrap-tit" v-html="title"></div>
<div v-if="type=='toast'&&icon" class="vlayer__toast-icon" :class="['vlayer'+icon]" v-html="toastIcon[icon]"></div>
<div class="vlayer__wrap-cntbox">
<template v-if="$slots.content">
<div class="vlayer__wrap-cnt"><slot name="content" /></div>
</template>
<template v-else>
<template v-if="content">
<iframe v-if="type=='iframe'" scrolling="auto" allowtransparency="true" frameborder="0" :src="content"></iframe>
<!-- message|notify|popover -->
<div v-else-if="type=='message' || type=='notify' || type=='popover'" class="vlayer__wrap-cnt">
<i v-if="icon" class="vlayer-msg__icon" :class="icon" v-html="messageIcon[icon]"></i>
<div class="vlayer-msg__group"><div v-if="title" class="vlayer-msg__title" v-html="title"></div><div class="vlayer-msg__content" v-html="content"></div></div>
</div><div v-else class="vlayer__wrap-cnt" v-html="content"></div>
</template>
</template>
<slot />
</div>
<div v-if="btns" class="vlayer__wrap-btns">
<span v-for="(btn,index) in btns" :key="index" class="btn" :class="{'btn-disabled': btn.disabled}" :style="btn.style" v-html="btn.text"></span>
</div>
<span v-if="xclose" class="vlayer__xclose" :class="!maximize&&xposition" :style="{'color': xcolor}" @click="close"></span>
<span v-if="maximize" class="vlayer__maximize"></span>
<span v-if="resize" class="vlayer__resize"></span>
</div>
<!-- 修复拖拽卡顿 -->
<div class="vlayer__dragfix"></div>
</div>
</template>
默认标题是拖拽区域,当然也可以自定义拖拽元素,只需设置 drag: '#xxx' 或者设置drag: false 来禁止弹窗拖拽功能。
当设置 dragOut: true 窗体可以拖拽到浏览器外部。
当使用popover弹窗,需要传入follow: '#xxxx' 定位元素。
另外还支持自定义弹窗显示位置,只需配置position即可。
<!-- 自定义弹窗位置 -->
<v-layer v-model="showPosition" xclose maximize drag=".dragImg" :position="rb">
<img class="dragImg" src="xxx.jpg" />
</v-layer>
设置fullscreen: true会全屏显示弹窗。
okay,基于vue.js开发pc端弹窗插件就分享到这里。希望对大家有所帮助哈!✍✍
链接:https://juejin.im/post/6890442763041669127/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
介绍
vlayer 一款基于vue.js构建的桌面端弹框组件。集合了 alert|dialog|modal|msg|notify|popover|toast|actionsheet 等多种功能于一身。
快速上手
在main.js中全局引入vlayer组件。
import VLayer from './components/vlayer';
Vue.use(VLayer);
标签式写法
<v-layer
v-model="isConfirm"
title="标题内容"
content="<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>"
xclose
z-index="2002"
lockScroll="false"
resize
dragOut
:btns="[
{text: '取消', click: () => isConfirm=false},
{text: '确定', style: 'color:#f90;', click: handleFn},
]"
/>
函数式写法
let $el = this.$vlayer({
title: '标题内容',
content: '<div style='color:#06f;padding:15px;'>弹窗内容信息!</div>',
xclose: true,
zIndex: 2002,
lockScroll: false,
resize: true,
dragOut: true,
btns: [
{text: '取消', click: () => { $el.close(); }},
{text: '确定', click: () => this.handleFn()},
]
});
效果预览
配置参数
vlayer默认支持30+种参数任意搭配。
@@默认参数
v-model 当前组件是否显示
title 标题
content 内容(支持自定义插槽内容)
type 弹窗类型(toast | footer | actionsheet | android/ios | contextmenu | drawer | iframe | message/notify/popover)
layerStyle 自定义弹窗样式
icon toast图标(loading | success | fail)
shade 是否显示遮罩层
shadeClose 是否点击遮罩时关闭弹窗
lockScroll 是否弹窗出现时将 body 滚动锁定
opacity 遮罩层透明度
xclose 是否显示关闭图标
xposition 关闭图标位置(left | right | top | bottom)
xcolor 关闭图标颜色
anim 弹窗动画(scaleIn | fadeIn | footer | fadeInUp | fadeInDown | fadeInLeft | fadeInRight)
position 弹出位置(auto | ['100px','50px'] | t | r | b | l | lt | rt | lb | rb)
drawer 抽屉弹窗(top | right | bottom | left)
follow 跟随元素定位弹窗(支持元素.kk #kk 或 [e.clientX, e.clientY])
time 弹窗自动关闭秒数(1、2、3)
zIndex 弹窗层叠(默认8080)
topmost 置顶当前窗口(默认false)
area 弹窗宽高(默认auto)设置宽度area: '300px' 设置高度area:['', '200px'] 设置宽高area:['350px', '150px']
maxWidth 弹窗最大宽度(只有当area:'auto'时,maxWidth的设定才有效)
maximize 是否显示最大化按钮(默认false)
fullscreen 全屏弹窗(默认false)
fixed 弹窗是否固定
drag 拖拽元素(可定义选择器drag:'.xxx' | 禁止拖拽drag:false)
dragOut 是否允许拖拽到窗口外(默认false)
resize 是否允许拉伸尺寸(默认false)
btns 弹窗按钮(参数:text|style|disabled|click)
------------------------------------------
@@组件式事件
open 打开弹出层时触发(@open="xxx")
close 关闭弹出层时触发(@close="xxx")
------------------------------------------
@@函数式事件
onOpen 打开弹窗回调
onClose 关闭弹窗回调
vlayer.vue模板
<template>
<div v-show="opened" class="vui__layer" :class="{'vui__layer-closed': closeCls}" :id="vlayerId">
<div v-if="JSON.parse(shade)" class="vlayer__overlay" @click="shadeClicked" :style="{opacity}"></div>
<div class="vlayer__wrap" :class="[''+anim, type&&'popui__'+type, drawer&&'popui'+drawer, xclose&&'vlayer-closable', tipArrow]" :style="layerStyle">
<div v-if="title" class="vlayer__wrap-tit" v-html="title"></div>
<div v-if="type=='toast'&&icon" class="vlayer__toast-icon" :class="['vlayer'+icon]" v-html="toastIcon[icon]"></div>
<div class="vlayer__wrap-cntbox">
<template v-if="$slots.content">
<div class="vlayer__wrap-cnt"><slot name="content" /></div>
</template>
<template v-else>
<template v-if="content">
<iframe v-if="type=='iframe'" scrolling="auto" allowtransparency="true" frameborder="0" :src="content"></iframe>
<!-- message|notify|popover -->
<div v-else-if="type=='message' || type=='notify' || type=='popover'" class="vlayer__wrap-cnt">
<i v-if="icon" class="vlayer-msg__icon" :class="icon" v-html="messageIcon[icon]"></i>
<div class="vlayer-msg__group"><div v-if="title" class="vlayer-msg__title" v-html="title"></div><div class="vlayer-msg__content" v-html="content"></div></div>
</div><div v-else class="vlayer__wrap-cnt" v-html="content"></div>
</template>
</template>
<slot />
</div>
<div v-if="btns" class="vlayer__wrap-btns">
<span v-for="(btn,index) in btns" :key="index" class="btn" :class="{'btn-disabled': btn.disabled}" :style="btn.style" v-html="btn.text"></span>
</div>
<span v-if="xclose" class="vlayer__xclose" :class="!maximize&&xposition" :style="{'color': xcolor}" @click="close"></span>
<span v-if="maximize" class="vlayer__maximize"></span>
<span v-if="resize" class="vlayer__resize"></span>
</div>
<!-- 修复拖拽卡顿 -->
<div class="vlayer__dragfix"></div>
</div>
</template>
默认标题是拖拽区域,当然也可以自定义拖拽元素,只需设置 drag: '#xxx' 或者设置drag: false 来禁止弹窗拖拽功能。
当设置 dragOut: true 窗体可以拖拽到浏览器外部。
当使用popover弹窗,需要传入follow: '#xxxx' 定位元素。
另外还支持自定义弹窗显示位置,只需配置position即可。
<!-- 自定义弹窗位置 -->
<v-layer v-model="showPosition" xclose maximize drag=".dragImg" :position="rb">
<img class="dragImg" src="xxx.jpg" />
</v-layer>
设置fullscreen: true会全屏显示弹窗。
okay,基于vue.js开发pc端弹窗插件就分享到这里。希望对大家有所帮助哈!✍✍
链接:https://juejin.im/post/6890442763041669127/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
从uniapp的webview跳回APP的方法
今天找一个网站:https://www.jianshu.com/p/163b1cdd664d 分享出来以后查看
今天找一个网站:https://www.jianshu.com/p/163b1cdd664d 分享出来以后查看
11.3日升级以后,横屏项目在CHROME中显示正常,但真机调试布局出现问题(升级前完全正常)
为什么一直好好的,前几天升级以后,我的横屏项目在CHROME中显示正常,但真机调试布局出现问题,如附件1和附件2显示。11.3日还是正常的,后面升级过就不正常了。我已经尝试如下:
1、以为是基座的问题,重新编译过基座也是不行。
2、按照https://ask.dcloud.net.cn/article/37911改了 __uniappview.html文件的内容并重新打开编译基座,还是不行
现在导致根本无法真机调试,而且还有其他几个项目也是用UNIAPP开发的横屏项目,改过的都不敢更新了。非常紧急,希望得到支持,非常感谢,非常感谢!!!
为什么一直好好的,前几天升级以后,我的横屏项目在CHROME中显示正常,但真机调试布局出现问题,如附件1和附件2显示。11.3日还是正常的,后面升级过就不正常了。我已经尝试如下:
1、以为是基座的问题,重新编译过基座也是不行。
2、按照https://ask.dcloud.net.cn/article/37911改了 __uniappview.html文件的内容并重新打开编译基座,还是不行
现在导致根本无法真机调试,而且还有其他几个项目也是用UNIAPP开发的横屏项目,改过的都不敢更新了。非常紧急,希望得到支持,非常感谢,非常感谢!!!
收起阅读 »5+ App 一键登录使用指南
概述
uni一键登录
是DCloud联合个推公司推出的,整合了三大运营商网关认证能力的服务。
通过运营商的底层SDK,实现App端无需短信验证码直接获取手机号,也就是很多主流App都提供的一键登陆功能。
uni一键登录
是替代短信验证登录的下一代登录验证方式,能消除现有短信验证模式等待时间长、操作繁琐和容易泄露的痛点。
- 支持版本:HBuilderX 3.0+
- 支持项目类型:uni-app的App端,5+ App,Wap2App
- 支持系统平台: Android,iOS
- 支持运营商: 中国移动,中国联通,中国电信
uni-app 项目请参考:一键登录(uni-verify)
运行效果展示(支持全屏模式和非全屏模式)
全屏效果 | 非全屏效果 |
---|---|
<img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/full_styles_v2.png"> | <img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/half_styles_v2.png"> |
注:页面标注的属性可以修改,具体请参考下面的 univerifyStyle 数据结构说明
开通
开通uni一键登录服务
开发者需要登录DCloud开发者中心,申请开通一键登录服务。
详细步骤参考:开通一键登录服务的详细教程
开通成功后会得到 apiKey、apiSecret。这2个信息,后续需要配置在uniCloud的云函数里。同时注意保密,这2个信息也是计费凭证。
集成模块
- 云端打包
在项目manifest.json页面“App模块配置”项的“OAuth(登录鉴权)”下勾选“一键登录(uni-verify)”
- 离线打包
- Android平台:一键登录Android离线打包配置
- iOS平台:一键登录iOS离线打包配置
开通uniCloud服务
一键登录在客户端获取 access_token 后,必须在 uniCloud 换取手机号码。
对于5+ App,需要新建一个 uni-app 应用,且开通其uniCloud服务。
在uniCloud的云函数中拿到手机号后,可以通过云函数url方式生成普通的http接口给 5+ App 使用。
开通uniCloud是免费的,其中阿里云是全免费,腾讯云是提供一个免费服务空间。
注意:
虽然一键登录需要uniCloud,但并不要求开发者把所有的后台服务都迁移到uniCloud
服务器API详见:uniCloud云函数中使用一键登录
开发
客户端 - 获取 AuthService
使用一键登录
,需要先调用plus.oauth.getServices获取服务对应的 AuthService 对象:
- id 为 'univerify'
- description 为 '一键登录'
示例代码如下:
var auth = null
plus.oauth.getServices(function(services) {
for (var i in services) {
var service = services[i];
if (service.id == "univerify") {
auth = service;
break;
}
}
}
客户端 - 预登录(可选)
预登录auth.preLogin操作可以判断当前设备环境是否支持一键登录授权认证,如果支持则可以显示一键登录选项,同时预登录会准备好相关环境,显著提升后续一键登录的操作速度。
如果当前设备环境不支持一键登录,此时应该显示其他的登录选项。
示例代码如下:
auth.preLogin(function(){ //预登录成功
// 显示一键登录选项
},function(error){ // 预登录失败
// 不显示一键登录选项(或置灰)
// 根据错误信息判断失败原因,如有需要可将错误提交给统计服务器
console.log(error.message);
})
错误信息数据示例:
{
"appid": "pPyZW6PXba10aJ00911",
"code": 30005,
"message": "-20202当前没有开启蜂窝网络, 请检查是否开启蜂窝网络。",
"metadata": {
"resultCode": "1",
"resultData": {},
"resultMsg": "获取鉴权信息失败",
"traceId": ""
},
"uid": "8b91b76e0f074cef74aa30811ff737"
}
客户端 - 请求登录授权
调用请求登录授权auth.login接口,弹出用户授权界面,根据用户操作及授权结果返回对应的回调,获取到openid
、access_token
示例代码如下:
auth.login(function(event){ //登录成功
var openid = auth.authResult.openid;
var access_tolen = auth.authResult.access_token;
},function(error){ //登录失败
},{ // 自定义页面参数
univerifyStyle: { // 自定义登录框样式
//参考`univerifyStyle 数据结构`
}
})
univerifyStyle 数据结构
{
"fullScreen": false, // 是否全屏显示,默认值: false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": true, // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"0px"
},
"privacyTerms": {
"defaultCheckBoxState":true, // 条款勾选框初始状态 默认值: true
"uncheckedImage":"", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
"checkedImage":"", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [
// 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
},
"buttons": { // 仅全屏模式生效,配置页面下方按钮 (3.1.14+ 版本支持)
"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
"list": [{
"iconPath": "/static/wechat.png", // 图标路径仅支持本地图片
"onclick": function() {} // 按钮点击回调方法
},
{
"iconPath": "/static/apple.png",
"onclick": function() {} // 按钮点击回调方法
}
]
}
}
客户端 - 关闭一键登录界面
请求登录认证操作完成后,不管成功或失败都不会关闭一键登录界面,需要主动调用auth.closeAuthView方法关闭。
客户端登录认证完成只是说明获取 access_token 成功,需要将此数据提交到服务器获取手机号码,完成业务服务登录逻辑后通知客户端关闭登录界面。
auth.closeAuthView()
获取勾选框状态 (3.2.5+ 版本支持)
获取用户是否选中了勾选框
var state = auth.getCheckBoxState();
// true 选中,false 未选中
换取手机号码
在 uniCloud 中可以将客户端获取的 access_token 置换为真实的手机号码。
重要提示:为了保证数据的安全,用户手机号码信息不应该返回给客户端 !!!
前置条件:已创建一个uni-app 应用,且开通uniCloud服务。
对于5+ App来说,因为本身不支持uniCloud能力:因此需要http服务化云函数进行调用。
操作步骤:
-
新建云函数,实现一键登录功能并上传部署。
创建云函数,代码参考uni-app 实现
-
将刚才上传的云函数,开通http服务状态。
-
5+ 应用访问uni-app 应用的 http 服务
返回数据示例
{
"data": {
"code": 0,
"success": true,
"phoneNumber": "166xxxx6666"
},
"statusCode": 200,
"header": {
"Content-Type": "application/json; charset=utf-8",
"Connection": "keep-alive",
"Content-Length": "53",
"Date": "Fri, 06 Nov 2020 08:57:21 GMT",
"X-CloudBase-Request-Id": "xxxxxxxxxxx",
"ETag": "xxxxxx""
},
"errMsg": "request:ok"
}
常见问题
- 双卡手机能否同时获取两个手机号码
不支持同时获取两个手机号,
双卡手机以开启数据流量的 SIM 卡进行认证。
概述
uni一键登录
是DCloud联合个推公司推出的,整合了三大运营商网关认证能力的服务。
通过运营商的底层SDK,实现App端无需短信验证码直接获取手机号,也就是很多主流App都提供的一键登陆功能。
uni一键登录
是替代短信验证登录的下一代登录验证方式,能消除现有短信验证模式等待时间长、操作繁琐和容易泄露的痛点。
- 支持版本:HBuilderX 3.0+
- 支持项目类型:uni-app的App端,5+ App,Wap2App
- 支持系统平台: Android,iOS
- 支持运营商: 中国移动,中国联通,中国电信
uni-app 项目请参考:一键登录(uni-verify)
运行效果展示(支持全屏模式和非全屏模式)
全屏效果 | 非全屏效果 |
---|---|
<img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/full_styles_v2.png"> | <img src="https://img.cdn.aliyun.dcloud.net.cn/client/doc/univerify/half_styles_v2.png"> |
注:页面标注的属性可以修改,具体请参考下面的 univerifyStyle 数据结构说明
开通
开通uni一键登录服务
开发者需要登录DCloud开发者中心,申请开通一键登录服务。
详细步骤参考:开通一键登录服务的详细教程
开通成功后会得到 apiKey、apiSecret。这2个信息,后续需要配置在uniCloud的云函数里。同时注意保密,这2个信息也是计费凭证。
集成模块
- 云端打包
在项目manifest.json页面“App模块配置”项的“OAuth(登录鉴权)”下勾选“一键登录(uni-verify)”
- 离线打包
- Android平台:一键登录Android离线打包配置
- iOS平台:一键登录iOS离线打包配置
开通uniCloud服务
一键登录在客户端获取 access_token 后,必须在 uniCloud 换取手机号码。
对于5+ App,需要新建一个 uni-app 应用,且开通其uniCloud服务。
在uniCloud的云函数中拿到手机号后,可以通过云函数url方式生成普通的http接口给 5+ App 使用。
开通uniCloud是免费的,其中阿里云是全免费,腾讯云是提供一个免费服务空间。
注意:
虽然一键登录需要uniCloud,但并不要求开发者把所有的后台服务都迁移到uniCloud
服务器API详见:uniCloud云函数中使用一键登录
开发
客户端 - 获取 AuthService
使用一键登录
,需要先调用plus.oauth.getServices获取服务对应的 AuthService 对象:
- id 为 'univerify'
- description 为 '一键登录'
示例代码如下:
var auth = null
plus.oauth.getServices(function(services) {
for (var i in services) {
var service = services[i];
if (service.id == "univerify") {
auth = service;
break;
}
}
}
客户端 - 预登录(可选)
预登录auth.preLogin操作可以判断当前设备环境是否支持一键登录授权认证,如果支持则可以显示一键登录选项,同时预登录会准备好相关环境,显著提升后续一键登录的操作速度。
如果当前设备环境不支持一键登录,此时应该显示其他的登录选项。
示例代码如下:
auth.preLogin(function(){ //预登录成功
// 显示一键登录选项
},function(error){ // 预登录失败
// 不显示一键登录选项(或置灰)
// 根据错误信息判断失败原因,如有需要可将错误提交给统计服务器
console.log(error.message);
})
错误信息数据示例:
{
"appid": "pPyZW6PXba10aJ00911",
"code": 30005,
"message": "-20202当前没有开启蜂窝网络, 请检查是否开启蜂窝网络。",
"metadata": {
"resultCode": "1",
"resultData": {},
"resultMsg": "获取鉴权信息失败",
"traceId": ""
},
"uid": "8b91b76e0f074cef74aa30811ff737"
}
客户端 - 请求登录授权
调用请求登录授权auth.login接口,弹出用户授权界面,根据用户操作及授权结果返回对应的回调,获取到openid
、access_token
示例代码如下:
auth.login(function(event){ //登录成功
var openid = auth.authResult.openid;
var access_tolen = auth.authResult.access_token;
},function(error){ //登录失败
},{ // 自定义页面参数
univerifyStyle: { // 自定义登录框样式
//参考`univerifyStyle 数据结构`
}
})
univerifyStyle 数据结构
{
"fullScreen": false, // 是否全屏显示,默认值: false
"backgroundColor": "#ffffff", // 授权页面背景颜色,默认值:#ffffff
"backgroundImage": "", // 全屏显示的背景图片,默认值:"" (仅支持本地图片,只有全屏显示时支持)
"icon": {
"path": "static/xxx.png" // 自定义显示在授权框中的logo,仅支持本地图片 默认显示App logo
},
"phoneNum": {
"color": "#202020" // 手机号文字颜色 默认值:#202020
},
"slogan": {
"color": "#BBBBBB" // slogan 字体颜色 默认值:#BBBBBB
},
"authButton": {
"normalColor": "#3479f5", // 授权按钮正常状态背景颜色 默认值:#3479f5
"highlightColor": "#2861c5", // 授权按钮按下状态背景颜色 默认值:#2861c5(仅ios支持)
"disabledColor": "#73aaf5", // 授权按钮不可点击时背景颜色 默认值:#73aaf5(仅ios支持)
"textColor": "#ffffff", // 授权按钮文字颜色 默认值:#ffffff
"title": "本机号码一键登录", // 授权按钮文案 默认值:“本机号码一键登录”
"borderRadius": "24px" // 授权按钮圆角 默认值:"24px" (按钮高度的一半)
},
"otherLoginButton": {
"visible": true, // 是否显示其他登录按钮,默认值:true
"normalColor": "", // 其他登录按钮正常状态背景颜色 默认值:透明
"highlightColor": "", // 其他登录按钮按下状态背景颜色 默认值:透明
"textColor": "#656565", // 其他登录按钮文字颜色 默认值:#656565
"title": "其他登录方式", // 其他登录方式按钮文字 默认值:“其他登录方式”
"borderColor": "", //边框颜色 默认值:透明(仅iOS支持)
"borderRadius": "0px" // 其他登录按钮圆角 默认值:"0px"
},
"privacyTerms": {
"defaultCheckBoxState":true, // 条款勾选框初始状态 默认值: true
"uncheckedImage":"", // 可选 条款勾选框未选中状态图片(仅支持本地图片 建议尺寸 24x24px)(3.2.0+ 版本支持)
"checkedImage":"", // 可选 条款勾选框选中状态图片(仅支持本地图片 建议尺寸24x24px)(3.2.0+ 版本支持)
"textColor": "#BBBBBB", // 文字颜色 默认值:#BBBBBB
"termsColor": "#5496E3", // 协议文字颜色 默认值: #5496E3
"prefix": "我已阅读并同意", // 条款前的文案 默认值:“我已阅读并同意”
"suffix": "并使用本机号码登录", // 条款后的文案 默认值:“并使用本机号码登录”
"privacyItems": [
// 自定义协议条款,最大支持2个,需要同时设置url和title. 否则不生效
{
"url": "https://", // 点击跳转的协议详情页面
"title": "用户服务协议" // 协议名称
}
]
},
"buttons": { // 仅全屏模式生效,配置页面下方按钮 (3.1.14+ 版本支持)
"iconWidth": "45px", // 图标宽度(高度等比例缩放) 默认值:45px
"list": [{
"iconPath": "/static/wechat.png", // 图标路径仅支持本地图片
"onclick": function() {} // 按钮点击回调方法
},
{
"iconPath": "/static/apple.png",
"onclick": function() {} // 按钮点击回调方法
}
]
}
}
客户端 - 关闭一键登录界面
请求登录认证操作完成后,不管成功或失败都不会关闭一键登录界面,需要主动调用auth.closeAuthView方法关闭。
客户端登录认证完成只是说明获取 access_token 成功,需要将此数据提交到服务器获取手机号码,完成业务服务登录逻辑后通知客户端关闭登录界面。
auth.closeAuthView()
获取勾选框状态 (3.2.5+ 版本支持)
获取用户是否选中了勾选框
var state = auth.getCheckBoxState();
// true 选中,false 未选中
换取手机号码
在 uniCloud 中可以将客户端获取的 access_token 置换为真实的手机号码。
重要提示:为了保证数据的安全,用户手机号码信息不应该返回给客户端 !!!
前置条件:已创建一个uni-app 应用,且开通uniCloud服务。
对于5+ App来说,因为本身不支持uniCloud能力:因此需要http服务化云函数进行调用。
操作步骤:
-
新建云函数,实现一键登录功能并上传部署。
创建云函数,代码参考uni-app 实现
-
将刚才上传的云函数,开通http服务状态。
-
5+ 应用访问uni-app 应用的 http 服务
返回数据示例
{
"data": {
"code": 0,
"success": true,
"phoneNumber": "166xxxx6666"
},
"statusCode": 200,
"header": {
"Content-Type": "application/json; charset=utf-8",
"Connection": "keep-alive",
"Content-Length": "53",
"Date": "Fri, 06 Nov 2020 08:57:21 GMT",
"X-CloudBase-Request-Id": "xxxxxxxxxxx",
"ETag": "xxxxxx""
},
"errMsg": "request:ok"
}
常见问题
- 双卡手机能否同时获取两个手机号码
不支持同时获取两个手机号,
双卡手机以开启数据流量的 SIM 卡进行认证。
自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android)
自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android):https://ext.dcloud.net.cn/plugin?id=3404
自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android):https://ext.dcloud.net.cn/plugin?id=3404