1、先说原因:renderjs和普通的js不同,如果想在<script module="echarts" lang="renderjs">获得<script>中的数据,虽然也是用this,但是这个this中的所有回调函数都会被私有化,读不出来。
2、举例:

<script>
	export default {
		data(){ // 原始情况是在prop中的,这里直接写在data
			return{
				option:{
					...... // 省略option中其他设定
					tooltip:{
						...... // 省略tooltip中其他设定
						formatter:e=>{console.log('我是formatter函数')}
					}
				}
			}
		}
	}
</script>
<script module="echarts" lang="renderjs">
export default {
	mounted(){
		console.log(this.option.tooltip.formatter) //打印出来的是:function () { [native code] }
		// 因此在this.chart.setOption的时候,这个设定就失效了
	}
}
</script>

3、解决办法
(I)既然renderjs读不到普通js中的内容,在renderjs中写formatter函数即可

<script module="echarts" lang="renderjs">
export default {
	mounted(){
		this.option.tooltip.formatter=e=>{console.log('我是formatter函数')} // 添加这句,在this.chart.setOption之前重新设定tooltip.formatter
		this.chart.setOption(this.option)
	}
}
</script>

(II)因为想组件化,只想用一个renderjs统筹管理所有的echart,又想到一个方法:
既然renderjs中不支持从js中接收函数类型。那么,先从js中接收一个字符串,再在renderjs中把这个字符串转换成函数。
函数转换成字符串有tostring方法,字符串转函数没原型链上的方法,查到一个String.prototype.toFunction=function(){ return eval('('+this+')')}; //作者@行列[xxooyy],直接绑到原型链或者renderjs中的methord中写一个方法都可以。

4、最终解决以后的代码
文件目录:
———static——echarts.js // echart官网下载的js压缩文件
∟——components——echart.vue // echart组件
∟——index.vue // 主要页面

// index.vue 中的代码
<template>
	<view>
		<echarts style="{'height': 500px}" :option="option"></echarts>
	</view>
</template>
<script>
	import echarts from '@/components/echart.vue'
	export default {
		components:{
			echarts
		},
		data() {
			return {
				option: { // 删减后,不确定有没有删掉必要的设定
					tooltip: {
						show: true,
						formatterFunction:`function(params) { 
							return 'asf'
						}` // 这里不是formatter,而是formatterFunction,因为echart原有的更新是增量式的,当然如果没更新功能,则用啥都无所谓。(怎么看有无更新:this.chart.setOption(option, option.notMerge)中有无第二个入参)
						// 所以这里不如直接当做有更新来处理,万无一失。
						// 如果检测formatter的有无,来改变formatter自己,会无限循环。
						// 举例:xAxis.data变化,echart.js会构造一个新的option,其内容为option:{xAxis:{data:[xxxxxxx,xxxx,x,x,x,xx,x]}},重新绘图。
						// 回到formatter: 检测formatter的有无 -> 改变formatter -> 生成新option{formatter:xxxxxx} -> 检测formatter的有无 -> 改变formatter ......无限循环
						// 使用formatterFunction:检测formatterFunction的有无 -> 改变formatter -> 生成新option{formatter:xxxxxx} -> 检测formatterFunction的有无 -> 无 -> 停止
					},
					xAxis: {
						type:'category',
						data: ["2022-02-10","2022-02-11","2022-02-12"] // x轴数据
					},
					yAxis: {
					    type: 'value',
					},
					series: [{
						type: 'bar',
						data: [15,20,25], // y轴数据
					}]
				},
		}
	}
</script>
// echart.vue 中的代码
<template>
		<view class="echarts" :prop="option" :change:prop="echarts.update"></view>
</template>
 
<script>
	export default {
		name: 'Echarts',
		props: {
			option: {
				type: Object,
				required: true
			},
		}
	}
</script>
 
<script module="echarts" lang="renderjs">
	export default {
		data() {
			return {
				chart: null
			}
		},
		mounted() {
			if (typeof window.echarts === 'object') {
				this.init()
			} else {
				// 动态引入类库
				const script = document.createElement('script')
				script.src = '@/static/echarts.js'
				script.onload = this.init
				document.head.appendChild(script)
			}
		},
		methods: {
			/**
			 * 初始化echarts
			 */
			init() {
				this.chart = echarts.init(this.$el)
				this.update(this.option)
			},
			/**
			 * 监测数据更新
			 * @param {Object} option
			 */
			update(option) {
				if (this.chart) {
					// 因App端,回调函数无法从renderjs外传递,故在此自定义设置相关回调函数
					if (option) {
						// tooltip
						if (option.tooltip) {
							if (option.tooltip.formatterFunction){
								console.log(1111111)
								option.tooltip.formatter=this.toFunction(option.tooltip.formatterFunction)
							}
						}
                    // 设置新的option
					this.chart.setOption(option, option.notMerge)
					}
					
				}
			},
			/**
			 * 字符串类型转换成函数类型(renderjs不支持函数类型的传递)
			 * @param {Object} value
			 */
			toFunction(e){
				return eval('('+e+')')
			}
		}
	}
</script>
 
<style lang="scss" scoped>
	.echarts {
		width: 100%;
		height: 100%;
	}
</style>
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