uni-app 外部js文件中修改vue组件数据状态成功但UI样式响应不及时

uni-app 外部js文件中修改vue组件数据状态成功但UI样式响应不及时

开发环境 版本号 项目创建方式
Mac macOS Big Sur 11.2.3 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Mac

PC开发环境操作系统版本号:macOS Big Sur 11.2.3

HBuilderX类型:正式

HBuilderX版本号:3.1.10

手机系统:iOS

手机系统版本号:IOS 14

手机厂商:苹果

手机机型:iphone6s Plus

页面类型:vue

打包方式:离线

项目创建方式:HBuilderX

### 示例代码:

.vue 中
```javascript
import { IMAudioManage} from "./IMKit.js"

<template>
<view>
<view v-for="(item, index) in chatList" :key="index">  
<div class="content" [@click](/user/click)="play(item)">  
<div :class="['common', item.isPlaying ? 'big':'big_0']"></div>  
<div :class="['common', item.isPlaying ? 'middle':'middle_0']"></div>  
<div class="common min"></div>   
</div>  
</view>  
</view>  
</template>

methods: {
play(messageModel){
IMAudioManage.playByMessage(messageModel)
}
}

IMKit.js中
const IMAudioManage = {
playByMessage(messageModel) {
messageModel.isPlaying = true
}
}

export { IMAudioManage}

操作步骤:

.vue 中

import { IMAudioManage} from "./IMKit.js"

<template>
<view>
<view v-for="(item, index) in chatList" :key="index">  
<div class="content" [@click](/user/click)="play(item)">  
<div :class="['common', item.isPlaying ? 'big':'big_0']"></div>  
<div :class="['common', item.isPlaying ? 'middle':'middle_0']"></div>  
<div class="common min"></div>   
</div>  
</view>  
</view>  
</template>

methods: {
play(messageModel){
IMAudioManage.playByMessage(messageModel)
}
}

IMKit.js中
const IMAudioManage = {
playByMessage(messageModel) {
messageModel.isPlaying = true
}
}

export { IMAudioManage}

预期结果:

类似微信的语音消息播放,点击播放,会有播放动画。如果当前正在播放,这时点击下一个,需要停止上一个播放动画,并开始当前播放动画

实际结果:

如果当前正在播放,这时点击下一个语音消息,被点击的视图不会出现播放动画,isPlaying 数据实际是已被修改成true ,但是ui响应不及时


更多关于uni-app 外部js文件中修改vue组件数据状态成功但UI样式响应不及时的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app 外部js文件中修改vue组件数据状态成功但UI样式响应不及时的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在 uni-app 中,直接修改外部 JS 文件中的对象属性时,Vue 的响应式系统可能无法及时检测到数据变化,导致 UI 更新延迟。这是因为 Vue 无法自动追踪在组件外部对对象属性的修改。

解决方案:

  1. 使用 Vue.set 或 this.$set
    IMKit.js 中通过 Vue.set 或组件实例的 $set 方法修改属性,确保触发响应式更新:

    // 在 IMAudioManage 中引入 Vue
    import Vue from 'vue'
    
    const IMAudioManage = {
      playByMessage(messageModel) {
        Vue.set(messageModel, 'isPlaying', true)
      }
    }
    
  2. 通过组件方法更新状态
    将状态修改逻辑放在 Vue 组件内,通过回调函数确保响应式更新:

    // .vue 文件中
    methods: {
      play(messageModel) {
        // 先停止其他播放项
        this.chatList.forEach(item => {
          if (item !== messageModel) {
            this.$set(item, 'isPlaying', false)
          }
        })
        // 播放当前项
        IMAudioManage.playByMessage(messageModel, () => {
          this.$set(messageModel, 'isPlaying', true)
        })
      }
    }
    
    // IMKit.js 中
    const IMAudioManage = {
      playByMessage(messageModel, callback) {
        // 播放逻辑
        callback()
      }
    }
    
  3. 使用深拷贝强制更新
    在修改数据后,通过重新赋值整个数组触发更新:

    this.chatList = [...this.chatList]
回到顶部