
关于webview顶部灰条的解决
新版本webview调整了适配沉浸式的规则,开发者可以更灵活的根据自己的需要进行沉浸式模式的适配,
这种情况下webview会自动调整内容区域避免和安全区域重合,一些老项目升级后如不做处理在沉浸式模式下顶部会显示灰条或者其他显示异常,该问题可以通过以下方式解决:
注意:webview style 中位置区域的计算是包含安全区域的
在meta节点中添加viewport-fit,关于viewport-fit 的详细说明可以自己百度下
<meta name="viewport" content="... viewport-fit=cover"/>
如果想和老版本保持一致可以设置webview style 的contentAdjust属性(该属性不支持动态修改)
false 表示不调整如下:
// 5+App
var wb = new plus.webview.create("url","id", {contentAdjust:false});
//uniapp
"pages": [
{
"path": "....",
"style": {
"app-plus": {
"contentAdjust":false
如果是通过 web-view 组件加载 html 组件页面上面或下面有留白除了需要添加 viewport-fit=cover
,还要给 html 添加 style="height: 100vh;"
<html style="height: 100vh;">
由于问题产生的原因不同,如果以上无法解决你的问题请在下方留言
新版本webview调整了适配沉浸式的规则,开发者可以更灵活的根据自己的需要进行沉浸式模式的适配,
这种情况下webview会自动调整内容区域避免和安全区域重合,一些老项目升级后如不做处理在沉浸式模式下顶部会显示灰条或者其他显示异常,该问题可以通过以下方式解决:
注意:webview style 中位置区域的计算是包含安全区域的
在meta节点中添加viewport-fit,关于viewport-fit 的详细说明可以自己百度下
<meta name="viewport" content="... viewport-fit=cover"/>
如果想和老版本保持一致可以设置webview style 的contentAdjust属性(该属性不支持动态修改)
false 表示不调整如下:
// 5+App
var wb = new plus.webview.create("url","id", {contentAdjust:false});
//uniapp
"pages": [
{
"path": "....",
"style": {
"app-plus": {
"contentAdjust":false
如果是通过 web-view 组件加载 html 组件页面上面或下面有留白除了需要添加 viewport-fit=cover
,还要给 html 添加 style="height: 100vh;"
<html style="height: 100vh;">
由于问题产生的原因不同,如果以上无法解决你的问题请在下方留言
收起阅读 »
【全开源+免费更新】doodoo.js创建项目教程
创建项目
async/await
// 下载demo
git clone https://github.com/doodooke/doodoo.js.git
// 安装依赖
yarn install
// 进入项目
cd doodoo.js/example
// 启动项目
node app.js
启动项目
在项目目录下执行命令 node app.js,如果能看到类似下面的内容,表示服务启动成功。
[doodoo] Version: 2.0.0
[doodoo] Website: 127.0.0.1
[doodoo] Nodejs Version: v8.12.0
[doodoo] Nodejs Platform: darwin x64
[doodoo] Server Enviroment: development
[doodoo] Server Startup Time: 212ms
[doodoo] Server Current Time: 2018-08-21 11:17:19
[doodoo] Server Running At: http://127.0.0.1:3000
doodoo.js官方文档:https://doodooke.github.io/doodoo.js/#/
【案例】多多客小程序官网:doodooke.com
创建项目
async/await
// 下载demo
git clone https://github.com/doodooke/doodoo.js.git
// 安装依赖
yarn install
// 进入项目
cd doodoo.js/example
// 启动项目
node app.js
启动项目
在项目目录下执行命令 node app.js,如果能看到类似下面的内容,表示服务启动成功。
[doodoo] Version: 2.0.0
[doodoo] Website: 127.0.0.1
[doodoo] Nodejs Version: v8.12.0
[doodoo] Nodejs Platform: darwin x64
[doodoo] Server Enviroment: development
[doodoo] Server Startup Time: 212ms
[doodoo] Server Current Time: 2018-08-21 11:17:19
[doodoo] Server Running At: http://127.0.0.1:3000
doodoo.js官方文档:https://doodooke.github.io/doodoo.js/#/
【案例】多多客小程序官网:doodooke.com

分享一个基于uni-app简单的抽奖页面代码
<template>
<view class="container">
<view class="header">
<view class="header-title"> 点击转盘抽奖获得红包 </view>
</view>
<view class="main">
<view class="canvas-container">
<view :animation="animationData" class="canvas-content" >
<view class="canvas-line">
<view class="canvas-litem" v-for="(item,index1) in awardsList" :key="index1" :style="[{transform:'rotate('+item.lineTurn+')'}]"></view>
</view>
<view class="canvas-list">
<view class="canvas-item" v-for="(iteml,index2) in awardsList" :key="index2">
<view class="canvas-item-text" :style="[{transform:'rotate('+iteml.turn+')'}]">
<text>{{iteml.award}}</text>
<image class="canvas-item-text-img" src="../../static/icon/huodong.png"></image>
</view>
</view>
</view>
</view>
<view @tap="playReward" class="canvas-btn" v-bind:class="btnDisabled">开始 </view>
<view class="canvas-btn-table">剩余{{chishu}}次</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
awardsConfig : {
chance: true,
awards: [
{ index: 0, name: '10元红包',type:0},
{ index: 1, name: '谢谢参与',type:1},
{ index: 2, name: '50元红包',type:0},
{ index: 3, name: '谢谢参与',type:1},
{ index: 4, name: '100元话费',type:0},
{ index: 5, name: '谢谢参与',type:1},
{ index: 6, name: '20元红包',type:0},
{ index: 7, name: '谢谢参与',type:1}
]
},
awardsList: {},
animationData: {},
btnDisabled: '',
chishu:2
};
},
onLoad:function(){
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#A83FDB',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
},
onReady: function (e) {
this.drawAwardRoundel();
//分享
uni.showShareMenu({
withShareTicket: true
});
},
methods: {
//画抽奖圆盘
drawAwardRoundel: function () {
var awards = this.awardsConfig.awards;
var awardsList = [];
var turnNum = 1 / awards.length*360; // 文字旋转 turn 值
// 奖项列表
for (var i = 0; i < awards.length; i++) {
awardsList.push({ turn: i * turnNum + 'deg', lineTurn: i * turnNum + turnNum / 2 + 'deg', award: awards[i].name });
}
this.btnDisabled = this.awardsConfig.chance ? '' : 'disabled';
this.awardsList = awardsList;
},
//发起抽奖
playReward: function () {
if (this.chishu == 0) {
uni.showToast({
title:'抽奖次数已经用完',
icon:'none'
})
return
}
//中奖index
var awardsNum = this.awardsConfig.awards;
var awardIndex = Math.round(Math.random()*(awardsNum.length-1));//随机数
var runNum = 8;//旋转8周
var duration = 4000;//时长
// 旋转角度
this.runDeg = this.runDeg || 0;
this.runDeg = this.runDeg + (360 - this.runDeg % 360) + (360 * runNum - awardIndex * (360 / awardsNum.length))
//创建动画
var animationRun = uni.createAnimation({
duration: duration,
timingFunction: 'ease'
})
animationRun.rotate(this.runDeg).step();
this.animationData= animationRun.export();
this.btnDisabled= 'disabled';
// 中奖提示
var awardsConfig = this.awardsConfig;
var awardType = awardsConfig.awards[awardIndex].type;
this.chishu = this.chishu - 1;
if (awardType == 0) {
setTimeout(function () {
uni.showModal({
title: '恭喜',
content: '获得' + (awardsConfig.awards[awardIndex].name),
showCancel: false
});
this.btnDisabled= '';
}.bind(this), duration);
}else{
setTimeout(function () {
uni.showModal({
title: '很遗憾',
content: '没中奖 ' + (awardsConfig.awards[awardIndex].name),
showCancel: false
});
this.btnDisabled= '';
}.bind(this), duration);
}
}
}
}
</script>
<style>
page {
background: #fff;
}
.header{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100upx;
}
/* 转盘 */
.canvas-container {
margin: 0 auto;
position: relative;
width: 600upx;
height: 600upx;
border-radius: 50%;
box-shadow: 0 10upx 30upx #333, 0 0 10upx #000;
border: 10rpx solid #A83FDB;
}
.canvas-content {
position: absolute;
left: 0;
top: 0;
z-index: 1;
display: block;
width: 600upx;
height:600upx;
border-radius: inherit;
background-clip: padding-box;
/* background-color: #ffcb3f; */
}
.canvas-element {
position: relative;
z-index: 1;
width: inherit;
height: inherit;
border-radius: 50%;
}
.canvas-list {
position: absolute;
left: 0;
top: 0;
width: inherit;
height: inherit;
z-index: 9999;
}
.canvas-item {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
color: #e4370e;
font-weight: bold;
text-shadow: 0 1upx 1upx rgba(255, 255, 255, 0.6);
}
.canvas-item-text {
position: relative;
display: block;
padding-top: 20upx;
margin: 0 auto;
text-align: center;
-webkit-transform-origin: 50% 300upx;
transform-origin: 50% 300upx;
display: flex;
flex-direction: column;
align-items: center;
}
.canvas-item-text text{
font-size:30upx;
}
.canvas-item-text-img{
width:60upx;
height:60upx;
padding-top:10upx;
}
/* 分隔线 */
.canvas-line {
position: absolute;
left: 0;
top: 0;
width: inherit;
height: inherit;
z-index: 99;
}
.canvas-litem {
position: absolute;
left: 300upx;
top: 0;
width: 3upx;
height: 300upx;
background-color: rgba(228, 55, 14, 0.4);
overflow: hidden;
-webkit-transform-origin: 50% 300upx;
transform-origin: 50% 300upx;
}
/**
* 抽奖按钮
*/
.canvas-btn {
position: absolute;
left: 260upx;
top: 260upx;
z-index: 400;
width: 80upx;
height: 80upx;
border-radius: 50%;
color: #f4e9cc;
background-color: #e44025;
line-height: 80upx;
text-align: center;
font-size: 26upx;
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6);
text-decoration: none;
}
.canvas-btn::after {
position: absolute;
display: block;
content: ' ';
left: 12upx;
top: -44upx;
width: 0;
height: 0;
overflow: hidden;
border-width:30upx;
border-style: solid;
border-color: transparent;
border-bottom-color: #e44025;
}
.canvas-btn.disabled {
pointer-events: none;
background: #b07a7b;
color: #ccc;
}
.canvas-btn.disabled::after {
border-bottom-color: #b07a7b;
}
.canvas-btn-table{
color:#A83FDB;
width:120upx;
text-align: center;
position: absolute;
left: 240upx;
top:360upx;
font-size:26upx;
background-color: #FFFFFF;
opacity: 0.9;
}
</style>
<template>
<view class="container">
<view class="header">
<view class="header-title"> 点击转盘抽奖获得红包 </view>
</view>
<view class="main">
<view class="canvas-container">
<view :animation="animationData" class="canvas-content" >
<view class="canvas-line">
<view class="canvas-litem" v-for="(item,index1) in awardsList" :key="index1" :style="[{transform:'rotate('+item.lineTurn+')'}]"></view>
</view>
<view class="canvas-list">
<view class="canvas-item" v-for="(iteml,index2) in awardsList" :key="index2">
<view class="canvas-item-text" :style="[{transform:'rotate('+iteml.turn+')'}]">
<text>{{iteml.award}}</text>
<image class="canvas-item-text-img" src="../../static/icon/huodong.png"></image>
</view>
</view>
</view>
</view>
<view @tap="playReward" class="canvas-btn" v-bind:class="btnDisabled">开始 </view>
<view class="canvas-btn-table">剩余{{chishu}}次</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
awardsConfig : {
chance: true,
awards: [
{ index: 0, name: '10元红包',type:0},
{ index: 1, name: '谢谢参与',type:1},
{ index: 2, name: '50元红包',type:0},
{ index: 3, name: '谢谢参与',type:1},
{ index: 4, name: '100元话费',type:0},
{ index: 5, name: '谢谢参与',type:1},
{ index: 6, name: '20元红包',type:0},
{ index: 7, name: '谢谢参与',type:1}
]
},
awardsList: {},
animationData: {},
btnDisabled: '',
chishu:2
};
},
onLoad:function(){
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#A83FDB',
animation: {
duration: 400,
timingFunc: 'easeIn'
}
})
},
onReady: function (e) {
this.drawAwardRoundel();
//分享
uni.showShareMenu({
withShareTicket: true
});
},
methods: {
//画抽奖圆盘
drawAwardRoundel: function () {
var awards = this.awardsConfig.awards;
var awardsList = [];
var turnNum = 1 / awards.length*360; // 文字旋转 turn 值
// 奖项列表
for (var i = 0; i < awards.length; i++) {
awardsList.push({ turn: i * turnNum + 'deg', lineTurn: i * turnNum + turnNum / 2 + 'deg', award: awards[i].name });
}
this.btnDisabled = this.awardsConfig.chance ? '' : 'disabled';
this.awardsList = awardsList;
},
//发起抽奖
playReward: function () {
if (this.chishu == 0) {
uni.showToast({
title:'抽奖次数已经用完',
icon:'none'
})
return
}
//中奖index
var awardsNum = this.awardsConfig.awards;
var awardIndex = Math.round(Math.random()*(awardsNum.length-1));//随机数
var runNum = 8;//旋转8周
var duration = 4000;//时长
// 旋转角度
this.runDeg = this.runDeg || 0;
this.runDeg = this.runDeg + (360 - this.runDeg % 360) + (360 * runNum - awardIndex * (360 / awardsNum.length))
//创建动画
var animationRun = uni.createAnimation({
duration: duration,
timingFunction: 'ease'
})
animationRun.rotate(this.runDeg).step();
this.animationData= animationRun.export();
this.btnDisabled= 'disabled';
// 中奖提示
var awardsConfig = this.awardsConfig;
var awardType = awardsConfig.awards[awardIndex].type;
this.chishu = this.chishu - 1;
if (awardType == 0) {
setTimeout(function () {
uni.showModal({
title: '恭喜',
content: '获得' + (awardsConfig.awards[awardIndex].name),
showCancel: false
});
this.btnDisabled= '';
}.bind(this), duration);
}else{
setTimeout(function () {
uni.showModal({
title: '很遗憾',
content: '没中奖 ' + (awardsConfig.awards[awardIndex].name),
showCancel: false
});
this.btnDisabled= '';
}.bind(this), duration);
}
}
}
}
</script>
<style>
page {
background: #fff;
}
.header{
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100upx;
}
/* 转盘 */
.canvas-container {
margin: 0 auto;
position: relative;
width: 600upx;
height: 600upx;
border-radius: 50%;
box-shadow: 0 10upx 30upx #333, 0 0 10upx #000;
border: 10rpx solid #A83FDB;
}
.canvas-content {
position: absolute;
left: 0;
top: 0;
z-index: 1;
display: block;
width: 600upx;
height:600upx;
border-radius: inherit;
background-clip: padding-box;
/* background-color: #ffcb3f; */
}
.canvas-element {
position: relative;
z-index: 1;
width: inherit;
height: inherit;
border-radius: 50%;
}
.canvas-list {
position: absolute;
left: 0;
top: 0;
width: inherit;
height: inherit;
z-index: 9999;
}
.canvas-item {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
color: #e4370e;
font-weight: bold;
text-shadow: 0 1upx 1upx rgba(255, 255, 255, 0.6);
}
.canvas-item-text {
position: relative;
display: block;
padding-top: 20upx;
margin: 0 auto;
text-align: center;
-webkit-transform-origin: 50% 300upx;
transform-origin: 50% 300upx;
display: flex;
flex-direction: column;
align-items: center;
}
.canvas-item-text text{
font-size:30upx;
}
.canvas-item-text-img{
width:60upx;
height:60upx;
padding-top:10upx;
}
/* 分隔线 */
.canvas-line {
position: absolute;
left: 0;
top: 0;
width: inherit;
height: inherit;
z-index: 99;
}
.canvas-litem {
position: absolute;
left: 300upx;
top: 0;
width: 3upx;
height: 300upx;
background-color: rgba(228, 55, 14, 0.4);
overflow: hidden;
-webkit-transform-origin: 50% 300upx;
transform-origin: 50% 300upx;
}
/**
* 抽奖按钮
*/
.canvas-btn {
position: absolute;
left: 260upx;
top: 260upx;
z-index: 400;
width: 80upx;
height: 80upx;
border-radius: 50%;
color: #f4e9cc;
background-color: #e44025;
line-height: 80upx;
text-align: center;
font-size: 26upx;
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6);
text-decoration: none;
}
.canvas-btn::after {
position: absolute;
display: block;
content: ' ';
left: 12upx;
top: -44upx;
width: 0;
height: 0;
overflow: hidden;
border-width:30upx;
border-style: solid;
border-color: transparent;
border-bottom-color: #e44025;
}
.canvas-btn.disabled {
pointer-events: none;
background: #b07a7b;
color: #ccc;
}
.canvas-btn.disabled::after {
border-bottom-color: #b07a7b;
}
.canvas-btn-table{
color:#A83FDB;
width:120upx;
text-align: center;
position: absolute;
left: 240upx;
top:360upx;
font-size:26upx;
background-color: #FFFFFF;
opacity: 0.9;
}
</style>
收起阅读 »

GraceUI6.0 正式发布!支持Vue3 nvue 150+组件及模板(组件+布局+模板+JS工具库)、兼容性极好(1万+ 开发者真实项目反馈)! 从1.0到6.0 期待与您美好相遇~
2022年06月13日 GraceUI 6.0 版本正式发布
GraceUI 是一款成熟完善的、为uni-app量身打造的优秀的UI框架!经过近4年的维护已经成为组件多、界面丰富、运行稳定的 uni-app 专业UI框架 !
GraceUI 第一版发布于2018年9月,4年多来我们一直坚持收集反馈,高效、高频更新!从1.0到6.0 GraceUI 已经变得更加丰富、兼容性更好~
在此也感谢近万名使用者的一路相伴,感谢你们的支持与反馈~
官网 : https://www.graceui.com/
1. 丰富的组件及样式
GraceUI 的组件、样式、布局、界面非常丰富,总量 150+!您可以使用他们快速的完成应用页面的布局~
1.1 基础布局组件及样式
页面布局 · Flex布局 · 元素定位 · 文本颜色 · 背景样式 · 阴影效果 · 圆角边框 · 文本样式 · 内置图标 · 样式动画
1.2 常用布局
宫格布局 · 头部导航 · 底部导航 · 切换导航 · 吸顶容器 · 动态吸顶 · 通用列表 · 滑动列表 · 新闻列表 · 评论列表 · 图文卡片 · 名片卡片 · 滚动区域 · 遮罩弹层 · 局部选项卡 · 全屏选项卡 · 分段切换 · 折叠面板 · 普通表格 · 数据表格 · 分类展示 · 横向公告 · 返回顶部 · 弹出菜单 · 功能菜单 · 时间轴 · 侧边抽屉 · 图标分类 · 横向日期
1.3 加载组件
加载组件 · 全屏加载 · 下拉刷新 · 刷新组件 · 上拉加载
1.4 常用组件
徽章组件 · 标签组件 · 滚动公告 · 无缝滚动 · 按钮组件 · 进度按钮 · 搜索组件 · 星级评价 · 通用标题 · 倒计时 · 轮播组件 · 日历时间 · 区间滑块 · 进度圆环 · 城市选择 · 地区联动 · 步骤提示 · 链接组件 · 优惠券组件 · 为空展示 · 图片选择 · 多图上传 · 头像群组 · 数值动画 · 日期时间选择 · 时间段选择器
1.5 对话框组件
顶部消息框 · 模态对话框 · 底部对话框 · 底部消息框
1.6 表单相关
表单元素 · 表单验证 · 数值框 · 数字键盘 · 可选标签 · 点选按钮 · 下拉选择
1.7 文章相关
文本编辑器 · 编辑器解析 · 富文本加强 · 展开全文
1.8 JS 工具库
时间转换 · 网络请求 · 随机数值 · md5转换 · 系统信息
1.9 常用界面库
搜索界面 · 登录注册 · 个人中心 · 购物车 · 订单中心 · 图片剪裁 · 商品详情 · 图片懒加载 · 骨架加载 · 抽奖活动 · 瀑布流 · 选择问卷 · 地址列表 · 添加地址 · 证件上传 · 滚动推荐 · 短信验证 · 排行榜 · 商城套装 · 即时通讯
2. 强大的版本支持 业界首款成熟的基于uni-app 的 nvue UI 框架
GraceUI 6.0 基于 vue3.0 同时支持 nvue,为app端更流畅的体验提供了极大的便利~
nvue 普通版本基本同步,想优化您的app?添加一个 .nuve 复制 vue 代码即可迅速完成~
3. 更好的兼容性、更稳定
GraceUI 自发布以来已经有上万名使用者,在开发的过程中不断给我们最真实的反馈,我们更是以积极的心态面对每一个反馈,及时确认问题并及时修正(最快10分钟哦)~经过一年多的 "锤炼",GraceUI 变得极度稳定、兼容性极好~ 感谢每一份反馈,感谢每一位支持者~
您不需要费力的去布局,有 GraceUI 就够了 ^_^
4. Grace.JS 化繁为简,只为热爱 ~
Grace.js 是 GraceUI 框架的 js 框架,目标是 " 简化您的 uni-app 及 微信小程序 api 操作,同时提供丰富、好用的 js 工具,大幅度提高您的开发效率" 。
5. 收费说明
GraceUI 6.0 版本售价 299元
收费只是最基本的维护开销,不是"赚钱的买卖",我们更认为是您的一种信任,对于我们更多的是责任!所以这里不是淘宝,不是简单的交易!我们希望得到正向的反馈、正向的帮助,不断完善,最终成为"组件多、稳定性好" 的UI框架!
一次性收费永久免费更新 ~
官网 :
2022年06月13日 GraceUI 6.0 版本正式发布
GraceUI 是一款成熟完善的、为uni-app量身打造的优秀的UI框架!经过近4年的维护已经成为组件多、界面丰富、运行稳定的 uni-app 专业UI框架 !
GraceUI 第一版发布于2018年9月,4年多来我们一直坚持收集反馈,高效、高频更新!从1.0到6.0 GraceUI 已经变得更加丰富、兼容性更好~
在此也感谢近万名使用者的一路相伴,感谢你们的支持与反馈~
官网 : https://www.graceui.com/
1. 丰富的组件及样式
GraceUI 的组件、样式、布局、界面非常丰富,总量 150+!您可以使用他们快速的完成应用页面的布局~
1.1 基础布局组件及样式
页面布局 · Flex布局 · 元素定位 · 文本颜色 · 背景样式 · 阴影效果 · 圆角边框 · 文本样式 · 内置图标 · 样式动画
1.2 常用布局
宫格布局 · 头部导航 · 底部导航 · 切换导航 · 吸顶容器 · 动态吸顶 · 通用列表 · 滑动列表 · 新闻列表 · 评论列表 · 图文卡片 · 名片卡片 · 滚动区域 · 遮罩弹层 · 局部选项卡 · 全屏选项卡 · 分段切换 · 折叠面板 · 普通表格 · 数据表格 · 分类展示 · 横向公告 · 返回顶部 · 弹出菜单 · 功能菜单 · 时间轴 · 侧边抽屉 · 图标分类 · 横向日期
1.3 加载组件
加载组件 · 全屏加载 · 下拉刷新 · 刷新组件 · 上拉加载
1.4 常用组件
徽章组件 · 标签组件 · 滚动公告 · 无缝滚动 · 按钮组件 · 进度按钮 · 搜索组件 · 星级评价 · 通用标题 · 倒计时 · 轮播组件 · 日历时间 · 区间滑块 · 进度圆环 · 城市选择 · 地区联动 · 步骤提示 · 链接组件 · 优惠券组件 · 为空展示 · 图片选择 · 多图上传 · 头像群组 · 数值动画 · 日期时间选择 · 时间段选择器
1.5 对话框组件
顶部消息框 · 模态对话框 · 底部对话框 · 底部消息框
1.6 表单相关
表单元素 · 表单验证 · 数值框 · 数字键盘 · 可选标签 · 点选按钮 · 下拉选择
1.7 文章相关
文本编辑器 · 编辑器解析 · 富文本加强 · 展开全文
1.8 JS 工具库
时间转换 · 网络请求 · 随机数值 · md5转换 · 系统信息
1.9 常用界面库
搜索界面 · 登录注册 · 个人中心 · 购物车 · 订单中心 · 图片剪裁 · 商品详情 · 图片懒加载 · 骨架加载 · 抽奖活动 · 瀑布流 · 选择问卷 · 地址列表 · 添加地址 · 证件上传 · 滚动推荐 · 短信验证 · 排行榜 · 商城套装 · 即时通讯
2. 强大的版本支持 业界首款成熟的基于uni-app 的 nvue UI 框架
GraceUI 6.0 基于 vue3.0 同时支持 nvue,为app端更流畅的体验提供了极大的便利~
nvue 普通版本基本同步,想优化您的app?添加一个 .nuve 复制 vue 代码即可迅速完成~
3. 更好的兼容性、更稳定
GraceUI 自发布以来已经有上万名使用者,在开发的过程中不断给我们最真实的反馈,我们更是以积极的心态面对每一个反馈,及时确认问题并及时修正(最快10分钟哦)~经过一年多的 "锤炼",GraceUI 变得极度稳定、兼容性极好~ 感谢每一份反馈,感谢每一位支持者~
您不需要费力的去布局,有 GraceUI 就够了 ^_^
4. Grace.JS 化繁为简,只为热爱 ~
Grace.js 是 GraceUI 框架的 js 框架,目标是 " 简化您的 uni-app 及 微信小程序 api 操作,同时提供丰富、好用的 js 工具,大幅度提高您的开发效率" 。
5. 收费说明
GraceUI 6.0 版本售价 299元
收费只是最基本的维护开销,不是"赚钱的买卖",我们更认为是您的一种信任,对于我们更多的是责任!所以这里不是淘宝,不是简单的交易!我们希望得到正向的反馈、正向的帮助,不断完善,最终成为"组件多、稳定性好" 的UI框架!
一次性收费永久免费更新 ~
官网 :
收起阅读 »
UNI-APP 开发微信公众号(H5)JSSDK 的使用方式
uni-app 中为兼容微信小程序生态存在全局的 wx 对象,而微信 JS-SDK 也是注册全局的 wx 对象,为避免混淆,可以将微信 JS-SDK 中的 wx 对象改名。采用以下两种方案之一即可。
方案一:模块化
在 uni-app 中可以使用模块方式引用微信 js-sdk ,可以避免与 uni-app 内置 wx 全局对象冲突的问题。
微信官网直接下载的如果使用有问题,可以使用 jweixin-module。
安装
- NPM安装方式(不会用NPM就不要用这种方式)
npm install jweixin-module --save
- 下载使用方式
下载地址:https://unpkg.com/jweixin-module@1.6.0/lib/index.js
使用
var jWeixin = require('jweixin-module')
jWeixin.ready(function(){
// TODO
});
方案二:全局引入
如果不使用模块化引入 JS-SDK,而采用传统方式在 html 模板中直接全局引入,可以修改全局变量名称。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<!-- Open Graph data -->
<!-- <meta property="og:title" content="Title Here" /> -->
<!-- <meta property="og:url" content="http://www.example.com/" /> -->
<!-- <meta property="og:image" content="http://example.com/image.jpg" /> -->
<!-- <meta property="og:description" content="Description Here" /> -->
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"/>
<script>
window.jWeixin=window.wx;
delete window.wx;
</script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
完整API
uni-app 中为兼容微信小程序生态存在全局的 wx 对象,而微信 JS-SDK 也是注册全局的 wx 对象,为避免混淆,可以将微信 JS-SDK 中的 wx 对象改名。采用以下两种方案之一即可。
方案一:模块化
在 uni-app 中可以使用模块方式引用微信 js-sdk ,可以避免与 uni-app 内置 wx 全局对象冲突的问题。
微信官网直接下载的如果使用有问题,可以使用 jweixin-module。
安装
- NPM安装方式(不会用NPM就不要用这种方式)
npm install jweixin-module --save
- 下载使用方式
下载地址:https://unpkg.com/jweixin-module@1.6.0/lib/index.js
使用
var jWeixin = require('jweixin-module')
jWeixin.ready(function(){
// TODO
});
方案二:全局引入
如果不使用模块化引入 JS-SDK,而采用传统方式在 html 模板中直接全局引入,可以修改全局变量名称。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<!-- Open Graph data -->
<!-- <meta property="og:title" content="Title Here" /> -->
<!-- <meta property="og:url" content="http://www.example.com/" /> -->
<!-- <meta property="og:image" content="http://example.com/image.jpg" /> -->
<!-- <meta property="og:description" content="Description Here" /> -->
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"/>
<script>
window.jWeixin=window.wx;
delete window.wx;
</script>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
完整API
收起阅读 »

