uniapp 无法操作DOM 结合 renderJS使用echarts

1 为什么要使用 renderjs

  • 某些h5端使用的插件涉及到大量的dom操作,无法跨端使用。
  • 直接运行在视图层,解决了视图层与逻辑层频繁通信导致的性能折损,让动画更流畅。
  • renderjs是一种可以直接运行在视图层(webview)中的js技术,可以在视图层操作dom。

2 兼容性

AppH5
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>
  • 32
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个在 `script module="echarts" lang="renderjs"` 标签中获取 DOM 对象的 Uniapp 案例: ```html <template> <view class="container"> <ec-canvas ref="myChart" @init="initChart" canvas-id="myChart" /> <button @click="getDom">Get DOM Object</button> </view> </template> <script> import { ECharts } from '@/components/ec-canvas/echarts'; export default { methods: { initChart(canvas, width, height) { const chart = ECharts.init(canvas, null, { width, height, }); chart.setOption({ // ECharts 配置项 }); this.chart = chart; }, getDom() { const { myChart } = this.$refs; const dom = myChart.$el.firstElementChild; console.log(dom); // 输出获取到的 DOM 对象 }, }, }; </script> ``` 在上面的代码中,我们使用了 `ec-canvas` 组件来绘制 ECharts 图表,并在 `initChart` 方法中初始化了图表。然后,在 `getDom` 方法中,我们通过 `$refs` 获取到了 `myChart` 对象,并使用 `myChart.$el.firstElementChild` 获取了该组件中的第一个子元素,即图表的 DOM 对象。最后,我们将获取到的 DOM 对象输出到控制台中。 需要注意的是,使用 `ec-canvas` 组件绘制图表时,需要在 `canvas-id` 属性中指定一个唯一的 ID,而且需要在 `init` 事件中初始化图表。同时,我们使用了 `ECharts.init` 方法来初始化图表,返回的 `chart` 对象包含了很多有用的方法。在本例中,我们将 `chart` 对象保存在了组件实例中,以便后续的操作

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值