uni-app中使用RenderJs 使用原生js 使用iframe

1. RenderJs运行机制

RenderJs运行的层叫【视图层】,Uniapp原生Script叫【逻辑层】,逻辑层要调用视图层需要使用一个叫【watcher】,具体怎么调用呢

为了实现这两层之间的通信,uniapp提供了一些特定的机制。以下是对这些通信机制的详细解释,以及一个具体的示例,说明逻辑层如何调用视图层的watcher。

通信机制
‌通过this.$ownerInstance获取当前组件的ComponentDescriptor实例‌:

在RenderJs中,你可以通过this.$ownerInstance访问到当前组件的ComponentDescriptor实例。这个实例提供了与逻辑层通信的接口。
‌通过事件和callMethod方法进行通信‌:

逻辑层可以触发事件,并在RenderJs中监听这些事件。
RenderJs也可以通过this.$ownerInstance.callMethod方法调用逻辑层中的方法,并传递数据。

2. 举例

<template>
  <view>
    <!-- 视图层组件,绑定:prop和:change:prop -->
    <view :prop="someData" :change:prop="renderScript.onDataChange"></view>
    <button @click="changeData">改变数据并触发watcher</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      someData: '初始数据', // 逻辑层数据
    };
  },
  methods: {
    changeData() {
      this.someData = '新数据'; // 改变数据,这将触发视图层的watcher
    },
    // 逻辑层接收来自视图层的数据(可选)
    receiveDataFromRenderJs(data) {
      console.log('从视图层接收到的数据:', data);
    },
  },
};
</script>

<script module="renderScript" lang="renderjs">
export default {
  data() {
    return {
      receivedData: '', // 用于存储从逻辑层接收到的数据
    };
  },
  methods: {
    onDataChange(newValue, oldValue, ownerVm, vm) {
      console.log('数据变化了,新值:', newValue, '旧值:', oldValue);
      
      // 可以在这里调用逻辑层的方法,并传递数据
      // ownerVm.callMethod('receiveDataFromRenderJs', { someKey: newValue });
    },
    // 视图层向逻辑层发送数据(示例)
    sendDataToLogicLayer() {
      // 假设这里有一些逻辑需要向逻辑层发送数据
      const dataToSend = { fromRenderJs: '这是视图层的数据' };
      this.$ownerInstance.callMethod('receiveDataFromRenderJs', dataToSend);
    },
  },
};
</script>

解释
‌模板部分‌:

我们定义了一个视图层组件,并使用:prop和:change:prop绑定了逻辑层的数据和视图层的watcher方法。
当someData在逻辑层发生变化时,将触发renderScript.onDataChange方法。
‌逻辑层部分‌:

我们定义了一个someData数据和一个changeData方法,用于改变someData的值。
当someData的值改变时,将触发视图层的onDataChangewatcher方法。
我们还定义了一个receiveDataFromRenderJs方法,用于接收来自视图层的数据(虽然在这个示例中并没有直接调用它,但展示了如何接收数据)。
‌视图层(RenderJs)部分‌:

我们定义了一个onDataChange方法,当逻辑层的数据变化时,这个方法将被调用。
在onDataChange方法中,我们可以访问新旧值,并可以在这里调用逻辑层的方法,传递数据。
我们还定义了一个sendDataToLogicLayer方法,用于演示如何从视图层向逻辑层发送数据。
通过这种方式,你可以在uniapp中实现逻辑层和视图层之间的有效通信

3. 使用iframe打开src并获取src返回的数据
由于项目需要调用另一网页,并需要数据往返操作,遂使用iframe

发送数据参数给iframe,通过在mounted()给iframe添加返回消息的监听事件 调用onMessage(e)方法,获取iframe返回的图片base64数据 再通过button点击事件 用test()方法传递给逻辑层

<template>
	<view>
		<view :prop="someData" :change:prop="renderjs.onPrint"></view>
		<iframe v-show="true" class="printIframe" id="printIframe"
			src="http://192.168.120.50/LCA/index.html"></iframe>
		
		<button class="btn1" v-show="false" ref="btn1" @click="renderjs.test">打印</button>
	</view>
</template>

