您的位置:首页 > 移动开发

Dclound + vue开发 Hybrid APP注意事项

2017-11-12 17:14 375 查看

1.vue实例放在 plusready 函数内执行回调函数

vue实例如果用到Dclound 内置api时候需要放在 plusready 函数内执行回调函数,在iOS上,plus ready只是为了向下兼容,因为在webview最开始,plus就是生效的,但是在安卓手机webview最开始,plus并不一定就是生效的。苹果和安卓在配合vue使用时候可能由于Dclound和vue生命周期先后渲染顺序不同,引发莫名错误,所以应该采用如下方法解决例如:

定义plusReady.js

/**
* plusReady 事件
* @param callack
*/
export function plusReady (callack) {
if (window.plus) {
callack()
} else {
document.addEventListener('plusready', callack, false)
}
}
export default {plusReady}

定义webview.js
const webview = {}
webview.close = function (id) {
evt.plusReady(() => {
var view
if (id) {
view = window.plus.webview.getWebviewById(id)
} else {
view = window.plus.webview.currentWebview()
}
window.plus.webview.close(view)
})
}
export default webview

vue页面A
import webview from 'xxxxx'
mounted: {
webview.close('id')
}


所以最好自己封装好webview模块方法,之后在vue实例内使用,或者在实例内如下方法:

import evt from '../xx/xx/xx/plusReady'
mounted () {
evt.plusReady(() => {
var view
if (id) {
view = window.plus.webview.getWebviewById(id)
} else {
view = window.plus.webview.currentWebview()
}
// var ws= window.plus.webview.currentWebview();
window.plus.webview.close(view)
})
}


2.vue多页面开发Dclound webview页传值

传值有两种方法

第一种采用Dclound内webview创建时候传值,只能传字符串

页面A
window.plus.webview.create('newslist.html', 'B', {}, {val: val.name, vid: val.id})// 创建B页面
页面B
var view =  window.plus.webview.getWebviewById('B')
window.plus.webview.show(view)
this.id = view.vid
this.val = view.val


第二种采用事件广播传值

//所需方法
// A页面打开B页面,B处理之后把数据传回给A
webview.childsendevent = function (name, data) {
evt.plusReady(() => {
var wvB = window.plus.webview.currentWebview()
var wvA = wvB.opener()
wvA.evalJS(`document.dispatchEvent(new CustomEvent('${name}', {
detail:JSON.parse('${JSON.stringify(data)}'),
bubbles: true,
cancelable: true
}));`)
wvB.close()
})
}
//监听
webview.parentgetevent = function (name, fun) {
evt.plusReady(() => {
document.addEventListener(name, fun)
})
}

页面A
mounted () {
webview.parentgetevent('事件名', this.getshijian)
}
destroyed () {
//如果需要卸载事件
webview.removeparentevent('事件名', this.getshijian)
}
methods: {
getshijian (e) {
console.log(e.detail.obj) B传的value值
}
}
页面B
webview.childsendevent('事件名', {obj: value})


3.手机返回键

如果有用到vue嵌套路由,Dlound的手机返回键监听需要根据自己页面逻辑重写,切需要在嵌套路由的单页面入口文件js内处理,

let app = r => require.ensure([], () => r(require('./app')), 'app')
let forget = r => require.ensure([], () => r(require('./forget')), 'forget')
let sure = r => require.ensure([], () => r(require('./sure')), 'sure')
const routes = [
{
path: '/',
component: app,
children: [
{
path: '/forget',
component: forget,
children: [
{
path: 'sure',
component: sure
}
]
}
]
}
]
import evt from 'xxxxx/plusReady'
var first = null
evt.plusReady(() => {
var webview = window.plus.webview.currentWebview()
window.plus.key.addEventListener('backbutton', function () {
let href = window.location.href
var wvs = window.plus.webview.all()
webview.canBack(function (e) {
if (href.indexOf('forget/sure') > -1) {
router.push('/forget')
} else if (href.indexOf('/forget') > -1) {
router.push('/')
} else if (webview.id === 'login.html') {
if (wvs.length <= 1) {
if (!first) {
first = new Date().getTime()
window.plus.nativeUI.toast('再按一次退出应用')
setTimeout(function () {
first = null
}, 1000)
} else {
if (new Date().getTime() - first < 1000) {
window.plus.runtime.quit()
}
}
} else {
webview.close()
}
}
})
})
})


4.三方分享三方登陆

注意微信分享略缩图需小于35kb

新浪微博分享需要内容+链接的字符串形式,

三方登陆,大同小异看文档

