登入模板的内部没有办法使用<map>标签
在其他的模板使用<map>没有问题,但是在新建项目的登入模板内使用map,会出现白屏的问题
在其他的模板使用<map>没有问题,但是在新建项目的登入模板内使用map,会出现白屏的问题
基于thinkCMF5.1和uni-app开发的uniCMF,帮助开发者快速构建WEB,APP和小程序应用。
源码地址:https://www.thinkcmf.com/appstore/theme/45.html
课程地址:http://www.3mooc.com/front/couinfo/527
uniapp免费课程(1块钱是平台推广费用)已经发布,源码价格5月10日开始提升到50元(现在20元),买了源码的同学提供后续的更新和指导!
前台演示地址:http://hrai.online (PC端自行切换手机模式)
后台演示地址:http://hrai.online/admin。
目前正在考虑是否需要录制教程,或者直接用文档模式。
现已完成的功能有:
**轮播图,文章搜索
上拉加载,下拉刷新
获取文章列表,分类列表
用户登录,注册,找回密码,微信小程序登录
绑定手机,邮箱,短信验证码,邮箱验证码
文章收藏,点赞,评论,分享(小程序)
修改个人信息,用户发布文章**
持续更新中。。。
uniCMF完全遵循cmfapi手册规范,开发者可以直接复制手册上的api或代码使用。
api手册地址:
https://www.thinkcmf.com/cmf5api.html
uni-app文档地址:
https://uniapp.dcloud.io/
源码地址:https://www.thinkcmf.com/appstore/theme/45.html
课程地址:http://www.3mooc.com/front/couinfo/527
uniapp免费课程(1块钱是平台推广费用)已经发布,源码价格5月10日开始提升到50元(现在20元),买了源码的同学提供后续的更新和指导!
前台演示地址:http://hrai.online (PC端自行切换手机模式)
后台演示地址:http://hrai.online/admin。
目前正在考虑是否需要录制教程,或者直接用文档模式。
现已完成的功能有:
**轮播图,文章搜索
上拉加载,下拉刷新
获取文章列表,分类列表
用户登录,注册,找回密码,微信小程序登录
绑定手机,邮箱,短信验证码,邮箱验证码
文章收藏,点赞,评论,分享(小程序)
修改个人信息,用户发布文章**
持续更新中。。。
uniCMF完全遵循cmfapi手册规范,开发者可以直接复制手册上的api或代码使用。
api手册地址:
https://www.thinkcmf.com/cmf5api.html
uni-app文档地址:
https://uniapp.dcloud.io/
收起阅读 »SQLite云端打包配置说明
HBuilderX 1.7.2及以上版本支持SQLite操作db文件。
概述
SQLite是一种嵌入式数据库,本质上就是一个数据库文件(.db)。是无服务器的、零配置的、事务性的简单轻量级SQL数据库引擎。
通常在移动设备上适合不需要高并发量的本地数据存储。
SQLite API使用
plus.sqlite已经封装好操作db数据库文件接口,按以下方法调用即可。
在uni-app中可使用条件编译直接调用5+ Push接口
打开数据库
使用前需调用plus.sqlite.openDatabase打开数据库,必须指定数据库文件路径(.db)和数据库名称。
数据库文件路径使用需注意以下问题:
应用资源目录中的文件只可读,在使用相对路径(如"./x.db")或5+API路径RelativeURL的应用资源目录(如"_www/x.db")时不能写入保存数据。通常可以将一些应用的初始数据作为资源内置到应用中,在业务逻辑中进行读取操作。
如果需要在应用的业务逻辑产生的数据保存,应该将数据库文件保存在可写目录中,推荐使用5+API路径的应用私有文档目录(如"_doc/x.db"),此目录中的文件是可读可写,并且应用热更新时不会影响此目录中的文件。
数据库文件路径只可读时,如果文件不存在打开数据库则会失败;数据库文件路径可读可写时,如果文件不存在则自动创建数据库文件。
注意:Android平台目前已知数据库文件不存在时不会自动创建(此问题会在HBuilderX1.8.1版本修复),临时解决方法是先创建不存在的文件,示例如下:
document.addEventListener('plusready', function(e){
// 确保_doc/test.db文件存在
plus.io.requestFileSystem( plus.io.PRIVATE_DOC, function(fs){
fs.root.getFile('test.db', {create:true}, function(fileEntry){
console.log('ensure test.db file!');
});
});
}, false);
// 打开数据库
function openDB(){
outSet('打开数据库: ');
plus.sqlite.openDatabase({
name: 'first',
path: '_doc/test.db',
success: function(e){
console.log(JSON.stringify(e));
},
fail: function(e){
console.log(JSON.stringify(e));
}
});
}
操作数据库
- 执行SQL语句(plus.sqlite.executeSql),对数据进行增、删、改操作。数据库文件路径必须可读可写,否则会操作失败。
- 执行事务(plus.sqlite.transaction),对数据库执行事务操作。数据库文件路径必须可读可写,否则会操作失败。
- 执行查询SQL语句(plus.sqlite.selectSql),对数据库执行查询操作。数据库文件路径可读即可。
关闭数据库
数据库操作完成后,必须调用plus.sqlite.closeDatabase关闭,否则一直占用系统资源。推荐操作前打开数据库,完成操作后及时关闭数据库,避免引起占用系统资源而无法执行其它操作。
完整5+ API接口参考SQLite规范文档
云端打包配置
使用SQLite功能,提交云端打包时需在manifest.json中配置使用“SQLite(数据库)”。
-
HBuilderX1.8.0及以后版本通过可视化界面配置
打开应用的manifest.json文件,选择“模块权限配置”项,勾选“SQLite数据库”,如下图所示:
-
HBuilderX1.7.2&1.7.3版本通过源码视图配置
打开应用manifest.json文件,点击“源码视图”,在"permissions"节点下添加"SQLite"节点://... "permissions" : { //... "SQLite" : {} }, //...
uni-app应用在"app-plus"->"modules"节点下添加"SQLite"数据
HBuilderX 1.7.2及以上版本支持SQLite操作db文件。
概述
SQLite是一种嵌入式数据库,本质上就是一个数据库文件(.db)。是无服务器的、零配置的、事务性的简单轻量级SQL数据库引擎。
通常在移动设备上适合不需要高并发量的本地数据存储。
SQLite API使用
plus.sqlite已经封装好操作db数据库文件接口,按以下方法调用即可。
在uni-app中可使用条件编译直接调用5+ Push接口
打开数据库
使用前需调用plus.sqlite.openDatabase打开数据库,必须指定数据库文件路径(.db)和数据库名称。
数据库文件路径使用需注意以下问题:
应用资源目录中的文件只可读,在使用相对路径(如"./x.db")或5+API路径RelativeURL的应用资源目录(如"_www/x.db")时不能写入保存数据。通常可以将一些应用的初始数据作为资源内置到应用中,在业务逻辑中进行读取操作。
如果需要在应用的业务逻辑产生的数据保存,应该将数据库文件保存在可写目录中,推荐使用5+API路径的应用私有文档目录(如"_doc/x.db"),此目录中的文件是可读可写,并且应用热更新时不会影响此目录中的文件。
数据库文件路径只可读时,如果文件不存在打开数据库则会失败;数据库文件路径可读可写时,如果文件不存在则自动创建数据库文件。
注意:Android平台目前已知数据库文件不存在时不会自动创建(此问题会在HBuilderX1.8.1版本修复),临时解决方法是先创建不存在的文件,示例如下:
document.addEventListener('plusready', function(e){
// 确保_doc/test.db文件存在
plus.io.requestFileSystem( plus.io.PRIVATE_DOC, function(fs){
fs.root.getFile('test.db', {create:true}, function(fileEntry){
console.log('ensure test.db file!');
});
});
}, false);
// 打开数据库
function openDB(){
outSet('打开数据库: ');
plus.sqlite.openDatabase({
name: 'first',
path: '_doc/test.db',
success: function(e){
console.log(JSON.stringify(e));
},
fail: function(e){
console.log(JSON.stringify(e));
}
});
}
操作数据库
- 执行SQL语句(plus.sqlite.executeSql),对数据进行增、删、改操作。数据库文件路径必须可读可写,否则会操作失败。
- 执行事务(plus.sqlite.transaction),对数据库执行事务操作。数据库文件路径必须可读可写,否则会操作失败。
- 执行查询SQL语句(plus.sqlite.selectSql),对数据库执行查询操作。数据库文件路径可读即可。
关闭数据库
数据库操作完成后,必须调用plus.sqlite.closeDatabase关闭,否则一直占用系统资源。推荐操作前打开数据库,完成操作后及时关闭数据库,避免引起占用系统资源而无法执行其它操作。
完整5+ API接口参考SQLite规范文档
云端打包配置
使用SQLite功能,提交云端打包时需在manifest.json中配置使用“SQLite(数据库)”。
-
HBuilderX1.8.0及以后版本通过可视化界面配置
打开应用的manifest.json文件,选择“模块权限配置”项,勾选“SQLite数据库”,如下图所示:
-
HBuilderX1.7.2&1.7.3版本通过源码视图配置
打开应用manifest.json文件,点击“源码视图”,在"permissions"节点下添加"SQLite"节点://... "permissions" : { //... "SQLite" : {} }, //...
uni-app应用在"app-plus"->"modules"节点下添加"SQLite"数据
判断iOS系统推送功能是否开启,并可提醒去设置页打开设置推送
如果需要判断ios系统推送功能是否开启,并提醒去设置页打开设置推送,可以用以下nativeJS 代码:
function isOpenPush() {
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
plus.nativeUI.confirm("推送设置没有开启,是否去开启?", function(e) {
if (e.index == 0) {
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
var application2 = UIApplication.sharedApplication();
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
}
}, {
"buttons": ["Yes", "No"],
"verticalAlign": "center"
});
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if(enabledTypes == 0){
console.log("推送未开启!");
}else{
console.log("已经开启推送功能!")
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
}
此功能在uniapp项目且配置为自定义模式的时候,会报:“plus.ios.import is not a function”错误。
该问题已经在HBuilderX1.9.4.20190426 之后版本已经解决
如果需要判断ios系统推送功能是否开启,并提醒去设置页打开设置推送,可以用以下nativeJS 代码:
function isOpenPush() {
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
console.log("enabledTypes1:" + enabledTypes);
if (enabledTypes == 0) {
plus.nativeUI.confirm("推送设置没有开启,是否去开启?", function(e) {
if (e.index == 0) {
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
var application2 = UIApplication.sharedApplication();
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
}
}, {
"buttons": ["Yes", "No"],
"verticalAlign": "center"
});
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if(enabledTypes == 0){
console.log("推送未开启!");
}else{
console.log("已经开启推送功能!")
}
console.log("enabledTypes2:" + enabledTypes);
}
plus.ios.deleteObject(app);
}
此功能在uniapp项目且配置为自定义模式的时候,会报:“plus.ios.import is not a function”错误。
该问题已经在HBuilderX1.9.4.20190426 之后版本已经解决
在 uni-app 中使用 UniPush
HBuilderX 1.7.2 起,上线了 UniPush 功能。
UniPush
请认真阅读 UniPush 使用指南 及文中涉及到的相关文档说明,了解下什么是 UniPush。
在 uni-app 中使用
在 uni-app 中使用 UniPush 的话,可以通过条件编译直接使用 plus 的能力。
App.vue
较为合理的方案,是在 App.vue 中一次监听,集中处理获取推送消息后的操作。
export default {
onLaunch: function() {
// #ifdef APP-PLUS
const _self = this;
const _handlePush = function(message) {
// TODO
};
plus.push.addEventListener('click', _handlePush);
plus.push.addEventListener('receive', _handlePush);
// #endif
}
}
回调中的处理
- 较为常见的场景是,收到 Push 消息后根据推送消息的信息,跳转到某个指定的页面。
uni.navigateTo({ url: message.payload.pagePath });
- 如果某个数据信息,需要在推送成功后同步到其它页面,就需要用到 vuex 了。
vuex
/store/index.js
export default new Vuex.Store({
state: {
pushMessage: {}
},
mutations: {
updatePushMessage(state, message) {
/**
* 注意:这里为了方便预览查看效果,始终对 payload 做了序列化的处理。
* 实际开发期中,请自行调整代码并注意发送的 payload 消息格式。
*/
let payload = message.payload;
if (typeof payload !== 'string') {
message.payload = JSON.stringify(payload);
}
state.pushMessage = message || {};
}
}
})
消息同步
在 App.vue 中更新推送消息
export default {
onLaunch() {
// #ifdef APP-PLUS
const _self = this;
const _handlePush = function(message) {
/**
* 通过 vuex 来同步页面的数据,仅做演示。
* 实际开发中,这里可能是跳转到某个页面等操作,请根据自身业务需求编写。
*/
_self.updatePushMessage(message);
};
plus.push.addEventListener('click', function(message) {
plus.nativeUI.toast('push click');
_handlePush(message);
});
plus.push.addEventListener('receive', function(message) {
plus.nativeUI.toast('push receive');
_handlePush(message);
});
// #endif
},
methods: {
...mapMutations(['updatePushMessage'])
}
}
/pages/index/index.vue 页面渲染推送消息结果
<view>
<text class="title">推送消息 title:{{pushMessage.title}}</text>
<text class="title">推送消息 content:{{pushMessage.content}}</text>
<text class="title">推送消息 payload:{{pushMessage.payload}}</text>
<text class="title">推送消息 aps:{{pushMessage.aps}}</text>
</view>
源码
详细的示例代码,请下载附件查看。
测试发布
推送功能,涉及到第三方的 SDK 模块,因此与登录、分享等功能类似,需要打包后生效。
- 阅读 UniPush开通指南 开通服务
- manifest.json->App SDK配置,勾选“DCloud UniPush”。
- manifest.json->App模块权限配置,勾选 Push(消息推送)。
- 提交打包,自定义基座或正式打包均可。
结语
现如今各大厂商对于应用权限的管理愈发严格,在开发 Push 功能的过程中,需要仔细并且耐心。
如果使用 UniPush 的过程中遇到问题,请仔细对照文档检查后,再发帖详细描述问题。
参考文档
HBuilderX 1.7.2 起,上线了 UniPush 功能。
UniPush
请认真阅读 UniPush 使用指南 及文中涉及到的相关文档说明,了解下什么是 UniPush。
在 uni-app 中使用
在 uni-app 中使用 UniPush 的话,可以通过条件编译直接使用 plus 的能力。
App.vue
较为合理的方案,是在 App.vue 中一次监听,集中处理获取推送消息后的操作。
export default {
onLaunch: function() {
// #ifdef APP-PLUS
const _self = this;
const _handlePush = function(message) {
// TODO
};
plus.push.addEventListener('click', _handlePush);
plus.push.addEventListener('receive', _handlePush);
// #endif
}
}
回调中的处理
- 较为常见的场景是,收到 Push 消息后根据推送消息的信息,跳转到某个指定的页面。
uni.navigateTo({ url: message.payload.pagePath });
- 如果某个数据信息,需要在推送成功后同步到其它页面,就需要用到 vuex 了。
vuex
/store/index.js
export default new Vuex.Store({
state: {
pushMessage: {}
},
mutations: {
updatePushMessage(state, message) {
/**
* 注意:这里为了方便预览查看效果,始终对 payload 做了序列化的处理。
* 实际开发期中,请自行调整代码并注意发送的 payload 消息格式。
*/
let payload = message.payload;
if (typeof payload !== 'string') {
message.payload = JSON.stringify(payload);
}
state.pushMessage = message || {};
}
}
})
消息同步
在 App.vue 中更新推送消息
export default {
onLaunch() {
// #ifdef APP-PLUS
const _self = this;
const _handlePush = function(message) {
/**
* 通过 vuex 来同步页面的数据,仅做演示。
* 实际开发中,这里可能是跳转到某个页面等操作,请根据自身业务需求编写。
*/
_self.updatePushMessage(message);
};
plus.push.addEventListener('click', function(message) {
plus.nativeUI.toast('push click');
_handlePush(message);
});
plus.push.addEventListener('receive', function(message) {
plus.nativeUI.toast('push receive');
_handlePush(message);
});
// #endif
},
methods: {
...mapMutations(['updatePushMessage'])
}
}
/pages/index/index.vue 页面渲染推送消息结果
<view>
<text class="title">推送消息 title:{{pushMessage.title}}</text>
<text class="title">推送消息 content:{{pushMessage.content}}</text>
<text class="title">推送消息 payload:{{pushMessage.payload}}</text>
<text class="title">推送消息 aps:{{pushMessage.aps}}</text>
</view>
源码
详细的示例代码,请下载附件查看。
测试发布
推送功能,涉及到第三方的 SDK 模块,因此与登录、分享等功能类似,需要打包后生效。
- 阅读 UniPush开通指南 开通服务
- manifest.json->App SDK配置,勾选“DCloud UniPush”。
- manifest.json->App模块权限配置,勾选 Push(消息推送)。
- 提交打包,自定义基座或正式打包均可。
结语
现如今各大厂商对于应用权限的管理愈发严格,在开发 Push 功能的过程中,需要仔细并且耐心。
如果使用 UniPush 的过程中遇到问题,请仔细对照文档检查后,再发帖详细描述问题。
参考文档
收起阅读 »关于HbuderX配置外部web服务器问题,我看到还有很多不会,我分享一下怎么弄
1,首先你需要知道自己的ip地址,运行cmd ipconfig
2,打开工具看图片运行到外部浏览器
查看浏览器的地址,记住这个端口号
3,打开配置服务器
找到这一块
4,把你们本机的ip地址填写进去还有端口号看图
5,完美运行,如果手机wifi跟电脑在同一个网关上,可以实现扫码直接预览
1,首先你需要知道自己的ip地址,运行cmd ipconfig
2,打开工具看图片运行到外部浏览器
查看浏览器的地址,记住这个端口号
3,打开配置服务器
找到这一块
4,把你们本机的ip地址填写进去还有端口号看图
5,完美运行,如果手机wifi跟电脑在同一个网关上,可以实现扫码直接预览
plus removeRecursively 删除指定目录下的所有文件(有可能包含目录?)
直接上代码:
var dirPath = '_doc/tempImage/';
plus.io.resolveLocalFileSystemURL(dirPath, function(entry) {
//读取这个目录对象
var directoryReader = entry.createReader();
// console.log(dirPath)
//读取这个目录下的所有文件
directoryReader.readEntries(function(entries) {
// console.log(entries.length)
//如果有才操作
if (entries.length > 0) {
//删除目录将会删除其下的所有文件及子目录 不能删除根目录,如果操作删除根目录
//将会删除目录下的文件及子目录,不会删除根目录自身。 删除目录成功通过succesCB
//回调返回,失败则通过errorCB返回。
entry.removeRecursively(function(entry) {
// console.log('删除成功回调')
//删除成功回调
}, function(e) {
// console.log('!!')
//错误信息
$.toast(e.message + ' ?!');
})
}
}, function(e) {
$.toast('读取文件失败:' + e.message)
})
}, function(e) {
$.toast('读取目录失败:' + e.message)
})
以前 readEntries 成功回调的返回参数对象也有 removeRecursively 方法来着,现在没有了,郁闷,害得我找了半天毛病,手册上还是错误的,给我整得蒙蔽的。
注意上面的两个回调对象变量名称是不一样的。
直接上代码:
var dirPath = '_doc/tempImage/';
plus.io.resolveLocalFileSystemURL(dirPath, function(entry) {
//读取这个目录对象
var directoryReader = entry.createReader();
// console.log(dirPath)
//读取这个目录下的所有文件
directoryReader.readEntries(function(entries) {
// console.log(entries.length)
//如果有才操作
if (entries.length > 0) {
//删除目录将会删除其下的所有文件及子目录 不能删除根目录,如果操作删除根目录
//将会删除目录下的文件及子目录,不会删除根目录自身。 删除目录成功通过succesCB
//回调返回,失败则通过errorCB返回。
entry.removeRecursively(function(entry) {
// console.log('删除成功回调')
//删除成功回调
}, function(e) {
// console.log('!!')
//错误信息
$.toast(e.message + ' ?!');
})
}
}, function(e) {
$.toast('读取文件失败:' + e.message)
})
}, function(e) {
$.toast('读取目录失败:' + e.message)
})
以前 readEntries 成功回调的返回参数对象也有 removeRecursively 方法来着,现在没有了,郁闷,害得我找了半天毛病,手册上还是错误的,给我整得蒙蔽的。
注意上面的两个回调对象变量名称是不一样的。
对于uniapp瀑布流怎么做,几行代码教你
对于新鲜的uniapp别人问我瀑布流怎么做,现在我几行代码教你,本人就根据官网的看图demo来弄吧。思路就是把图标以纵向左右分开,设置宽度各自占一半,然后就是图片宽度一定(占一半),高度根据图片自己高度设置,假如高度太高了,可以自行限制一半自由发挥,看不到明显效果的话,就是图片高度都是等高的
<template>
<view class="index">
<view class="left">
<block v-for="(item, index) in list" :key="index" class="itemlist">
<view class="card" @click="goDetail(item)" v-if="index%2==0">
<image class="card-img" :src="item.img_src" mode="widthFix"></image>
<text class="card-num-view">{{item.img_num}}P</text>
<view class="card-bottm row">
<view class="car-title-view row">
<text class="card-title">{{item.title}}</text>
</view>
<view @click.stop="share(item)" class="card-share-view"></view>
</view>
</view>
</block>
</view>
<view class="right">
<block v-for="(item, index) in list" :key="index" class="itemlist">
<view class="card" @click="goDetail(item)" v-if="index%2==1">
<image class="card-img" :src="item.img_src" mode="widthFix"></image>
<text class="card-num-view">{{item.img_num}}P</text>
<view class="card-bottm row">
<view class="car-title-view row">
<text class="card-title">{{item.title}}</text>
</view>
<view @click.stop="share(item)" class="card-share-view"></view>
</view>
</view>
</block>
</view>
</view>
</template>
.left,.right{
display: inline-block;
vertical-align: top;
width: 49%;
}
.itemlist{
background-color: #fff;
margin: 1%;
margin-bottom: 20rpx;
display: inline-block;
}
对于新鲜的uniapp别人问我瀑布流怎么做,现在我几行代码教你,本人就根据官网的看图demo来弄吧。思路就是把图标以纵向左右分开,设置宽度各自占一半,然后就是图片宽度一定(占一半),高度根据图片自己高度设置,假如高度太高了,可以自行限制一半自由发挥,看不到明显效果的话,就是图片高度都是等高的
<template>
<view class="index">
<view class="left">
<block v-for="(item, index) in list" :key="index" class="itemlist">
<view class="card" @click="goDetail(item)" v-if="index%2==0">
<image class="card-img" :src="item.img_src" mode="widthFix"></image>
<text class="card-num-view">{{item.img_num}}P</text>
<view class="card-bottm row">
<view class="car-title-view row">
<text class="card-title">{{item.title}}</text>
</view>
<view @click.stop="share(item)" class="card-share-view"></view>
</view>
</view>
</block>
</view>
<view class="right">
<block v-for="(item, index) in list" :key="index" class="itemlist">
<view class="card" @click="goDetail(item)" v-if="index%2==1">
<image class="card-img" :src="item.img_src" mode="widthFix"></image>
<text class="card-num-view">{{item.img_num}}P</text>
<view class="card-bottm row">
<view class="car-title-view row">
<text class="card-title">{{item.title}}</text>
</view>
<view @click.stop="share(item)" class="card-share-view"></view>
</view>
</view>
</block>
</view>
</view>
</template>
.left,.right{
display: inline-block;
vertical-align: top;
width: 49%;
}
.itemlist{
background-color: #fff;
margin: 1%;
margin-bottom: 20rpx;
display: inline-block;
}
收起阅读 »
有偿提供佳博蓝牙打印机服务
一个打印小票的功能,做了快一个月,又是要文档,又是求助别人,终于弄好了。所以有相似功能还没搞定的同学,可以试试联系我。如果你已经完成了蓝牙发现并且能连接上打印机,只是最后的outputstream.write没有反应,在确认的我方法可以正常打印的情况下 收费是200,如果从蓝牙发现开始,收费500,但是要提供给我打印机的技术文档。另外说一句,如果最后一步outputstream.write这个没反应,最有可能的原因是你的打印机是双模式的,即票据模式和标签模式,而打印机默认是标签模式的。所以导致无法打印。但是我按照文档切换的时候是无效的,所以我就干脆用的标签模式打印,但是标签模式的打印高度是固定的,最后我采取了分段打印的方法,有能力的可以参考,实在不行的可以联系我。暂时只支持安卓时间,苹果没有研究。
一个打印小票的功能,做了快一个月,又是要文档,又是求助别人,终于弄好了。所以有相似功能还没搞定的同学,可以试试联系我。如果你已经完成了蓝牙发现并且能连接上打印机,只是最后的outputstream.write没有反应,在确认的我方法可以正常打印的情况下 收费是200,如果从蓝牙发现开始,收费500,但是要提供给我打印机的技术文档。另外说一句,如果最后一步outputstream.write这个没反应,最有可能的原因是你的打印机是双模式的,即票据模式和标签模式,而打印机默认是标签模式的。所以导致无法打印。但是我按照文档切换的时候是无效的,所以我就干脆用的标签模式打印,但是标签模式的打印高度是固定的,最后我采取了分段打印的方法,有能力的可以参考,实在不行的可以联系我。暂时只支持安卓时间,苹果没有研究。
收起阅读 »MUI input mui-input-password 和 Vue 共同使用失效的问题
<input v-model="password" type="password" class="mui-input-password mui-input" placeholder="设置6位数字密码">
和Vue共用,那个小眼睛失效。无论怎么动态初始化都不好使!
解决办法:
1、在Vue中自定义组件:
Vue.component('p-input', {
mounted:function() {
mui('.mui-input-row input').input();
},
props: ['value', 'placeholder'],
template:
'<input type="password" class="mui-input mui-input-password" :placeholder=placeholder '+
' v-bind:value="value" '+
' v-on:input="$emit(\'input\', $event.target.value)" '+
'>'
})
2、html中这么用:
<p-input v-model="password" placeholder="设置6位数字密码"></p-input>
<input v-model="password" type="password" class="mui-input-password mui-input" placeholder="设置6位数字密码">
和Vue共用,那个小眼睛失效。无论怎么动态初始化都不好使!
解决办法:
1、在Vue中自定义组件:
Vue.component('p-input', {
mounted:function() {
mui('.mui-input-row input').input();
},
props: ['value', 'placeholder'],
template:
'<input type="password" class="mui-input mui-input-password" :placeholder=placeholder '+
' v-bind:value="value" '+
' v-on:input="$emit(\'input\', $event.target.value)" '+
'>'
})
2、html中这么用:
<p-input v-model="password" placeholder="设置6位数字密码"></p-input>
开发电商app的优势
> 更好提升品牌价值
企业在开发APP时,可根据企业品牌特性,通过增加一些新奇趣的营销互动体验模式,提升消费者的App使用感受。同时,借助高质量的内容、视频、秒杀、积分兑换等营销模式,融入于电商软件中,能更好地拉近用户与品牌距离,同时提高产品销量,提升品牌高度。目前,力谱云支持:秒杀、满减、会员积分、分红返利、预付卡、代金券等数十余种营销功能,供企业加速流量变现之路。
> 更好提升品牌价值
企业在开发APP时,可根据企业品牌特性,通过增加一些新奇趣的营销互动体验模式,提升消费者的App使用感受。同时,借助高质量的内容、视频、秒杀、积分兑换等营销模式,融入于电商软件中,能更好地拉近用户与品牌距离,同时提高产品销量,提升品牌高度。目前,力谱云支持:秒杀、满减、会员积分、分红返利、预付卡、代金券等数十余种营销功能,供企业加速流量变现之路。
收起阅读 »