
iOS 离线SDK集成示例
说明
本示例工程实现了从原生页面跳转 uniapp
页面,然后在 uniapp
页面中通过调用原生扩展 Module
插件的方法在跳转回原生页面,希望对那些想在现有原生工程中集成uni-app
的用户有所帮助;
运行方式
- 下载原生离线sdk,并解压;
- 将本帖子中的附件下载,并解压放到离线sdk的根目录中;
- 直接运行
HBuilder-Integrate.xcodeproj
即可;
效果
欢迎讨论
下载工程
说明
本示例工程实现了从原生页面跳转 uniapp
页面,然后在 uniapp
页面中通过调用原生扩展 Module
插件的方法在跳转回原生页面,希望对那些想在现有原生工程中集成uni-app
的用户有所帮助;
运行方式
- 下载原生离线sdk,并解压;
- 将本帖子中的附件下载,并解压放到离线sdk的根目录中;
- 直接运行
HBuilder-Integrate.xcodeproj
即可;
效果
欢迎讨论
下载工程
收起阅读 »
HBuilderx打包iOS教程
HBuilderx使用自有证书打包打包iOS需要两个iOS证书文件p12和.mobileprovision
如果还没这两个文件先申请!
HBuilder在线打包iOS步骤
1、打开HBuilder工具,选择完工的项目,点击发行,选择发行为原生安装包。
2、选择iOS打包,支持的设备类型(可以选择支持iPhone和支持ipad),选择使用苹果证书
AppID:跟申请证书描述.mobileprovision时选择的要一致(又称套装id,appid,BundleID,应用id,包名)
profile文件:选择上传配置文件.mobileprovision
私钥证书:上传.p12文件
私钥密码:输入创建p12设置的密码。
然后点击打包。
3、打包成功后,下载保存ipa,这个ipa包就能安装到手机测试了。
HBuilderx使用自有证书打包打包iOS需要两个iOS证书文件p12和.mobileprovision
如果还没这两个文件先申请!
HBuilder在线打包iOS步骤
1、打开HBuilder工具,选择完工的项目,点击发行,选择发行为原生安装包。
2、选择iOS打包,支持的设备类型(可以选择支持iPhone和支持ipad),选择使用苹果证书
AppID:跟申请证书描述.mobileprovision时选择的要一致(又称套装id,appid,BundleID,应用id,包名)
profile文件:选择上传配置文件.mobileprovision
私钥证书:上传.p12文件
私钥密码:输入创建p12设置的密码。
然后点击打包。
3、打包成功后,下载保存ipa,这个ipa包就能安装到手机测试了。

使用本地iconfont阿里字体图标 无需转换base64
1.首先登陆iconfont官网,创建自己的项目,找到需要的图标加入购物车,然后添加到项目中
2.生成unicode ,点击下载至本地,解压
3.将解压后的文件放入static目录
4.修改为本地引入方式

5.使用时在App.vue中全局引入该文件@import "./common/iconfont.css";(根据该文件路径),即可以在各页面中使用
6.使用方法
(1).使用class渲染图标
(2).使用字体编码
1.首先登陆iconfont官网,创建自己的项目,找到需要的图标加入购物车,然后添加到项目中
2.生成unicode ,点击下载至本地,解压
3.将解压后的文件放入static目录
4.修改为本地引入方式
5.使用时在App.vue中全局引入该文件@import "./common/iconfont.css";(根据该文件路径),即可以在各页面中使用
6.使用方法
(1).使用class渲染图标
(2).使用字体编码