import evt from '@config/H5Plus/plusReady'
let sharebox = {}
export default {
data () {
return {
contentmsg: {
wbcont: '',
cont: '',
href: '',
title: '',
img: ''
}
}
},
mounted () {
this.init()
},
methods: {
init () {
evt.plusReady(() => {
window.plus.share.getServices(function (s) {
for (var i in s) {
var t = s[i]
sharebox[t.id] = t
}
}, function (e) {
console('获取分享服务列表失败:' + e.message)
})
})
},
async initstart () {
try {
let res = await imagetextshow(this.id)
if (res.data.Error) {
Toast({
message: res.data.Msg,
position: 'middle',
duration: 2000
})
} else {
console.log(JSON.stringify(res))
this.contentmsg.cont = res.data.description
this.contentmsg.title = res.data.title
this.contentmsg.href = res.data.titleurl
this.contentmsg.img = res.data.suolue_thumb
this.contentmsg.wbcont = res.data.title + res.data.titleurl//新浪微博分享需要内容+链接
}
} catch (e) {
}
},

shareHref () {
console.log(111)
let _this = this
var shareBts = []
// 更新分享列表
var ss = sharebox['weixin']
ss && ss.nativeClient && (shareBts.push({title: '微信朋友圈', s: ss, x: 'WXSceneTimeline'}),
shareBts.push({title: '微信好友', s: ss, x: 'WXSceneSession'}))
//        ss = sharebox['sinaweibo']
//        ss && shareBts.push({title: '新浪微博', s: ss})
// ss = sharebox['tencentweibo']
// ss && shareBts.push({title: '腾讯微博', s: ss})
// ss = sharebox['qq']
// ss && ss.nativeClient && shareBts.push({title: 'QQ', s: ss})
// 弹出分享列表
if (shareBts.length > 0) {
window.plus.nativeUI.actionSheet({cancel: '取消', buttons: shareBts}, function (e) {
if (e.index > 0) {
console.log(e.index - 1)
if (e.index - 1 === 2) {
_this.shareAction(shareBts[e.index - 1], false)
} else {
_this.shareAction(shareBts[e.index - 1], true)
}
}
})
} else {
window.plus.nativeUI.alert('当前环境无法支持分享链接操作!')
}
},
/**
* 分享操作
* @param {JSON} sb 分享操作对象s.s为分享通道对象(plus.share.ShareService)
* @param {Boolean} bh 是否分享链接
*/
shareAction (sb, bh) {
console.log('分享操作:')
if (!sb || !sb.s) {
console.log('无效的分享服务!')
return
}
var msg = {content: this.contentmsg.cont + this.contentmsg.href, extra: {scene: sb.x}}
if (bh) {
//其他分享
msg.href = this.contentmsg.href
msg.title = this.contentmsg.title
msg.content = this.contentmsg.cont
msg.thumbs = [this.contentmsg.img]
msg.pictures = [this.contentmsg.img]
} else {
//微博分享
msg.pictures = [this.contentmsg.img]
}
// 发送分享
if (sb.s.authenticated) {
console.log('---已授权---')
this.shareMessage(msg, sb.s)
} else {
console.log('---未授权---')
sb.s.authorize(function () {
this.shareMessage(msg, sb.s)
}, function (e) {
Toast({
message: '认证授权失败',
iconClass: 'iconfont icon-error'
})
console.log('认证授权失败:' + e.code + ' - ' + e.message)
})
}
},
/**
* 发送分享消息
* @param {JSON} msg
* @param {plus.share.ShareService} s
*/
shareMessage (msg, s) {
console.log(JSON.stringify(msg))
s.send(msg, function () {
Toast({
message: '分享成功',
iconClass: 'iconfont icon-error'
})
console.log('分享到"' + s.description + '"成功!')
}, function (e) {
Toast({
message: '分享失败',
iconClass: 'iconfont icon-error'
})
console.log('分享到"' + s.description + '"失败: ' + JSON.stringify(e))
})
}
}
}
</script>


5.系统状态栏

ios6.0以上,以及部分安卓可以自己设置样式,且在一个webview页设置成功默认所有页面同样生效

evt.plusReady(() => {
window.plus.navigator.setStatusBarStyle('UIStatusBarStyleBlackOpaque')//文字样式
window.plus.navigator.setStatusBarBackground('#1c1e25')//背景样式
})


也可以在manifest.json配置

"distribute": {
"apple": {
"UIStatusBarStyle":"设置状态栏的样式,可取值UIStatusBarStyleBlackTranslucent/UIStatusBarStyleDefault/UIStatusBarStyleBlackOpaque",
"StatusBarBackground":"设置状态栏的背景颜色,iOS7以上系统有效,支持#RRGGBB格式"
}
}


6.缓存

前台手动存cookie存储不上,无论采用js原生方法,还是webview模块内方法都存储失败,有需求尽量使用storage模块内置方法,注意一样放在evt.plusReady()回调内使用,无论是强制退出还是返回键退出只要不清除缓存,Storage永远保存在app内,可以记录登陆状态等,后台接口返回时候如果带cookie是可以存在app中。供后台自己使用,但是只要强制退出app时,cookie会失效

7.打包发布

如果有用到微信分享,登陆等,注意安卓的包名一定要和微信开发平台内的包名一致,否则安卓的微信分享,微信登陆将失败
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: