上一篇文章记录了Vue是如何向iOS发送消息实现通信的,这一篇就记录一下iOS是如何向Vue传递参数的。
1、为什么要向js发送参数
像京东,淘宝等商城类应用的商品详情页面排版使用原生语言实现同样的效果非常费劲,所以类似这样的页面可以使用H5来进行实现。
通过H5实现商品详情展示,原生实现列表。可以凑活兼顾渲染大列表H5性能问题和原生排版不便的问题。
2、流程
文章中,通过上文Vue 向 iOS发送消息中的弹窗确定事件来执行App.vue文件中的一个函数,这个函数接受一个参数,参数为一个数组,同时跳转到下一个列表页面并对上级传入的数据进行展示。
3、vue端需要注意的事情
;与原生js不同,vue的函数需要在mounted中将函数挂载到全局中,才可以被iOS发现并使用
mounted: function() {
// reciveMsg为methods中声明并实现的函数
window.reciveMsg = this.reciveMsg;
},
4、开始
一、iOS 端
iOS端通过WKScriptMessageHandler的回调函数,处理由js传到iOS的消息,我们在这个回调里继续做操作
// 回调函数返回js发送到webview中的消息
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
let alert = UIAlertController.init(title: "js函数名: \(message.name)", message: "Message.body:\(message.body)", preferredStyle: .alert);
let alert_action_default = UIAlertAction.init(title: "确定", style: .default) { (action) in
let js_String = "var title_1 = 30; var price_1 = 40; var title_2 = 10; var price_2 = 50; reciveMsg([{title:title_1,price:price_1},{title:title_2,price:price_2}])"
self.webView.evaluateJavaScript(js_String) { (result, error) in
print(error.debugDescription);
print(result ?? "result is no exist");
}
}
let alert_action_cancel = UIAlertAction.init(title: "取消", style: .cancel, handler: nil);
alert.addAction(alert_action_default);
alert.addAction(alert_action_cancel);
self.present(alert, animated: true, completion: nil);
}
这段代码的意思是,在接到web中click me按钮点击事件后,iOS弹出一个窗口,当窗口的确定按钮被点击后,webView执行声明的那一段js代码。
上面代码中声明了一段js代码, 代码中,声明了四个变量,title_1、price_1、title_2、price_2、并分别给这几个变量赋了值。而后,这段代码中还有一个js函数,即我们在App.vue里面声明并挂载至全局的那个函数。
二、Vue端
;Vue端通过声明函数并挂载到全局实现iOS可以发现并执行此函数。
export default {
mounted: function() {
// reciveMsg为methods中声明并实现的函数
window.reciveMsg = this.reciveMsg;
},
methods: {
reciveMsg: function(param) {
this.detailParam = param;
//跳转下一个页面
this.$router.push({
name: "goodDetail",
//需要下一个页面接收的参数
params: {
goods: this.detailParam,
}
});
return param;
},
}
};
然后,新建一个文件GoodsDetail.vue,这个是我们的商品详情页面,简单对这个文件做一下布局(只是为了演示效果,没有做页面)
<template>
<div class="ListView">
<div class="ListView-item" v-for="(item, index) in ListDataSource" :key="index">
<img class="ListView-item-img" :src="item.img" />
<p class="ListView-item-title">{{item.title}}</p>
<p class="ListView-item-price">{{item.price}}</p>
</div>
</div>
</template>
<script>
import { log } from "util";
export default {
// 在页面创建完成后,接收从上级页面传递进来的数据
created: function() {
console.log(this.$route.params.goods);
//声明变量接收上个页面传过来的数据,这里$route不是$router
this.ListDataSource = this.$route.params.goods;
},
data: function() {
return {
ListDataSource: [],
};
}
};
</script>
<style lang="scss" scoped>
.ListView {
display: flex;
flex-direction: column;
overflow: hidden;
overflow-y: scroll;
}
</style>
5、关于通过手机或者模拟器查看js日志
打开Safari浏览器->Safari偏好设置
点击Safari上方meun的开发就能看到模拟器和手机选项。
这样就可以在模拟器或者手机运行程序的时候查到js的log日志了。
6、看一下运行的效果
可以看到,这个简洁列表里面显示的数据,就是我们在iOS代码里声明的js代码中的那些参数的值