uniapp renderjs "只能行内调用, 不能通过方法调用" 学习

故障代码

app报错(h5正常), 说 echarts 为undefined。

<view class="content">
    <button @click="get" @touchend="update">update</button>
    <img src="" alt="我是alt" id="img"/>
</view>
<script>
	export default{
		methods: {
			get(){
				return this.echarts.uiGet(); //改为 @click="echarts.uiGet" 是正常的。 
			}
		}
	}
</script>
<script module="echarts" lang="renderjs">
	export default{
		methods:{
			uiGet(){
				const img = document.querySelector("#img");
				console.log(img.getAttribute("alt"))
			}
		}
	}
</script>

故障原因

与uniapp执行方式有关系(下面只讨论app下的模式)

ui与js分层

传统浏览器ui与js是执行在一个环境里的, 假如js任务很多,ui页面响应会变的缓慢。
而uniapp为了避免这个问题, 把ui放在了webview中,将用户执行的js放在jscore里(ios下)
jscore 是一个纯净的js执行环境, 没有浏览器的属性。
ui与jscore通过jsbridge进行通信。

uniapp编译与vue编译器行为不一致

这是因为uniapp魔改了vue的编译器, 正常vue2编译器会这样编译

<button @click="get"></button>

// render
with(this){return _c('button', {on: {click: get}})}

uniapp 会考虑@click里的表达式是不是引用的 renderjs模块的代码。判断方式如下图所示。

image

如果是, 在真实view层会生成相应的代码。

具体生成的render代码

// HBuilderX\plugins\uniapp-cli\node_modules\@dcloudio\uni-template-compiler\lib\index.js
// service 逻辑层
with(this){
    return _c('view',
        {staticClass:_$s(0,'sc',"content"),
        attrs:{"_i":0}},[
            _c('button',
                {attrs:{"_i":1},on:{"touchend":update}}),_c('img',{attrs:{"id":"img","_i":2}})])
}
// view 真实渲染层
with(this){
    return _c('uni-view',
        {staticClass:_$g(0,'sc'),
        attrs:{"_i":0}},
        [
            _c('v-uni-button',
                {attrs:{"_i":1},
                    on:{
                        "click":function($event){$event = $handleWxsEvent($event);echarts.uiGet($event, $getComponentDescriptor())},
                        "touchend":function($event){return $handleViewEvent($event)}}},[_v("update")]),
                        _c('img',{attrs:{"src":"","alt":"我是alt","id":"img","_i":2}})],1)}

posted @ 2024-05-06 20:21  re大法好  阅读(63)  评论(1编辑  收藏  举报