【分享】苹果App上架App Store注意事项,避免被拒!
iOS APP上架审核比较严格!
这里整理了iOS上架需要注意的事项,上架前尽量避免,争取一次提交审核成功,被拒打回重新修改提交审核会耗费很多时间!
1、应用内包含检查更新功能iOS 应用的版本更新必须通过 App Store 进行,自身 App 内不能包含提示更新功能。从2015年3月起,所有包含检查更新功能的 App 都会被拒绝上架。
2、使用第三方登录时未做安装检测接入第三方登录要检测是否安装了第三方客户端,未安装时不要显示对应按钮。2015年9月之前,通常可以采用判断未安装则隐藏登录按钮的方式。但目前隐藏按钮的方式也可能被审核拒绝,QQ 和微博提供了 web 登录的方式,如果判断未安装,需要允许用户使用 webview 的登录方式。苹果在条款中有声明不允许 iOS 应用的正常使用需要依赖另外一个 App。
3、采集设备IDFA但应用没有广告功能从2014年2月起,Apple 开始拒绝采集 IDFA (identifier for advertising) 却未集成任何广告服务的应用进入 App Store。如果 App 本身没有广告,ASO100.com 建议可以在审核的时候显示一个 Banner 广告,并且放在比较明显的位置,审核通过后关掉即可。
4、含UGC却未提供用户协议及举报功能如果你的 App 内有发帖等UGC(用户产生内容)功能,必须提供用户协议,并留有内容举报功能,否则就会被审核拒绝。
5、上传时没有使用真实的应用截图应用程序的名称、描述、截图或者预览与应用的内容和功能不相关将会被拒绝。有 App 因为应用截图使用的是自己设计的插画而被审核拒绝。
6、应用必须使用邀请码才能注册使用苹果要求应用不能限制只有部分用户可以使用。
7、应用内出现第三方移动平台的名字或图标一直以来,苹果都不允许iOS开发者在进行软件描述时提到 Android 版本,而自从2015年4月起,在 App 内、截图等任何地方提到安卓、Android 的文字、图标、系统界面都会被拒。曾经有电商 App,因为出现了售卖三星安卓手机而被拒。。。
8、应用内涉及奖励,未声明与苹果无关App 里有实物奖励的话,不能使用苹果产品(例如 iPhone 、iPad 等)作为奖品。另外一定要声明“奖励由本公司提供,与苹果官方无关”。
9、没有提供恢复内购的方法增加一个“恢复购买记录”的按钮即可。
10、未注册时不能使用与账号无关的功能对于资讯等 App,在没有进行与用户信息相关的操作时,却强行让用户登录,甚至不登录就无法看到任何内容,有可能会被拒绝。
11、iPhone 应用在 iPad 上不能正常显示iPhone程序必须不经修改就能以iPhone分辨率和2倍iPhone 3GS的分辨率在iPad上运行。即使你的App 只为 iPhone 用户提供,在 iPad 上也必须能够正常显示,否则审核会被拒绝。
12、侵犯第三方版权对于视频、音乐、图书类的应用很容易因为这一条而被拒。另外 ASO100.com 建议应用内最好不要出现第三方的商标,例如运营商的Logo、影视公司的 Logo 等。13、应用截图、名称、描述等出现不雅词汇在应用截图、名称、描述等任何地方出现例如诸如 牛逼、绿茶婊、无节操、逗比 等词汇,都会被苹果审核拒绝。
14、应用出现 beta版、测试版字样不要过度谦虚地在启动画面或者应用名称上加上”beta”字样,苹果不允许测试版产品上架。
15、注册缺少隐私政策如果应用包含注册功能,注册页面必须提供隐私说明协议按钮或者链接。另外在 iTunes connect 提交新版本的时候,Privacy Policy URL 必须要填写。
16、应用出现崩溃、加载失败等 bug审核期间出现崩溃会导致审核被拒。ASO100.com 建议,在审核期间务必保证服务器稳定,避免审核人员审核时出现内容加载失败的情况,导致被拒。
17、应用描述、截图和应用功能不符如果应用的描述或截图介绍的功能在审核期间没有体现,则会被拒绝,如果介绍文案不够详细也会有一定概率被拒。
18、应用包含应用推荐功能除特殊情况,苹果明令禁止应用内推荐其他APP。
19、应用包含不正确的诊断功能如果你的应用中,包含不真实的系统检测或优化功能,苹果会认为这项功能有误导用户的嫌疑,审核时会被拒绝。
20、应用提交的新版本与上一版差异过大如果你提交的新版本应用与上一版相比,功能上变化过大,比如将游戏升级为工具类应用,或在新版本中完全改掉前一版产品的功能,则会被苹果拒绝。
iOS APP上架审核比较严格!
这里整理了iOS上架需要注意的事项,上架前尽量避免,争取一次提交审核成功,被拒打回重新修改提交审核会耗费很多时间!
1、应用内包含检查更新功能iOS 应用的版本更新必须通过 App Store 进行,自身 App 内不能包含提示更新功能。从2015年3月起,所有包含检查更新功能的 App 都会被拒绝上架。
2、使用第三方登录时未做安装检测接入第三方登录要检测是否安装了第三方客户端,未安装时不要显示对应按钮。2015年9月之前,通常可以采用判断未安装则隐藏登录按钮的方式。但目前隐藏按钮的方式也可能被审核拒绝,QQ 和微博提供了 web 登录的方式,如果判断未安装,需要允许用户使用 webview 的登录方式。苹果在条款中有声明不允许 iOS 应用的正常使用需要依赖另外一个 App。
3、采集设备IDFA但应用没有广告功能从2014年2月起,Apple 开始拒绝采集 IDFA (identifier for advertising) 却未集成任何广告服务的应用进入 App Store。如果 App 本身没有广告,ASO100.com 建议可以在审核的时候显示一个 Banner 广告,并且放在比较明显的位置,审核通过后关掉即可。
4、含UGC却未提供用户协议及举报功能如果你的 App 内有发帖等UGC(用户产生内容)功能,必须提供用户协议,并留有内容举报功能,否则就会被审核拒绝。
5、上传时没有使用真实的应用截图应用程序的名称、描述、截图或者预览与应用的内容和功能不相关将会被拒绝。有 App 因为应用截图使用的是自己设计的插画而被审核拒绝。
6、应用必须使用邀请码才能注册使用苹果要求应用不能限制只有部分用户可以使用。
7、应用内出现第三方移动平台的名字或图标一直以来,苹果都不允许iOS开发者在进行软件描述时提到 Android 版本,而自从2015年4月起,在 App 内、截图等任何地方提到安卓、Android 的文字、图标、系统界面都会被拒。曾经有电商 App,因为出现了售卖三星安卓手机而被拒。。。
8、应用内涉及奖励,未声明与苹果无关App 里有实物奖励的话,不能使用苹果产品(例如 iPhone 、iPad 等)作为奖品。另外一定要声明“奖励由本公司提供,与苹果官方无关”。
9、没有提供恢复内购的方法增加一个“恢复购买记录”的按钮即可。
10、未注册时不能使用与账号无关的功能对于资讯等 App,在没有进行与用户信息相关的操作时,却强行让用户登录,甚至不登录就无法看到任何内容,有可能会被拒绝。
11、iPhone 应用在 iPad 上不能正常显示iPhone程序必须不经修改就能以iPhone分辨率和2倍iPhone 3GS的分辨率在iPad上运行。即使你的App 只为 iPhone 用户提供,在 iPad 上也必须能够正常显示,否则审核会被拒绝。
12、侵犯第三方版权对于视频、音乐、图书类的应用很容易因为这一条而被拒。另外 ASO100.com 建议应用内最好不要出现第三方的商标,例如运营商的Logo、影视公司的 Logo 等。13、应用截图、名称、描述等出现不雅词汇在应用截图、名称、描述等任何地方出现例如诸如 牛逼、绿茶婊、无节操、逗比 等词汇,都会被苹果审核拒绝。
14、应用出现 beta版、测试版字样不要过度谦虚地在启动画面或者应用名称上加上”beta”字样,苹果不允许测试版产品上架。
15、注册缺少隐私政策如果应用包含注册功能,注册页面必须提供隐私说明协议按钮或者链接。另外在 iTunes connect 提交新版本的时候,Privacy Policy URL 必须要填写。
16、应用出现崩溃、加载失败等 bug审核期间出现崩溃会导致审核被拒。ASO100.com 建议,在审核期间务必保证服务器稳定,避免审核人员审核时出现内容加载失败的情况,导致被拒。
17、应用描述、截图和应用功能不符如果应用的描述或截图介绍的功能在审核期间没有体现,则会被拒绝,如果介绍文案不够详细也会有一定概率被拒。
18、应用包含应用推荐功能除特殊情况,苹果明令禁止应用内推荐其他APP。
19、应用包含不正确的诊断功能如果你的应用中,包含不真实的系统检测或优化功能,苹果会认为这项功能有误导用户的嫌疑,审核时会被拒绝。
20、应用提交的新版本与上一版差异过大如果你提交的新版本应用与上一版相比,功能上变化过大,比如将游戏升级为工具类应用,或在新版本中完全改掉前一版产品的功能,则会被苹果拒绝。
收起阅读 »
解决mui.ajax使用FormData方式上传图片无法接收参数的问题
以前图片上传一直采用的图片压缩后上传base64字符串的方式,没有任何问题,最近的一个项目跟其他端是公用的接口,必须使用input file文件上传图片,结果接口各种接收不到formData append的参数,论坛各种搜都是说放弃file上传方式,最后采用原生XMLHttpRequest上传终于可以了。代码如下:
var xhr = new XMLHttpRequest();
var formData = new FormData();
formData.append('file', file);
formData.append('openId', localStorage.openId);
formData.append('provider', 'app');
xhr.open('POST', URL + 'mobileshopapi/Common/PostUploadImage', true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var res = JSON.parse(xhr.responseText)
}
}
xhr.send(formData);
以前图片上传一直采用的图片压缩后上传base64字符串的方式,没有任何问题,最近的一个项目跟其他端是公用的接口,必须使用input file文件上传图片,结果接口各种接收不到formData append的参数,论坛各种搜都是说放弃file上传方式,最后采用原生XMLHttpRequest上传终于可以了。代码如下:
var xhr = new XMLHttpRequest();
var formData = new FormData();
formData.append('file', file);
formData.append('openId', localStorage.openId);
formData.append('provider', 'app');
xhr.open('POST', URL + 'mobileshopapi/Common/PostUploadImage', true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var res = JSON.parse(xhr.responseText)
}
}
xhr.send(formData);
收起阅读 »

