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

Vue3中details标签ToggleEvent无法访问newState/oldState属性问题

问题

在Vue 3.3.4 + TypeScript 5.2项目中使用HTML <details> 标签时,按规范点击该标签应触发ToggleEvent,且事件对象应包含newState和oldState属性,但实际无法获取这两个属性。

示例代码如下:

<template>
  <details @toggle="onMyToggle">
    <summary>My Title</summary>
    Details....
  </details>
</template>

<script setup lang="ts">
function onMyToggle(e: ToggleEvent) {
  console.log(e);

  if (e.newState === "open") {
    console.log("It's open now!");
  } else {
    console.log("It's closed now!");
  }
}
</script>

<style scoped></style>

在Chrome 117和FireFox 118中测试,两个浏览器均宣称支持该事件,Vue已将事件传递给处理函数,但打印的事件对象中缺失newState和oldState属性,控制台输出为:

toggle { target: details, isTrusted: true, srcElement: details, currentTarget: details, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, … }
解决方法

原因分析

目前主流浏览器(包括Chrome、Firefox)虽然支持<details>的toggle事件,但并未实现规范中定义的ToggleEvent接口的newState和oldState属性。浏览器实际触发的只是一个普通的Event对象,而非标准的ToggleEvent。

替代方案

既然无法直接获取newState/oldState,可以通过读取<details>元素的open属性来判断当前状态,有两种实现方式:

方式一:使用Vue的ref获取元素

<template>
  <details @toggle="onMyToggle" ref="detailsRef">
    <summary>My Title</summary>
    Details....
  </details>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const detailsRef = ref<HTMLDetailsElement | null>(null);

function onMyToggle() {
  if (!detailsRef.value) return;
  
  const isOpen = detailsRef.value.open;
  console.log(isOpen ? "现在展开了!" : "现在收起了!");
}
</script>

<style scoped></style>

方式二:通过事件目标直接获取状态

无需额外定义ref,直接从事件对象的target属性读取元素状态:

<template>
  <details @toggle="onMyToggle">
    <summary>My Title</summary>
    Details....
  </details>
</template>

<script setup lang="ts">
function onMyToggle(e: Event) {
  const detailsEl = e.target as HTMLDetailsElement;
  const isOpen = detailsEl.open;
  console.log(isOpen ? "现在展开了!" : "现在收起了!");
}
</script>

<style scoped></style>

补充说明

  • ToggleEvent的newState/oldState属性目前仍处于规范草案阶段,尚未被主流浏览器落地实现,这是问题的核心原因。
  • 直接使用<details>的open属性是当前最可靠的跨浏览器方案,所有支持<details>的浏览器都支持该属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 13:19:53