<script>
	export default {
	  data() {
	    return {
	      someData: '初始数据', // 逻辑层数据
	    };
	  },
	  methods: {
	    changeData() {
	    	//数据变化时则调用renderjs.onPrint,
	    	this.someData = '新数据'; // 改变数据,这将触发视图层的watcher
	    },
	    // 逻辑层接收来自视图层的数据(可选)
	    receiveDataFromRenderJs(data) {
	      console.log('从视图层接收到的数据:', data);
	    },
	  },
	};
</script>
<script lang="renderjs" module="renderjs">
	export default {
		data() {
			return {
				image: '',
				brcode: ''
			}
		},
		methods: {
			test(e, o) {
				if(o){
					o.callMethod('testFun', this.image)
				}else{
					this.$o.callMethod('testFun', this.image)
				}
				
			},
			onMessage(e) {
				//iframe返回的数据e.data.data(图片base64)
				console.log(e.data)
				if (e.data.data) {
					this.image = e.data.data
					if (document.querySelector('.btn1')) {
						document.querySelector('.btn1').click()
					}
				}
			},
			onPrint(newValue, oldValue, ownerVm, vm) {
				console.log('数据变化了,新值:', newValue, '旧值:', oldValue);
				if (newValue && newValue.length > 0) {
					const iframe = document.querySelector(".printIframe")
					
					iframe.contentWindow.postMessage({
						Print_Data: newValue//把新数据发送给iframe,iframe会返回标签图片的base64
					}, '*');

				}
			}
		},
		mounted() {
			//添加iframe返回消息的监听事件,调用this.onMessage方法
			window.removeEventListener('message', this.onMessage);
			window.addEventListener('message', this.onMessage);

		}
	}
</script>
### 使用 HBuilder X 进行微信小程序或 APP 的套壳教程 #### 工具准备 为了顺利进行套壳操作,需准备好如下工具和环境配置: - 安装最新版本的 HBuilder X 开发工具[^1]。 - 注册并登录 DCloud 账号,在线获取应用签名证书。 #### 创建项目结构 创建一个新的 uni-app 项目作为基础框架。此框架将用于承载外部网页内容,并通过特定方式嵌入至目标平台中。 ```bash # 打开命令行工具执行以下命令安装 CLI 并初始化新项目 npm install -g @dcloudio/uni-cli uni create my-shell-project cd my-shell-project ``` #### 配置 webview 组件加载页面 在 `pages/index/index.vue` 文件里引入 `<web-view>` 或者自定义组件来实现对外部 URL 地址的访问功能。 ```html <template> <div class="container"> <!-- 微信小程序 --> <web-view v-if="isWeChat" :src="url"></web-view> <!-- App 环境下可选方案一:使用 plus.webview.open 方法打开链接 --> <button type="primary" @click="openUrl()" v-else>Open Web Page</button> <!-- 方案二:直接利用原生 WebView 控件展示网页 --> <iframe id="frameId" style="display:none;" referrerPolicy="no-referrer"></iframe> </div> </template> <script> export default { data() { return { url: 'https://example.com', // 替换成实际要套壳的目标网站地址 isWeChat: false, // 判断当前运行环境是否为微信客户端 }; }, onLoad(options){ this.isWeChat = /micromessenger/i.test(navigator.userAgent); }, methods:{ openUrl(){ if (plus.os.name === "Android") { window.location.href=this.url; } else if(plus.os.name === "iOS"){ var wv=plus.webview.create(this.url,'external',{top:'0px',bottom:'0px'}); plus.navigator.closeSplashscreen(); plus.webview.currentWebview().append(wv); } } } } </script> ``` #### 设置权限声明与安全域名白名单 对于微信小程序而言,需要前往微信公众平台后台设置合法外链域名为确保能正常拉取远程资源[^2]。而对于 Android 和 iOS 应用,则应在 manifest.json 中适当位置添加网络请求许可声明。 ```json { ... "permissions": [ "network" ], "securityStyle": "normal", "domainWhiteList": ["*.example.com"] } ``` #### 发布前测试验证 完成上述步骤之后,建议先在本地模拟器以及真机设备上进行全面的功能性和兼容性检测,确认无误后再正式提交审核发布流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值