RenderJs

renderjs 是一个运行在视图层的 js。它比 WXS 更加强大。它只支持 app-vue 和 web。

主要作用

  1. 大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力

    uni-app 的 app 端逻辑层和视图层是分离的,这种机制有很多好处,但也有一个副作用是在造成了两层之间通信阻塞。尤其是 App 的 Android 端阻塞问题影响了高性能应用的制作。

    renderjs 运行在视图层,可以直接操作视图层的元素,避免通信折损。

  2. 在视图层操作 dom,运行 for web 的 js 库

    官方不建议在 uni-app 里操作 dom,但如果你不开发小程序,想使用一些操作了 dom、window 的库,其实可以使用 renderjs 来解决。

    在 app-vue 环境下,视图层由 webview 渲染,而 renderjs 运行在视图层,自然可以操作 dom 和 window。

注意事项

  1. 目前仅支持内联使用。
  2. 不要直接引用大型类库,推荐通过动态创建 script 方式引用。
  3. 可以使用 vue 组件的生命周期(不支持 beforeDestroydestroyedbeforeUnmountunmounted),不可以使用 App、Page 的生命周期
  4. 视图层和逻辑层通讯方式与 WXS 一致,另外可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例,使用 callMethod 方法,去抛出方法、传值,类似于 vue 组件间 emit
  5. 注意逻辑层给数据时最好一次性给到渲染层,而不是不停从逻辑层向渲染层发消息,那样还是会产生逻辑层和视图层的多次通信,还是会卡
  6. 观测更新的数据在视图层可以直接访问到。
  7. APP 端视图层的页面引用资源的路径相对于根目录计算,例如:./static/test.js。
  8. APP 端可以使用 dom、bom API,不可直接访问逻辑层数据,不可以使用 uni 相关接口(如:uni.request)
  9. H5 端逻辑层和视图层实际运行在同一个环境中,相当于使用 mixin 方式,可以直接访问逻辑层数据。

演示代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<template>
<view>
<view :msg="msg" :change:msg="renderScript.receiveMsg" class="renderjs" id="renderjs-view"> {{msg}} </view>
<button @click="renderScript.emitData">直接调用renderjs中的emitData的方法</button>
<button @click="changeMsg" class="app-view">改变msg的值,直接调用renderjs中receiveMsg的值</button>
<button @click="renderScript.renferMsg">通过renderjs改变msg的值,同时调用renderjs中的emitData的方法</button>
</view>
</template>

<script>
export default {
data() {
return {
msg: "我是service层原来的msg"
};
},
methods: {
// 触发逻辑层出入renderjs数据改变
changeMsg() {
this.msg = "msg值改变了";
},
// 接收renderjs发回的数据
receiveRenderData(val) {
console.log("renderjs返回的值-->", val);
},
//接收renderjs发回的数据,同时触发:change:msg,调用enderjs中的emitData的方法
serviceClick(e) {
this.msg = e;
}
}
};
</script>

<script module="renderScript" lang="renderjs">
export default {
data() {
return {
name: "我是renderjs数据"
};
},
methods: {
renferMsg(event, ownerInstance) {
// 调用 service层的serviceClick方法,传值
ownerInstance.callMethod("serviceClick", {
test: "这是点击renderjs的区域,向service层传递变量"
});
},
// 接收逻辑层发送的数据
receiveMsg(newValue, oldValue, ownerVm, vm) {
console.log("msg变化了newValue", newValue);
console.log("msg变化了oldValue", oldValue);
console.log("msg变化了ownerVm", ownerVm);
console.log("msg变化了vm", vm);

this.$ownerInstance.callMethod("receiveRenderData", newValue); // 同 ownerVm.callMethod
},
// 发送数据到逻辑层
emitData(e, ownerVm) {
ownerVm.callMethod("receiveRenderData", this.name);
}
}
};
</script>