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

Vue.js日期输入表单在Safari中无法提交的问题求助

Vue.js 日期输入框清空后 Safari 无法提交表单的解决方案

问题重现

使用 Vue.js 3 的 <script setup> 编写表单,包含 type="date" 的输入框并绑定 v-model 到空字符串响应式变量。按以下步骤操作:

  • 选择一个日期
  • 点击 Clear 按钮清空日期值
  • 点击 Save 提交表单

Chrome 中可正常触发 submit 函数,但 Safari 17.2.1 中点击 Save 无响应,且 ValidityState 显示正常。相同逻辑的 React 代码可正常运行。

Vue 问题代码

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

const createdAt = ref('')

const submit = () => {
  console.log('submit')
}

const clear = () => {
  createdAt.value = ''
}
</script>

<template>
  <form @submit.prevent="submit">
    <label for="createdAt">CreatedAt</label>
    <input id="createdAt" type="date" v-model="createdAt" />
    <button type="button" @click="clear">Clear</button>
    <button>Save</button>
  </form>
</template>

原因分析

Safari 对 type="date" 输入框的空值处理与 Chrome 存在差异,Vue 的 v-model 绑定空字符串时,Safari 可能未正确同步输入框内部状态,导致表单默认提交行为被隐性拦截(即使 ValidityState 显示正常)。而 React 通过 onChange 直接赋值输入框 value,状态同步逻辑更直接,规避了该问题。

解决方案

方案1:清空时手动触发输入框的 input 事件

强制 Safari 识别输入框状态变化,确保表单提交逻辑正常触发:

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

const createdAt = ref('')
const createdAtInput = ref<HTMLInputElement | null>(null)

const submit = () => {
  console.log('submit')
}

const clear = () => {
  createdAt.value = ''
  // 手动触发input事件同步Safari输入框状态
  createdAtInput.value?.dispatchEvent(new Event('input', { bubbles: true }))
}
</script>

<template>
  <form @submit.prevent="submit">
    <label for="createdAt">CreatedAt</label>
    <input 
      ref="createdAtInput"
      id="createdAt" 
      type="date" 
      v-model="createdAt" 
    />
    <button type="button" @click="clear">Clear</button>
    <button>Save</button>
  </form>
</template>

方案2:显式声明 Save 按钮的 type="submit"

虽然浏览器默认按钮类型为 submit,但显式声明可避免 Safari 的隐性行为:

<template>
  <form @submit.prevent="submit">
    <!-- ...其他元素 -->
    <button type="submit">Save</button>
  </form>
</template>

方案3:清空时设置 null 而非空字符串

将响应式变量设为 null 能更好兼容 Safari 的日期输入框处理逻辑:

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

const createdAt = ref<string | null>(null)

const clear = () => {
  createdAt.value = null
}
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 11:47:39