本篇文章带大家了解一下renderjs,通过在uniapp中使用better-scroll,聊聊renderjs的一些细节,希望对大家有所帮助!

包含内容:
使用renderjs在app端获取dom
renderjs和service层之间的通信
renderjs中如何接收到service层中的自定义id(重点,官方文档没有的)
一、renderjs
1.1 renderjs的概念
官方文档
运行在视图层的js,只支持app-vue和h5(简单来说就是开了另外一条线程)
1.2 renderjs的作用
大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力(减少通讯损耗提升性能,例如一些手势或canvas动画的场景)
在视图层操作dom,运行for web的js库(可以操作dom,意味着拥有window、document等这些全局变量,在app-vue的service层没有这些)
1.3 renderjs的使用
官方文档给出的示例 (内容较为详细,也可以看我接下来的简要概括)
在原先的script标签的同级新增一个script,设置lang=renderjs,module=(值任意,相当于命名空间,之后会根据这个名字调用其中的方法)
新script标签内的结构和之前的几乎一致,有几点不同的需要注意:
生命周期不和uniapp相同,而是和vue相同,
onLoad应该写成原生vue的created官方文档好像说了renderjs中无法使用uni这个全局变量,具体哪个地方忘了。实测结果是:部分可以。例如
uni.upx2px是可以用的,uni.request不可以,所以使用uni全局变量之前先输出看一下有没有
在template中使用一开始给renderjs的命名加.的方式调用其中的方法
<template> <view> <button @tap="test.handleClick">点击</button> </view></template> <script> export default { // 原先的script,这里被称为service层 }</script> <script module="test"> export default { data() { return {} }, methods: { handleClick(event, ownerInstance) { // event是事件对象 // ownerInstance和this.$ownerInstance是一样的,用来调用service层的方法 console.log('点击了按钮') } }, created() { console.log('renderjs初始化完毕') } }</script>二、renderjs和service层的通信
具体分为三部分:
在template中通过用户手动操作触发事件
在service层中调用方法
在renderjs中调用方法
从renderjs到service层:通过this.$ownerInstance.callMethod()方法可以调用service中的方法,第一个参数是方法名,第二个参数是传过去的参数
<template> <view> <button @tap="test.onClick">点击</button> </view></template> <script> export default { methods: { acceptDataFromRenderjs(data) { console.log('从renderjs中接收到的数据', data) } } }</script> <script module="test"> export default { data() { return {} }, methods: { onClick(event, ownerInstance) { ownerInstance.callMethod('acceptDataFromRenderjs', { content: '测试文字' }) // 或this.$ownerInstance.callMethod('acceptDataFromRenderjs', { content: '测试文字' }) // 需要注意的是:只有通过在template中用户手动操作触发renderjs的方法参数是这两个:event, ownerInstance; // 通过其他方法触发的函数参数不一样,后面会说 } } }</script>从service层到renderjs:
这里就需要template了,首先在template中绑定一个service中定义的值,然后在同样的位置增加:change:(属性名)=(触发的方法)来实现通信。
简单来说就是service负责数据的更改,通过template监听数据的变化来通知renderjs
<template> <view> // prop是个名字,可以随意改,注意:change:[name]这两个名字需要相同就行了 <text :prop="options" :change:prop="test.onChange">无内容</text> <button @tap="changeOptionFn">点击修改options</button> </view></template> <script> export default { data() { return { options: { // 这里存放准备传递给renderjs的数据 token: null, num: 1 } } }, methods: { changeOptionFn() { this.options = { // 这个地方我用时间戳来修改token,用于触发change,实际需要传递的数据是num token: Date.now(), num: Math.random() } } } }</script> <script module="test"> export default { methods: { onChange(newValue, oldValue, ownerInstance, instance) { console.log('service层中的options发生变化') console.log('新值', newValue) console.log('旧值', oldValue) // ownerInstance和this.$ownerInstance一样,可用来向service层通信 // instance和ownerInstance的区别是: // instance.$el指向的是触发事件的那个节点;ownerInstance.$el指向当前vue文件中的根节点; // instance的作用目前尚不明确,官方没有给出用法 } } }</script>在上面的例子中,prop初次绑定到节点时,事件不会触发。
用户首先通过点击按钮触发changeOptionFn事件