使用mix-mall为模板的商城Api终于诞生了
先贴代码
https://gitee.com/iotechn/unimall
使用SpringBoot + MyBatis-plus作为基础框架。
支持单机部署、集群部署,不用担心性能扩展了!!
完全面向服务开发,方便以后重构微服务。
在此非常感谢MixR大神!!
先贴代码
https://gitee.com/iotechn/unimall
使用SpringBoot + MyBatis-plus作为基础框架。
支持单机部署、集群部署,不用担心性能扩展了!!
完全面向服务开发,方便以后重构微服务。
在此非常感谢MixR大神!!
收起阅读 »
解决 HBuilderX + UniApp + Ts + 父组件Prop 在微信小程序中 无法绑定的 BUG;
项目转到 TS 以后,基本就没有使用过 Js 了。。所以下面的所有代码都使用 TS 作为说明; (PS.,我的项目的 ts 和 vue 是分开的)。
父组件 BaseUniComponent.ts 就是定义了一个 父组件中的 prop
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
export default class BaseUniComponent extends Vue{
@Prop({ default: null})
propInParent: null | string;
}
子组件 UserMoneyDetail.ts (继承子父组件,并且定义了一个子组件内的 prop)
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import BaseUniComponent from './Basic/BaseUniComponent';
@Component({})
export default class UserIncome extends BaseUniComponent {
@Prop({default: null})
propInComponent: null | string;
}
子组件页面: UserMoneyDetail.vue ( 显示传入进来的 prop 的值)
<template>
<view class="content">
<view>propInComponent: {{propInComponent}}</view>
<view>propInParent: {{propInParent}}</view>
</view>
</template>
<script lang="ts" src='./UserMoneyDetail.ts'></script>
入口页面 unientry.ts
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import UserMoney from './UserMoneyDetail.vue';
@Component({
components: {
UserMoney
}
})
export default class index extends Vue {
title: string = 'Hello';
}
入口页面 unientry.vue (分别绑定了定义在子组件内部的 prop 和 子组件继承自父类的 prop)
<template>
<view>
<UserMoney :propInComponent='title' :propInParent='title'></UserMoney>
</view>
</template>
<script lang="ts" src='./unientry.ts'></script>
在 h5 中这个毫无疑问正常,会显示 2个 Hello,
但是,编译到微信小程序中,却只会显示一个 Hello; ( 我的版本 , HBuilder X 2.2.2.20190816, )
最终发现一个是 HBuilder x 将代码编译成 微信小程序的问题, 也就是 uni-mp-weixin/dist/index.js 编译时,会丢失从父类继承过来的 prop 的定义;
此文件中第 682行定义了如下函数:
function initVueComponent (Vue, vueOptions) {
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
根据 vue.d.ts , 我没有找到 extendOptions 的任何说明,估计是一个未公开的属性吧;
但是 VueComponent.extendOptions 这个属性里面不包含有继承自父类的 Prop,这也就使得,后面在根据返回的 vueOptions 去创建 Vue 的实例时,也丢失了从父类继承而来的 Prop, 进而使得在 unientry.vue 中 :propInParent='title' 无法绑定子组件继承子父组件的 Prop;
问题找到,改正倒是非常简单。 修改 initVueComponent 的函数定义就可以了;
function initVueComponent (Vue, vueOptions) {
let inputVueOptions = vueOptions; //方便调试
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
//#region 往 vueOptions 中补充定义在父组件中但未定义在子组件中的 prop
let defaultInputVueOptions = inputVueOptions['default'];
if (defaultInputVueOptions && defaultInputVueOptions.options && defaultInputVueOptions.options.props) {
if (!vueOptions.props) vueOptions.props = {};
let propsInDefaultInputVueOptions = defaultInputVueOptions.options.props;
for (var oneProp in propsInDefaultInputVueOptions) {
if (!vueOptions.props[oneProp]) {
vueOptions.props[oneProp] = propsInDefaultInputVueOptions[oneProp];
}
}
}
//#endregion
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
编译到微信小程序中,显示正常( 我的版本 , HBuilder X 2.2.2.20190816, )
顺带做了一个项目模板: https://github.com/hesi726/HBuildX-UniApp-Ts-Template
项目转到 TS 以后,基本就没有使用过 Js 了。。所以下面的所有代码都使用 TS 作为说明; (PS.,我的项目的 ts 和 vue 是分开的)。
父组件 BaseUniComponent.ts 就是定义了一个 父组件中的 prop
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
export default class BaseUniComponent extends Vue{
@Prop({ default: null})
propInParent: null | string;
}
子组件 UserMoneyDetail.ts (继承子父组件,并且定义了一个子组件内的 prop)
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import BaseUniComponent from './Basic/BaseUniComponent';
@Component({})
export default class UserIncome extends BaseUniComponent {
@Prop({default: null})
propInComponent: null | string;
}
子组件页面: UserMoneyDetail.vue ( 显示传入进来的 prop 的值)
<template>
<view class="content">
<view>propInComponent: {{propInComponent}}</view>
<view>propInParent: {{propInParent}}</view>
</view>
</template>
<script lang="ts" src='./UserMoneyDetail.ts'></script>
入口页面 unientry.ts
import { Component, Emit, Prop, Vue } from "vue-property-decorator";
import UserMoney from './UserMoneyDetail.vue';
@Component({
components: {
UserMoney
}
})
export default class index extends Vue {
title: string = 'Hello';
}
入口页面 unientry.vue (分别绑定了定义在子组件内部的 prop 和 子组件继承自父类的 prop)
<template>
<view>
<UserMoney :propInComponent='title' :propInParent='title'></UserMoney>
</view>
</template>
<script lang="ts" src='./unientry.ts'></script>
在 h5 中这个毫无疑问正常,会显示 2个 Hello,
但是,编译到微信小程序中,却只会显示一个 Hello; ( 我的版本 , HBuilder X 2.2.2.20190816, )
最终发现一个是 HBuilder x 将代码编译成 微信小程序的问题, 也就是 uni-mp-weixin/dist/index.js 编译时,会丢失从父类继承过来的 prop 的定义;
此文件中第 682行定义了如下函数:
function initVueComponent (Vue, vueOptions) {
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
根据 vue.d.ts , 我没有找到 extendOptions 的任何说明,估计是一个未公开的属性吧;
但是 VueComponent.extendOptions 这个属性里面不包含有继承自父类的 Prop,这也就使得,后面在根据返回的 vueOptions 去创建 Vue 的实例时,也丢失了从父类继承而来的 Prop, 进而使得在 unientry.vue 中 :propInParent='title' 无法绑定子组件继承子父组件的 Prop;
问题找到,改正倒是非常简单。 修改 initVueComponent 的函数定义就可以了;
function initVueComponent (Vue, vueOptions) {
let inputVueOptions = vueOptions; //方便调试
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
//#region 往 vueOptions 中补充定义在父组件中但未定义在子组件中的 prop
let defaultInputVueOptions = inputVueOptions['default'];
if (defaultInputVueOptions && defaultInputVueOptions.options && defaultInputVueOptions.options.props) {
if (!vueOptions.props) vueOptions.props = {};
let propsInDefaultInputVueOptions = defaultInputVueOptions.options.props;
for (var oneProp in propsInDefaultInputVueOptions) {
if (!vueOptions.props[oneProp]) {
vueOptions.props[oneProp] = propsInDefaultInputVueOptions[oneProp];
}
}
}
//#endregion
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
编译到微信小程序中,显示正常( 我的版本 , HBuilder X 2.2.2.20190816, )
顺带做了一个项目模板: https://github.com/hesi726/HBuildX-UniApp-Ts-Template
收起阅读 »
MUI-POPOVER中加入mui-scroll无法滚动的问题
MUI-POPOVER中加入mui-scroll无法滚动的问题
最近遇到个需求,需要在mui-popover弹出框中加入列表并且有分页,所以就用了mui的上拉加载和下拉刷新,结果发现mui-scroll在mui-popover中不能滑动,经过查询资料得知,mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动)。
最后在mui.js中注市调如下代码就没问题了
参考文章
修改方法:
var onPopoverShown = function(e) {
this.removeEventListener('webkitTransitionEnd', onPopoverShown);
// 发现说是mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动),注释掉下面这段就好了
// this.addEventListener($.EVENT_MOVE, $.preventDefault);
$.trigger(this, 'shown', this);
}
MUI-POPOVER中加入mui-scroll无法滚动的问题
最近遇到个需求,需要在mui-popover弹出框中加入列表并且有分页,所以就用了mui的上拉加载和下拉刷新,结果发现mui-scroll在mui-popover中不能滑动,经过查询资料得知,mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动)。
最后在mui.js中注市调如下代码就没问题了
参考文章
修改方法:
var onPopoverShown = function(e) {
this.removeEventListener('webkitTransitionEnd', onPopoverShown);
// 发现说是mui.js将popover里的touchmove事件给拦截了,所以内容是不允许滑动(滚动),注释掉下面这段就好了
// this.addEventListener($.EVENT_MOVE, $.preventDefault);
$.trigger(this, 'shown', this);
}
收起阅读 »

在 WebStorm 中开发 uni-app
CLI 工程
全局安装 vue-cli 3.x(如已安装请跳过此步骤)
npm install -g @vue/cli
通过 CLI 创建 uni-app 项目
vue create -p dcloudio/uni-preset-vue my-project
此时,会提示选择项目模板,初次体验建议选择 hello uni-app
项目模板,如下所示:
<div>
<img src="http://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/h5-cli-01.png" width="300">
</div>
在 WebStorm 中打开项目
CLI 工程默认带了 uni-app 语法提示和 5+App 语法提示
运行项目
npm run dev:%PLATFORM%
发布项目
npm run build:%PLATFORM%
%PLATFORM%
可取值如下:
值 | 平台 |
---|---|
h5 | H5 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
mp-weixin | 微信小程序 |
mp-toutiao | 头条小程序 |
mp-qq | qq 小程序 |
HBuilderX 工程
HBuilderX 创建的工程默认不带 types 语法提示,在 WebStorm 中编辑的时候,可以自行安装
初始化npm(如已初始化跳过此步骤)
npm init -y
安装 uni-app 语法提示
npm i @dcloudio/types -D
注意
webstorm不识别rpx等单位
如果想了解HBuilderX为uni-app做了什么更好的优化,参考:https://ask.dcloud.net.cn/article/35451
CLI 工程
全局安装 vue-cli 3.x(如已安装请跳过此步骤)
npm install -g @vue/cli
通过 CLI 创建 uni-app 项目
vue create -p dcloudio/uni-preset-vue my-project
此时,会提示选择项目模板,初次体验建议选择 hello uni-app
项目模板,如下所示:
<div>
<img src="http://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/h5-cli-01.png" width="300">
</div>
在 WebStorm 中打开项目
CLI 工程默认带了 uni-app 语法提示和 5+App 语法提示
运行项目
npm run dev:%PLATFORM%
发布项目
npm run build:%PLATFORM%
%PLATFORM%
可取值如下:
值 | 平台 |
---|---|
h5 | H5 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
mp-weixin | 微信小程序 |
mp-toutiao | 头条小程序 |
mp-qq | qq 小程序 |
HBuilderX 工程
HBuilderX 创建的工程默认不带 types 语法提示,在 WebStorm 中编辑的时候,可以自行安装
初始化npm(如已初始化跳过此步骤)
npm init -y
安装 uni-app 语法提示
npm i @dcloudio/types -D
注意
webstorm不识别rpx等单位
如果想了解HBuilderX为uni-app做了什么更好的优化,参考:https://ask.dcloud.net.cn/article/35451
收起阅读 »
uniapp安卓缓存计算、缓存清理
官方有个未显示的文档http://www.html5plus.org/doc/zh_cn/cache.html用于管理应用缓存
但有些方法在uniapp上报错
感谢二位大佬提供的文章
师大酸梅杨
https://ask.dcloud.net.cn/article/1191
绝地求生
https://ask.dcloud.net.cn/article/13375
通过两位大佬的文章结合做出一个在uniapp安卓系统上可以计算缓存和清理缓存的代码,ios上可以计算但未找到获取缓存路径的方法,希望官方给出方案
计算缓存大小方法
formatSize() {
let that = this;
plus.cache.calculate(function(size) {
let sizeCache = parseInt(size);
if (sizeCache == 0) {
that.fileSizeString = "0B";
} else if (sizeCache < 1024) {
that.fileSizeString = sizeCache + "B";
} else if (sizeCache < 1048576) {
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
} else if (sizeCache < 1073741824) {
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
} else {
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
}
});
}
安卓清理缓存方法
clearCache() {
let that = this;
let os = plus.os.name;
if (os == 'Android') {
let main = plus.android.runtimeMainActivity();
let sdRoot = main.getCacheDir();
let files = plus.android.invoke(sdRoot, "listFiles");
let len = files.length;
for (let i = 0; i < len; i++) {
let filePath = '' + files[i]; // 没有找到合适的方法获取路径,这样写可以转成文件路径
plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
if (entry.isDirectory) {
entry.removeRecursively(function(entry) { //递归删除其下的所有文件及子目录
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize(); // 重新计算缓存
}, function(e) {
console.log(e.message)
});
} else {
entry.remove();
}
}, function(e) {
console.log('文件路径读取失败')
});
}
} else { // ios暂时未找到清理缓存的方法,以下是官方提供的方法,但是无效,会报错
plus.cache.clear(function() {
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize();
});
}
}
官方有个未显示的文档http://www.html5plus.org/doc/zh_cn/cache.html用于管理应用缓存
但有些方法在uniapp上报错
感谢二位大佬提供的文章
师大酸梅杨
https://ask.dcloud.net.cn/article/1191
绝地求生
https://ask.dcloud.net.cn/article/13375
通过两位大佬的文章结合做出一个在uniapp安卓系统上可以计算缓存和清理缓存的代码,ios上可以计算但未找到获取缓存路径的方法,希望官方给出方案
计算缓存大小方法
formatSize() {
let that = this;
plus.cache.calculate(function(size) {
let sizeCache = parseInt(size);
if (sizeCache == 0) {
that.fileSizeString = "0B";
} else if (sizeCache < 1024) {
that.fileSizeString = sizeCache + "B";
} else if (sizeCache < 1048576) {
that.fileSizeString = (sizeCache / 1024).toFixed(2) + "KB";
} else if (sizeCache < 1073741824) {
that.fileSizeString = (sizeCache / 1048576).toFixed(2) + "MB";
} else {
that.fileSizeString = (sizeCache / 1073741824).toFixed(2) + "GB";
}
});
}
安卓清理缓存方法
clearCache() {
let that = this;
let os = plus.os.name;
if (os == 'Android') {
let main = plus.android.runtimeMainActivity();
let sdRoot = main.getCacheDir();
let files = plus.android.invoke(sdRoot, "listFiles");
let len = files.length;
for (let i = 0; i < len; i++) {
let filePath = '' + files[i]; // 没有找到合适的方法获取路径,这样写可以转成文件路径
plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
if (entry.isDirectory) {
entry.removeRecursively(function(entry) { //递归删除其下的所有文件及子目录
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize(); // 重新计算缓存
}, function(e) {
console.log(e.message)
});
} else {
entry.remove();
}
}, function(e) {
console.log('文件路径读取失败')
});
}
} else { // ios暂时未找到清理缓存的方法,以下是官方提供的方法,但是无效,会报错
plus.cache.clear(function() {
uni.showToast({
title: '缓存清理完成',
duration: 2000
});
that.formatSize();
});
}
}
收起阅读 »