uni-app 在 h5 应用中,某种情况下 wxs 的 instance.callMethod 方法失效

uni-app 在 h5 应用中,某种情况下 wxs 的 instance.callMethod 方法失效

开发环境 版本号 项目创建方式
Windows 1907 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Windows

HBuilderX类型:正式

HBuilderX版本号:3.0.7

手机系统:Android

手机系统版本号:Android 11

手机厂商:模拟器

手机机型:模拟器

页面类型:vue

打包方式:离线

项目创建方式:HBuilderX

### 示例代码:

```html
<template>  
    <view class="content" @touchstart="test.touchstart">  
        <image class="logo" src="/static/logo.png"></image>  
        <view class="text-area">  
            <text class="title">{{title}}</text>  
        </view>  
        <view v-if="text">  
            <view v-for="s of text">{{s}}</view>  
        </view>  
    </view>  
</template>  

<script module="test" lang="wxs">  
    function fixInstance(instance){  
        var pageInstance = {}  
        pageInstance['$el'] = instance['$el']  
        pageInstance['$vm'] = instance['$vm']  
        pageInstance.__proto__ = instance.__proto__  
        while(!pageInstance['$vm']['$home']){  
            pageInstance['$vm'] = pageInstance['$vm']['$parent']  
        }  
        return pageInstance  
    }  
    function touchstart(e, instance){  
        console.log('instance')  
        console.log(instance.$vm._uid)  
        console.log(instance.$vm)  
        instance.callMethod('updateText')  
    }  

    module.exports = {touchstart}  
</script>  

<script>  
    export default {  
        data() {  
            return {  
                title: 'Hello',  
                text: '',  
                n: 3,  
                timer: null,  
            }  
        },  
        onLoad() {  
            this.timer = setInterval(() => {  
                if(this.n-- === 0){clearInterval(this.timer)}  
                this.updateText()  
            }, 100)  
        },  
        methods: {  
            updateText(){  
                this.text || (this.text = [])  
                this.text.push(new Date().getTime())  
                console.log('update text')  
            }  
        },  
        mounted(){  
            console.log(this._uid)  
            this.$home = 'root'  
        }  
    }  
</script>  

<style>  
    .content {  
        display: flex;  
        flex-direction: column;  
        align-items: center;  
        justify-content: center;  
    }  

    .logo {  
        height: 200rpx;  
        width: 200rpx;  
        margin-top: 200rpx;  
        margin-left: auto;  
        margin-right: auto;  
        margin-bottom: 50rpx;  
    }  

    .text-area {  
        display: flex;  
        justify-content: center;  
    }  

    .title {  
        font-size: 36rpx;  
        color: #8f8f94;  
    }  
</style>  

操作步骤:

取消注释 onLoad 方法的代码,定时器结束后,点击 logo,触发 wxs 的 touchstart 函数,此时调用 callMethod ,页面 text 并没有更新。

预期结果:

点击 logo,title 下的 text 多一行,callMethod 调用成功

实际结果:

没有多一行,也没有报错

bug描述:

在 h5 应用中,快速更新了 vue 的 data 后,wxs 的 callMehod 失效,失效的原因是,wxs 获取到的 instance.$vm 已经不含有相应的 vue 的 methods,data等。其 instance 的父节点上才存在相应的方法。

bug-demo.zip


更多关于uni-app 在 h5 应用中,某种情况下 wxs 的 instance.callMethod 方法失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

问题确认,已加分,后续修复

更多关于uni-app 在 h5 应用中,某种情况下 wxs 的 instance.callMethod 方法失效的实战教程也可以访问 https://www.itying.com/category-93-b0.html


HBuilderX 3.1.4 alpha 已修复

大佬,renderjs也存在这个问题,有时间能修复一下吗?

回复 秋云: 收到,将会排查

这是一个已知的uni-app在H5环境下的WXS调用问题。问题核心在于WXS获取的instance.$vm在快速数据更新后会丢失Vue实例方法。

解决方法:

  1. 使用您代码中已有的fixInstance方法修复instance对象:
function touchstart(e, instance){
    instance = fixInstance(instance)
    instance.callMethod('updateText')
}
  1. 或者更简单的方案是直接使用Vue的$emit代替callMethod:
function touchstart(e, instance){
    instance.$vm.$emit('updateText')
}
  1. 在Vue组件中监听这个事件:
mounted(){
    this.$on('updateText', this.updateText)
}
回到顶部