1 为什么要使用 renderjs
- 某些h5端使用的插件涉及到大量的dom操作,无法跨端使用。
- 直接运行在视图层,解决了视图层与逻辑层频繁通信导致的性能折损,让动画更流畅。
- renderjs是一种可以直接运行在视图层(webview)中的js技术,可以在视图层操作dom。
2 兼容性
App | H5 |
---|---|
2.5.5+支持 | ✔ |
3 使用方式
设置 script 节点的 lang 为 renderjs
<script module="test" lang="renderjs"> export default { mounted() { // ... }, methods: { // ... } } </script>
4 注意事项
- 目前仅支持内联使用。
- 不要直接引用大型类库,推荐通过动态创建 script 方式引用。
-
可以使用 vue 组件的生命周期不可以使用 App、Page 的生命周期
- 视图层和逻辑层通讯方式与 WXS 一致,另外可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。
- 观测更新的数据在视图层可以直接访问到。
- APP 端视图层的页面引用资源的路径相对于根目录计算,例如:./static/test.js。
- APP 端可以使用 dom、bom API,不可直接访问逻辑层数据,不可以使用 uni 相关接口(如:uni.request)
- H5 端逻辑层和视图层实际运行在同一个环境中,相当于使用 mixin 方式,可以直接访问逻辑层数据。
5 renderjs模块内的生命周期
<!-- H5:所有 UNI 框架的生命周期都可使用 APP:仅可使用 VUE 组件生命周期 视图层与逻辑层可以重复定义生命周期,都会执行。 --> <!-- 逻辑层 --> <script> export default { onLoad() { console.log('逻辑层生命周期 - onLoad'); }, created() { console.log('逻辑层生命周期 - created'); }, mounted() { console.log('逻辑层生命周期 - mounted'); } } </script> <!-- 视图层 --> <script module="moduleName" lang="renderjs" type="module" > export default { onLoad() { console.log('视图层生命周期 - onLoad'); // 页面生命周期 APP 不会执行 H5 会执行 }, created() { console.log('视图层生命周期 - created'); // 组件生命周期 H5 APP 都会执行,重复定义也会执行,不会被覆盖。 }, mounted() { console.log('视图层生命周期 - mounted'); // 组件生命周期 H5 APP 都会执行,重复定义也会执行,不会被覆盖。 } } </script>
6 renderjs模块内的this指向
[^tip]: APP 端和 H5 端的this指向不同
<!-- 逻辑层 --> <script> export default { data() { return { str:"逻辑层的数据模型" } }, methods: { test() { return "调用逻辑层的方法" } } } </script> <!-- 视图层 --> <script module="moduleName" lang="renderjs" type="module" > export default { mounted() { console.log("尝试获取逻辑层的数据模型",this.str) // H5端可正常打印 APP打印undefined console.log("尝试调用逻辑层的方法",this.test()) // H5端可正常调用 APP端报错 } } </script>
7 视图层和逻辑层的通信方式
视图层可以通过this.$ownerInstance.callMethod('方法名', 传的值)
来和逻辑层进行通信
代码中 :变量名="变量值" :change:变量名=”renderjs模块上的方法“
change就是监听定义的变量发生改变---->触发视图层上的方法----->通过this.$ownerInstance.callMethod('方法名', 传的值)
给页面传参---->页面接收值---->渲染页面
示例代码:
<template> <view> <!-- 监听变量 operation 的变化,operation 发生改变时,调用 test 模块的 loadOperation 方法 --> <view :operation="operation" :change:operation="test.loadOperation"> <!-- 调用 test 模块的 clicked 变量 --> test模块:{{test.clicked}} </view> <br /> <view>您总共点击了 {{total}} 次</view> <br /> <button @click="onClick">点击</button> </view> </template> <script> export default { data() { return { operation: true, total:0, } }, methods: { onClick(e){ this.operation = !this.operation }, /** * 接收 renderjs 传过来的数据 * @param {Object} data */ reciveMessage(data) { this.total = data; } } } </script> <script module="test" lang="renderjs"> export default { data() { return { clicked: false, count: 0 } }, methods: { loadOperation(newValue, oldValue, ownerInstance, instance) { // 数据变更 console.log(newValue,oldValue,ownerInstance,instance) this.clicked = newValue; // 向uni-app页面组件发送信息 this.sendMsg(); }, sendMsg() { // 向页面传参 this.$ownerInstance.callMethod('reciveMessage', ++this.count) }, } } </script> <style> </style>
二、Uniapp中结合renderJS使用echarts
1.echarts引入方式(通过动态创建script方式引用)
html使用echarts的方式:
1.为 ECharts 准备一个具备高宽的 DOM 容器。
<body> <!-- 为 ECharts 准备一个具备大小(宽高)的 DOM --> <div id="main" style="width: 600px;height:400px;"></div> </body>
2.通过 echarts.init 方法初始化一个 echarts 实例
// 基于准备好的dom,初始化echarts实例 var myChart = echarts.init(document.getElementById('main'));
3.通过 setOption 方法生成一个简单的柱状图,
// 指定图表的配置项和数据 var option = { title: { text: 'ECharts 入门示例' }, tooltip: {}, legend: { data:['销量'] }, xAxis: { data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"] }, yAxis: {}, series: [{ name: '销量', type: 'bar', data: [5, 20, 36, 10, 10, 20] }] }; // 使用指定的配置项和数据显示图表。 myChart.setOption(option);
renderjs使用echarts的方式:(同html的使用方式大致相同)
1.为 ECharts 准备一个具备高宽的 DOM 容器。
<view class="content"> <view id="echarts" style="width:100%;height:300rpx"></view> </view>
2.引入renderjs, 动态引入echarts。原生操作dom 。将echarts引入
3.script标签上的onload事件加载完成后初始化echarts 实例
4.通过 setoption方法生成
<script module="echarts" lang="renderjs"> let myChart export default { mounted() { if (typeof window.echarts === 'function') { myChart = echarts.init(document.getElementById('echarts')) // 观测更新的数据在 view 层可以直接访问到 myChart.setOption(this.option) } else { // 动态引入较大类库避免影响页面展示 const script = document.createElement('script') // view 层的页面运行在 www 根目录,其相对路径相对于 www 计算 script.src = 'static/echarts.js' //script标签的onload事件都是在外部js文件被加载完成并执行完成后才被触发的 script.onload = ()=>{ myChart = echarts.init(document.getElementById('echarts'),) myChart.setOption(this.option) } document.head.appendChild(script) } }, methods: { } } </script>