uni-app中renderjs使用
study夏羽 人气:0前言
对于UNI APP端的开发而言,由于上并没有document,不能进行相关的DOM操作,同时有关DOM渲染的第三方库(echart、openlayer等)也无法有效的使用,因此官方推出了renderjs方案,来解决上述问题。
renderjs是一个运行在视图层的js
renderjs的主要作用有2个:
大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
在视图层操作dom,运行for web的js库
renderjs和service层的通信
具体分为三部分:
1.在template中通过用户手动操作触发事件
2.在service层中调用方法
3.在renderjs中调用方法
从renderjs到service层:通过this.$ownerInstance.callMethod()方法可以调用service中的方法,第一个参数是方法名,第二个参数是传过去的参数
使用方式
设置 script 节点的 lang 为 renderjs
script的module的名称可以随便取,module=(值任意,相当于命名空间,之后会根据这个名字调用其中的方法),但是change:参数名称必须和module保持一致,虽然不会阻断renderjs的运行,但是会报错,也会导致无法捕获数据的变化
<script module="test" lang="renderjs"> export default { mounted() { // ... }, methods: { // ... } } </script>
<template> <view> <!-- prop是个名字,可以随意改,注意:change:[name]这两个名字需要相同就行了 --> <!-- 从service层到renderjs:首先在template中绑定一个service中定义的值,然后在同样的位置增加:change:(属性名)=(renderjs的module名.触发的方法)来实现通信。 简单来说就是service负责数据的更改,通过template监听数据的变化来通知renderjs this.$ownerInstance.callMethod方法必须通过点击事件执行--> <!-- msg是要向renderjs发送的数据,testRenderjs 为renderjs模块名称,onChange是renderjs中的监听方法 --> <view :prop="msg" :change:prop="testRenderjs.onChange" id="renderjs-view">{{msg}}</view> <button @tap="changeMsgFn">点击修改options</button> <button @tap="testRenderjs.emitData">直接调用renderjs中的emitData方法</button> </view> </template> <script> // 原先的script,这里被称为service层 export default { data() { return { // 这里存放准备传递给renderjs的数据 msg: "我是service层原来的msg" } }, methods: { // 触发service层 出入renderjs数据改变 changeMsgFn() { // 修改msg 触发change this.msg = "msg的值变了" }, // 接收renderjs发回的数据 acceptDataFromRenderjs(data) { console.log('从renderjs中接收到的数据', data) this.msg = data.content } } } </script> <!-- testRenderjs 为renderjs模块名称,lang固定写法 --> <script module="testRenderjs" lang="renderjs"> export default { data() { return { content:"我是来自renderjs的数据" } }, created() { console.log('renderjs初始化完毕') }, mounted() { const view = document.getElementById('renderjs-view') const button = document.createElement('button') button.innerText = '一个按钮' view.appendChild(button) }, methods: { // 接收逻辑层service层发送的数据 onChange(newValue, oldValue, ownerInstance, instance) { console.log('service层中的options发生变化') console.log('新值newValue', newValue) console.log('旧值oldValue', oldValue) // ownerInstance和this.$ownerInstance一样,可用来向service层通信 // instance和ownerInstance的区别是: // instance.$el指向的是触发事件的那个节点;ownerInstance.$el指向当前vue文件中的根节点; // instance的作用目前尚不明确,官方没有给出用法 }, // 发送数据到service层 emitData(event, ownerInstance) { // event是事件对象 ownerInstance.callMethod('acceptDataFromRenderjs', { content: this.content }) // 或者 /* this.$ownerInstance.callMethod('acceptDataFromRenderjs',{ content:this.content }) */ // 需要注意的是:只有通过在template中用户手动操作触发renderjs的方法参数是这两个:event, ownerInstance;通过其他方法触发的函数参数不一样 } } } </script>
补充:使用时的注意事项
- 目前仅支持内联使用。
- 不要直接引用大型类库,推荐通过动态创建 script 方式引用。
- 可以使用 vue 组件的生命周期不可以使用 App、Page 的生命周期
- 视图层和逻辑层通讯方式与 WXS 一致,另外可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。
- 观测更新的数据在视图层可以直接访问到。
- APP 端视图层的页面引用资源的路径相对于根目录计算,例如:./static/test.js。
- APP 端可以使用 dom、bom API,不可直接访问逻辑层数据,不可以使用 uni 相关接口(如:uni.request)
- H5 端逻辑层和视图层实际运行在同一个环境中,相当于使用 mixin 方式,可以直接访问逻辑层数据。
总结
加载全部内容