You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue中Ref值变更时HTML无法持续更新问题排查

解决Vue中WebSocket状态无法实时更新的问题

问题描述

用类封装WebSocket连接,通过Ref<number>存储连接的readyState,并在模板中展示该状态。WebSocket的open和close事件会触发Ref值变更,控制台能看到状态确实变化,但HTML仅在首次加载时更新,后续状态变更无法同步到页面。

问题根源

每次调用doConnect()方法时,都会创建新的WebSocket实例,同时重新执行this.wsState = ref(ws.readyState)——这相当于生成了一个全新的Ref对象。而模板绑定的是初始化阶段从ws实例解构出来的旧Ref对象,后续更新的是新Ref的value,模板没有关联到新的Ref,因此页面不会同步更新。

之前测试this.wsState.value++能生效,是因为那时候没有重新创建Ref,更新的还是模板绑定的旧Ref的value,所以能触发响应式更新。

修复方案

只初始化一次Ref对象,后续仅更新Ref的value,不重新赋值Ref:

<script setup>
import { ref } from 'vue';
class Ws {
  ws; // WebSocket实例
  wsState; // 唯一的Ref对象
  constructor() {
    // 先初始化Ref,避免后续重复创建
    this.wsState = ref(0);
    this.doConnect();
  }
  doConnect() {
    const ws = new WebSocket('wss://ws.ifelse.io/');
    this.ws = ws;
    // 直接更新已有Ref的value,不创建新Ref
    this.wsState.value = ws.readyState;
    ws.onopen = () => this.updateWsState();
    ws.onclose = () => this.updateWsState();
    ws.onerror = (e) => console.error(`ws err:`, e);
  }
  updateWsState() {
    this.wsState.value = this.ws.readyState;
    console.log(`ws state ${this.wsState.value}`);
  }
  toggleConnect() {
    if (
      this.ws.readyState === this.ws.CLOSED ||
      this.ws.readyState === this.ws.CLOSING
    ) {
      this.doConnect();
    } else {
      this.ws.close();
    }
  }
}
const ws = new Ws();
const { wsState } = ws;
</script>

<template>
  <ul>
    <li>0 CONNECTING</li>
    <li>1 OPEN</li>
    <li>2 CLOSING</li>
    <li>3 CLOSED</li>
  </ul>
  <p>ws state: {{ wsState }}</p>
  <button @click="ws.toggleConnect">toggle connect</button>
</template>

这样模板始终绑定同一个Ref对象,后续所有状态变更都会通过更新该Ref的value触发页面响应式更新。

内容的提问来源于stack exchange,提问作者Jackoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:53:27