#13888·vant

[Bug Report] van-form点击"添加"动态插入 v-for 字段后,validate-first 首个报错字段错乱(后面的字段被排到最前)

Author: alongcaiCreated Aug 3, 2026Updated Sep 4, 2026
Labelsbug: need confirm

Reproduction Link

1

Vant Version

4.10.2

Describe the Bug

初步定位:van-field 挂载时 link() 会触发一次基于"当前时刻" vnode 树的 sortChildren。插入点之后的字段此刻尚未被 Vue patch,其 instance.vnode 仍是旧对象 → flattenVNodes 找不到 → findVNodeIndex 返回 -1 → 这批字段被稳定排序整体移到注册表最前;之后没有新的 link(),错序不会自愈。

Reproduce Steps

<script setup>
import { ref, reactive } from 'vue'
import { showToast } from 'vant'
import 'vant/lib/index.css'

const formRef = ref()
const form = reactive({ name: '', type: '', list: [] })

const onAdd = () => form.list.push({ name: '' })

const onSubmit = () => {
  formRef.value.validate()
    .then(() => showToast('通过'))
    .catch((errors) => {
      console.log('首错 name =', errors && errors[0]?.name)
      console.log('完整顺序 =', errors && errors.map(e => e.name))
    })
}
</script>

<template>
  <van-form ref="formRef" required validate-first scroll-to-error>
    <!-- 前面的必填 -->
    <van-field
      v-model="form.name"
      name="name"
      label="姓名"
      placeholder="姓名"
      clearable
      :rules="[{ required: true, message: '请输入姓名' }]" />
    <!-- 动态插入块 -->
    <van-button block type="primary" plain style="margin: 8px 0;" @click="onAdd">添加</van-button>
    <template v-for="(item, i) in form.list" :key="i">
      <van-field
        v-model="form.list[i].name"
        :name="'row' + i"
        label="姓名"
        placeholder="姓名"
        clearable
        :rules="[{ required: true, message: '请输入姓名' }]" />
    </template>
    <!-- 后面的必填 -->
    <van-field
      v-model="form.type"
      name="type"
      label="类别"
      placeholder="请选择"
      readonly
      is-link
      :rules="[{ required: true, message: '请选择类别' }]" />
    <div style="margin: 16px">
      <van-button round block type="primary" @click="onSubmit">校验</van-button>
    </div>
  </van-form>
</template>

Device / Browser

No response