android平台:在uni-app使用5+插件
开发环境及工具
- Windows系统
- android studio
- HBuilderX
- 5+ SDK
- Android平台 5+ SDK 参考手册
uni-app 插件扩展
创建项目
- 在HBuilderX中创建一个uni-app项目,操作步骤:文件->新建->项目->选择uni-app->点击创建即可。
- 创建js插件文件,可采用下方模板。已兼容5+ 插件开发。
! function(root, factory) { if (typeof exports == 'object' && typeof module != 'undefined') { module.exports = factory() } else if (typeof define == 'function' && define.amd) { define(factory) } else { // 5+ 兼容 document.addEventListener('plusready', function(){ // 修改此处为插件命名 var moduleName = 'plugintest'; // 挂载在plus下 root.plus[moduleName] = factory() },false); } }(this, function() { //在此处定义自己的方法 var _BARCODE = 'plugintest'; var plugintest = { /*方法已忽略,详细方法请参考SDK中的demo*/ }; return plugintest; });
- 插件引用。直接require即可(5+ 项目需使用script标签引入)。详细代码请下载附件,解压至任意目录,拖入HBuilderX即可。
- 生成本地打包资源,导入android studio项目。可参考:HBuilderX 生成本地打包App资源
插件编写
用户可采用同步或异步的方式将结果传递到android端。
同步方法:
void plus.bridge.execSync( String service, String action, Array<String> args ); service: 插件类别名,对应dcloud_properties.xml的feature name。 action: 调用android端插件方法名称。对应java文件的方法名。 args: 参数列表。
异步方法:
void plus.bridge.exec( String service, String action, Array<String> args ); service: 插件类别名,对应dcloud_properties.xml的feature name。 action: 调用android端插件方法名称。对应java文件的方法名。 args: 参数列表。
示例代码
var plugintest = { PluginTestFunction: function(Argus1, Argus2, Argus3, Argus4, successCallback, errorCallback) { var success = typeof successCallback !== 'function' ? null : function(args) { successCallback(args); }, fail = typeof errorCallback !== 'function' ? null : function(code) { errorCallback(code); }; var callbackID = plus.bridge.callbackId(success, fail); return plus.bridge.exec(_BARCODE, "PluginTestFunction", [callbackID, Argus1, Argus2, Argus3, Argus4]); } };
android 扩展插件
导入SDK工程到Android studio
-
下载SDK至任意目录(目录中一定不能含有中文)。
-
将SDK中的HBuilder-Integrate-AS项目导入android studio,操作步骤:Studio ->File ->open ->选择1中解压的目录 ->Ok即可。
-
注意:项目中必须包含lib.5plus.base-release.aar文件。
编写插件
-
创建一个java类继承自StandardFeature(HBuilder-Integrate-AS中的PGPlugintest.java)。
-
实现方法,方法名必须与js方法中windows.plus.bridge.exec()或windows.plus.bridge.execSync()方法的第二个传入参数相同。
-
方法中需存在两个形参,IWebview pWebview代表发起请求的webview,JSONArray array代表JS请求传入的参数。
-
android 执行完操作将数据返回到js层,可采取JSUtil.execCallback()方法实现结果的传递。
JSUtil.execCallback(IWebview pWebViewImpl,String pCallbackId,String pMessage,int pStatus,boolean pKeepCallback) 参数: pWebViewImpl - webview对象 pCallbackId - 回调方法ID pMessage - 回调信息 pStatus - 回调code值 如:OK、ERROR pKeepCallback - js层回调function是否要保存
其余方法可参考Android平台 5+ SDK 参考手册
代码示例
public class PGPlugintest extends StandardFeature { public void PluginTestFunction(IWebview pWebview, JSONArray array) { // 原生代码中获取JS层传递的参数, // 参数的获取顺序与JS层传递的顺序一致 String CallBackID = array.optString(0); JSONArray newArray = new JSONArray(); newArray.put(array.optString(1)); newArray.put(array.optString(2)); newArray.put(array.optString(3)); newArray.put(array.optString(4)); // 调用方法将原生代码的执行结果返回给js层并触发相应的JS层回调函数 JSUtil.execCallback(pWebview, CallBackID, newArray, JSUtil.OK, false); } }
插件配置
- 配置dcloud_properties.xml文件,在features节点下添加如下节点:
<features> <feature name="plugintest" value="com.example.H5PlusPlugin.PGPlugintest"/> </features>
- 配置android studio的build.gradle文件。参考文章:Android平台,uni-app离线打包集成要领及注意事项
- 示例代码在下方附件中下载。
开发环境及工具
- Windows系统
- android studio
- HBuilderX
- 5+ SDK
- Android平台 5+ SDK 参考手册
uni-app 插件扩展
创建项目
- 在HBuilderX中创建一个uni-app项目,操作步骤:文件->新建->项目->选择uni-app->点击创建即可。
- 创建js插件文件,可采用下方模板。已兼容5+ 插件开发。
! function(root, factory) { if (typeof exports == 'object' && typeof module != 'undefined') { module.exports = factory() } else if (typeof define == 'function' && define.amd) { define(factory) } else { // 5+ 兼容 document.addEventListener('plusready', function(){ // 修改此处为插件命名 var moduleName = 'plugintest'; // 挂载在plus下 root.plus[moduleName] = factory() },false); } }(this, function() { //在此处定义自己的方法 var _BARCODE = 'plugintest'; var plugintest = { /*方法已忽略,详细方法请参考SDK中的demo*/ }; return plugintest; });
- 插件引用。直接require即可(5+ 项目需使用script标签引入)。详细代码请下载附件,解压至任意目录,拖入HBuilderX即可。
- 生成本地打包资源,导入android studio项目。可参考:HBuilderX 生成本地打包App资源
插件编写
用户可采用同步或异步的方式将结果传递到android端。
同步方法:
void plus.bridge.execSync( String service, String action, Array<String> args ); service: 插件类别名,对应dcloud_properties.xml的feature name。 action: 调用android端插件方法名称。对应java文件的方法名。 args: 参数列表。
异步方法:
void plus.bridge.exec( String service, String action, Array<String> args ); service: 插件类别名,对应dcloud_properties.xml的feature name。 action: 调用android端插件方法名称。对应java文件的方法名。 args: 参数列表。
示例代码
var plugintest = { PluginTestFunction: function(Argus1, Argus2, Argus3, Argus4, successCallback, errorCallback) { var success = typeof successCallback !== 'function' ? null : function(args) { successCallback(args); }, fail = typeof errorCallback !== 'function' ? null : function(code) { errorCallback(code); }; var callbackID = plus.bridge.callbackId(success, fail); return plus.bridge.exec(_BARCODE, "PluginTestFunction", [callbackID, Argus1, Argus2, Argus3, Argus4]); } };
android 扩展插件
导入SDK工程到Android studio
-
下载SDK至任意目录(目录中一定不能含有中文)。
-
将SDK中的HBuilder-Integrate-AS项目导入android studio,操作步骤:Studio ->File ->open ->选择1中解压的目录 ->Ok即可。
-
注意:项目中必须包含lib.5plus.base-release.aar文件。
编写插件
-
创建一个java类继承自StandardFeature(HBuilder-Integrate-AS中的PGPlugintest.java)。
-
实现方法,方法名必须与js方法中windows.plus.bridge.exec()或windows.plus.bridge.execSync()方法的第二个传入参数相同。
-
方法中需存在两个形参,IWebview pWebview代表发起请求的webview,JSONArray array代表JS请求传入的参数。
-
android 执行完操作将数据返回到js层,可采取JSUtil.execCallback()方法实现结果的传递。
JSUtil.execCallback(IWebview pWebViewImpl,String pCallbackId,String pMessage,int pStatus,boolean pKeepCallback) 参数: pWebViewImpl - webview对象 pCallbackId - 回调方法ID pMessage - 回调信息 pStatus - 回调code值 如:OK、ERROR pKeepCallback - js层回调function是否要保存
其余方法可参考Android平台 5+ SDK 参考手册
代码示例
public class PGPlugintest extends StandardFeature { public void PluginTestFunction(IWebview pWebview, JSONArray array) { // 原生代码中获取JS层传递的参数, // 参数的获取顺序与JS层传递的顺序一致 String CallBackID = array.optString(0); JSONArray newArray = new JSONArray(); newArray.put(array.optString(1)); newArray.put(array.optString(2)); newArray.put(array.optString(3)); newArray.put(array.optString(4)); // 调用方法将原生代码的执行结果返回给js层并触发相应的JS层回调函数 JSUtil.execCallback(pWebview, CallBackID, newArray, JSUtil.OK, false); } }
插件配置
- 配置dcloud_properties.xml文件,在features节点下添加如下节点:
<features> <feature name="plugintest" value="com.example.H5PlusPlugin.PGPlugintest"/> </features>
- 配置android studio的build.gradle文件。参考文章:Android平台,uni-app离线打包集成要领及注意事项
- 示例代码在下方附件中下载。

仿uc新闻列表源码分享
<template>
<view class="body">
<view class="tabbar" >
<view class="tabbarlist" >
<view class="tab">
<text>推荐</text>
</view>
<view class="tab">
<text>财经</text>
</view>
<view class="tab">
<text>科技</text>
</view>
<view class="tab">
<text>娱乐</text>
</view>
</view>
</view>
<!-- 数据是第三方的,如果自己的数据最好加一个type,通过type来分类排版,以下我是通过作者判断实现的 更多源码请加群 UniApp开源技术群 757988036 -->
<view class="uni-list">
<view class="uni-list-cell" hover-class="uni-list-cell-hover" v-for="(value,key) in listData" :key="key" @click="goDetail(value)" >
<view class="uni-media-list">
<image :class="[(value.author_name)=='36氪的朋友们' ? 'uni-media-list-logo':'listhide']" :src="value.cover"></image>
<view class="uni-media-list-body">
<view class="uni-media-list-text-top">{{value.title}}</view>
<view class="uni-media-list-text-bottom">
<text :class="[(value.author_name)=='全媒派' ? 'listhide':'']">{{value.author_name}}</text>
<text :class="[(value.author_name)=='36氪的朋友们' ? '':'listhide']" >{{value.published_at}}</text>
<image :class="[(value.author_name)=='全媒派' ? 'list3':'listhide']" :src="value.cover"></image>
<image :class="[(value.author_name)=='全媒派' ? 'list3':'listhide']" :src="value.cover"></image>
<image :class="[(value.author_name)=='全媒派' ? 'list3':'listhide']" :src="value.cover"></image>
</view>
</view>
<image :class="[(value.author_name)!=='36氪的朋友们' && (value.author_name)!=='全媒派' ? 'uni-media-list-logo':'listhide']" :src="value.cover"></image>
</view>
</view>
</view>
</view>
</template>
<script>
var dateUtils = require('../../../common/util.js').dateUtils;
export default {
data() {
return {
listData: [],
last_id: "",
reload: false
}
},
onLoad() {
this.getList();
},
onPullDownRefresh() {
this.reload = true;
this.last_id = "";
this.getList();
},
onReachBottom() {
this.getList();
},
methods: {
getList() {
var data = {
column: "id,post_id,title,author_name,cover,published_at" //需要的字段名
};
if (this.last_id) { //说明已有数据,目前处于上拉加载
data.minId = this.last_id;
data.time = new Date().getTime() + "";
data.pageSize = 10;
}
uni.request({
url: 'https://unidemo.dcloud.net.cn/api/news',
data: data,
success: (data) => {
if (data.statusCode == 200) {
let list = this.setTime(data.data);
this.listData = this.reload ? list : this.listData.concat(list);
this.last_id = list[list.length - 1].id;
this.reload = false;
}
},
fail: (data, code) => {
console.log('fail' + JSON.stringify(data));
}
})
},
goDetail: function (e) {
// if (!/前|刚刚/.test(e.published_at)) {
// e.published_at = dateUtils.format(e.published_at);
// }
let detail = {
author_name: e.author_name,
cover: e.cover,
id: e.id,
post_id: e.post_id,
published_at: e.published_at,
title: e.title
}
uni.navigateTo({
url: "../list2detail-detail/list2detail-detail?detailDate=" + encodeURIComponent(JSON.stringify(detail))
})
},
setTime: function (items) {
var newItems = [];
items.forEach((e) => {
newItems.push({
author_name: e.author_name,
cover: e.cover,
id: e.id,
post_id: e.post_id,
published_at: dateUtils.format(e.published_at),
title: e.title
});
});
return newItems;
}
},
}
</script>
</script>
<style>
.tabbar{width: 100%;height: 100upx; /* border-top: solid #eee 1upx; */ }
.tabbarlist{width: 100%;height: 100upx;position: fixed;background:#ffffff; z-index: 999999;border-bottom: solid #eee 1upx; }
.tabbarlist .tab{width: 20%;height: 100upx;/* background: #007AFF; */float: left;display: block;text-align: center;line-height: 100upx;color: #000;}
.listhide{display: none;}
.listshow{display: block;}
.list3{height: 140upx;margin-left: 4upx;}
.uni-media-list-logo {
width: 180upx;
height: 140upx;
}
.uni-media-list-body {
height: auto;
justify-content: space-around;
}
.uni-media-list-text-top {
height: 74upx;
font-size: 28upx;
overflow: hidden;
}
.uni-media-list-text-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
uniapp开源网http://uniapp.red 欢迎 uniapp开源技术群 757988036
演示地址:http://wx1.sinaimg.cn/mw690/0060lm7Tly1fyapsl1l03j30k00qojtn.jpg
<template>
<view class="body">
<view class="tabbar" >
<view class="tabbarlist" >
<view class="tab">
<text>推荐</text>
</view>
<view class="tab">
<text>财经</text>
</view>
<view class="tab">
<text>科技</text>
</view>
<view class="tab">
<text>娱乐</text>
</view>
</view>
</view>
<!-- 数据是第三方的,如果自己的数据最好加一个type,通过type来分类排版,以下我是通过作者判断实现的 更多源码请加群 UniApp开源技术群 757988036 -->
<view class="uni-list">
<view class="uni-list-cell" hover-class="uni-list-cell-hover" v-for="(value,key) in listData" :key="key" @click="goDetail(value)" >
<view class="uni-media-list">
<image :class="[(value.author_name)=='36氪的朋友们' ? 'uni-media-list-logo':'listhide']" :src="value.cover"></image>
<view class="uni-media-list-body">
<view class="uni-media-list-text-top">{{value.title}}</view>
<view class="uni-media-list-text-bottom">
<text :class="[(value.author_name)=='全媒派' ? 'listhide':'']">{{value.author_name}}</text>
<text :class="[(value.author_name)=='36氪的朋友们' ? '':'listhide']" >{{value.published_at}}</text>
<image :class="[(value.author_name)=='全媒派' ? 'list3':'listhide']" :src="value.cover"></image>
<image :class="[(value.author_name)=='全媒派' ? 'list3':'listhide']" :src="value.cover"></image>
<image :class="[(value.author_name)=='全媒派' ? 'list3':'listhide']" :src="value.cover"></image>
</view>
</view>
<image :class="[(value.author_name)!=='36氪的朋友们' && (value.author_name)!=='全媒派' ? 'uni-media-list-logo':'listhide']" :src="value.cover"></image>
</view>
</view>
</view>
</view>
</template>
<script>
var dateUtils = require('../../../common/util.js').dateUtils;
export default {
data() {
return {
listData: [],
last_id: "",
reload: false
}
},
onLoad() {
this.getList();
},
onPullDownRefresh() {
this.reload = true;
this.last_id = "";
this.getList();
},
onReachBottom() {
this.getList();
},
methods: {
getList() {
var data = {
column: "id,post_id,title,author_name,cover,published_at" //需要的字段名
};
if (this.last_id) { //说明已有数据,目前处于上拉加载
data.minId = this.last_id;
data.time = new Date().getTime() + "";
data.pageSize = 10;
}
uni.request({
url: 'https://unidemo.dcloud.net.cn/api/news',
data: data,
success: (data) => {
if (data.statusCode == 200) {
let list = this.setTime(data.data);
this.listData = this.reload ? list : this.listData.concat(list);
this.last_id = list[list.length - 1].id;
this.reload = false;
}
},
fail: (data, code) => {
console.log('fail' + JSON.stringify(data));
}
})
},
goDetail: function (e) {
// if (!/前|刚刚/.test(e.published_at)) {
// e.published_at = dateUtils.format(e.published_at);
// }
let detail = {
author_name: e.author_name,
cover: e.cover,
id: e.id,
post_id: e.post_id,
published_at: e.published_at,
title: e.title
}
uni.navigateTo({
url: "../list2detail-detail/list2detail-detail?detailDate=" + encodeURIComponent(JSON.stringify(detail))
})
},
setTime: function (items) {
var newItems = [];
items.forEach((e) => {
newItems.push({
author_name: e.author_name,
cover: e.cover,
id: e.id,
post_id: e.post_id,
published_at: dateUtils.format(e.published_at),
title: e.title
});
});
return newItems;
}
},
}
</script>
</script>
<style>
.tabbar{width: 100%;height: 100upx; /* border-top: solid #eee 1upx; */ }
.tabbarlist{width: 100%;height: 100upx;position: fixed;background:#ffffff; z-index: 999999;border-bottom: solid #eee 1upx; }
.tabbarlist .tab{width: 20%;height: 100upx;/* background: #007AFF; */float: left;display: block;text-align: center;line-height: 100upx;color: #000;}
.listhide{display: none;}
.listshow{display: block;}
.list3{height: 140upx;margin-left: 4upx;}
.uni-media-list-logo {
width: 180upx;
height: 140upx;
}
.uni-media-list-body {
height: auto;
justify-content: space-around;
}
.uni-media-list-text-top {
height: 74upx;
font-size: 28upx;
overflow: hidden;
}
.uni-media-list-text-bottom {
display: flex;
flex-direction: row;
justify-content: space-between;
}
</style>
uniapp开源网http://uniapp.red 欢迎 uniapp开源技术群 757988036
演示地址:http://wx1.sinaimg.cn/mw690/0060lm7Tly1fyapsl1l03j30k00qojtn.jpg

base64转amr文件
function dataURL2Audio(fname, base64Str, callback) { //base64转amr文件
var mv = base64Str || '';
if(typeof callback != 'function' || mv == '') return;
fname = fname || ((new Date()).getTime());
fname = (fname.indexOf('.amr') == fname.length - 4) ? fname : fname + '.amr';
var audioName = '_doc/audio/' + fname;
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getFile(audioName, {
create: true
}, function(entry) {
var fullPath = entry.fullPath;
if(mui.os.android) {
var Str = plus.android.importClass("java.lang.String");
var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
try {
var myatb, bstr;
var out = new FileOutputStream(fullPath);
var mystr = atob(mv);
var mlen = mystr.length;
var sstr = '';
while(mlen > 0) {
mysub = mystr.substr(0, 1000);
mystr = mystr.substr(1000);
mlen = mystr.length;
myatb = new Str(mysub);
bstr = myatb.getBytes("ISO8859-1");
out.write(bstr);
}
out.close();
callback && callback(entry); // 回调
} catch(ex) {
console.log('写入失败');
}
} else if(mui.os.ios) {
var NSData = plus.ios.importClass('NSData');
var nsData = new NSData();
nsData = nsData.initWithBase64EncodedStringoptions(mv, 0);
if(nsData) {
nsData.plusCallMethod({
writeToFile: fullPath,
atomically: true
});
plus.ios.deleteObject(nsData);
}
callback && callback(entry); // 回调
}
})
})
}
function dataURL2Audio(fname, base64Str, callback) { //base64转amr文件
var mv = base64Str || '';
if(typeof callback != 'function' || mv == '') return;
fname = fname || ((new Date()).getTime());
fname = (fname.indexOf('.amr') == fname.length - 4) ? fname : fname + '.amr';
var audioName = '_doc/audio/' + fname;
plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
fs.root.getFile(audioName, {
create: true
}, function(entry) {
var fullPath = entry.fullPath;
if(mui.os.android) {
var Str = plus.android.importClass("java.lang.String");
var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
try {
var myatb, bstr;
var out = new FileOutputStream(fullPath);
var mystr = atob(mv);
var mlen = mystr.length;
var sstr = '';
while(mlen > 0) {
mysub = mystr.substr(0, 1000);
mystr = mystr.substr(1000);
mlen = mystr.length;
myatb = new Str(mysub);
bstr = myatb.getBytes("ISO8859-1");
out.write(bstr);
}
out.close();
callback && callback(entry); // 回调
} catch(ex) {
console.log('写入失败');
}
} else if(mui.os.ios) {
var NSData = plus.ios.importClass('NSData');
var nsData = new NSData();
nsData = nsData.initWithBase64EncodedStringoptions(mv, 0);
if(nsData) {
nsData.plusCallMethod({
writeToFile: fullPath,
atomically: true
});
plus.ios.deleteObject(nsData);
}
callback && callback(entry); // 回调
}
})
})
}

iOS离线打包 - LivePusher直播推流插件配置
LivePusher直播推流配置
添加LivePusher直播推流插件
注: Linker Flags、framework添加方法参考该文档
- 依次添加下列Linker Flags: -llibLivePush。
- 添加下列库:
liblibLivePush.a
libDCUniGPUImage.a
"UPLiveSDKDll.framework",
"AVFoundation.framework",
"QuartzCore.framework",
"OpenGLES.framework",
"AudioToolbox.framework",
"VideoToolbox.framework",
"Accelerate.framework",
"CoreMedia.framework",
"CoreTelephony.framework",
"SystemConfiguration.framework",
"CoreMotion.framework",
"libc++.dylib",
"libbz2.1.0.dylib",
"libiconv.dylib",
"libz.dylib"
注意:如果是自定义组件模式下的live-pusher组件,需要再加上libDCUniLivePush.a库
3."UPLiveSDKDll.framework"这个库是动态库并且不支持模拟器,需要添加到如下图所示的地方:
LivePusher直播推流配置
添加LivePusher直播推流插件
注: Linker Flags、framework添加方法参考该文档
- 依次添加下列Linker Flags: -llibLivePush。
- 添加下列库:
liblibLivePush.a
libDCUniGPUImage.a
"UPLiveSDKDll.framework",
"AVFoundation.framework",
"QuartzCore.framework",
"OpenGLES.framework",
"AudioToolbox.framework",
"VideoToolbox.framework",
"Accelerate.framework",
"CoreMedia.framework",
"CoreTelephony.framework",
"SystemConfiguration.framework",
"CoreMotion.framework",
"libc++.dylib",
"libbz2.1.0.dylib",
"libiconv.dylib",
"libz.dylib"
注意:如果是自定义组件模式下的live-pusher组件,需要再加上libDCUniLivePush.a库
3."UPLiveSDKDll.framework"这个库是动态库并且不支持模拟器,需要添加到如下图所示的地方:

【全开源+免费更新】doodoo.js快速入门教程
简介
Doodoo.js -- 中文最佳实践Node.js快速开发框架。支持Koa.js, Express.js中间件,支持模块机制,插件机制,钩子机制,让开发 Node.js 项目更加简单、高效、灵活。
特性
支持koa全部中间件
支持使用 ES6+ 全部特性来开发项目
支持断点调试 ES6+ 项目
支持多种项目结构和多种项目环境
支持 Route, Controller 中使用Koa.js的所有API
支持多级 Controller
支持模块化开发
支持钩子机制
支持插件机制
支持错误处理
支持全局 doodoo 变量
支持 mysql, mongodb 数据库
支持前置,后置操作
支持 Restful 设计
支持启动自定义
支持环境加载配置
...
安装
环境要求:node >= 7.6.0
//npm
npm install doodoo.js --save
//yarn
yarn add doodoo.js
使用 ES6/7 特性来开发项目
//base controller, app/demo/controller/base.js
module.exports = class extends doodoo.Controller {
async _initialize() {
console.log('base _initialize');
}
async isLogin() {
console.log('base isLogin');
}
}
//index controller, app/demo/controller/index.js
const base = require('./base');
module.exports = class extends base {
async _initialize() {
await super._initialize();
}
async index() {
this.success("Hello Doodoo.js");
}
async index2() {
this.fail("Hello Doodoo.js");
}
}
详细的日志
服务 启动日志
[doodoo] Version: 2.0.0
[doodoo] Website: 127.0.0.1
[doodoo] Nodejs Version: v8.12.0
[doodoo] Nodejs Platform: darwin x64
[doodoo] Server Enviroment: development
[doodoo] Server Startup Time: 212ms
[doodoo] Server Current Time: 2018-08-21 11:17:19
[doodoo] Server Running At: http://127.0.0.1:3000
HTTP 请求日志
<-- GET /demo/index/index
--> GET /demo/index/index 200 4ms
doodoo.js官方文档:https://doodooke.github.io/doodoo.js/#/
【案例】多多客小程序官网:doodooke.com
简介
Doodoo.js -- 中文最佳实践Node.js快速开发框架。支持Koa.js, Express.js中间件,支持模块机制,插件机制,钩子机制,让开发 Node.js 项目更加简单、高效、灵活。
特性
支持koa全部中间件
支持使用 ES6+ 全部特性来开发项目
支持断点调试 ES6+ 项目
支持多种项目结构和多种项目环境
支持 Route, Controller 中使用Koa.js的所有API
支持多级 Controller
支持模块化开发
支持钩子机制
支持插件机制
支持错误处理
支持全局 doodoo 变量
支持 mysql, mongodb 数据库
支持前置,后置操作
支持 Restful 设计
支持启动自定义
支持环境加载配置
...
安装
环境要求:node >= 7.6.0
//npm
npm install doodoo.js --save
//yarn
yarn add doodoo.js
使用 ES6/7 特性来开发项目
//base controller, app/demo/controller/base.js
module.exports = class extends doodoo.Controller {
async _initialize() {
console.log('base _initialize');
}
async isLogin() {
console.log('base isLogin');
}
}
//index controller, app/demo/controller/index.js
const base = require('./base');
module.exports = class extends base {
async _initialize() {
await super._initialize();
}
async index() {
this.success("Hello Doodoo.js");
}
async index2() {
this.fail("Hello Doodoo.js");
}
}
详细的日志
服务 启动日志
[doodoo] Version: 2.0.0
[doodoo] Website: 127.0.0.1
[doodoo] Nodejs Version: v8.12.0
[doodoo] Nodejs Platform: darwin x64
[doodoo] Server Enviroment: development
[doodoo] Server Startup Time: 212ms
[doodoo] Server Current Time: 2018-08-21 11:17:19
[doodoo] Server Running At: http://127.0.0.1:3000
HTTP 请求日志
<-- GET /demo/index/index
--> GET /demo/index/index 200 4ms
doodoo.js官方文档:https://doodooke.github.io/doodoo.js/#/
【案例】多多客小程序官网:doodooke.com