
在 InertiaJS 中, 属性无法生效,因为 v-model 会接管表单控件的状态;正确做法是直接初始化 useForm 的初始值,使其与预期默认选项一致。
在 inertiajs 中,`
在使用 InertiaJS 构建表单时,一个常见误区是试图通过 HTML 的 selected 属性(如 <option :value="id" selected></option>)来设定下拉菜单的默认选中项。然而,由于 v-model 是双向绑定的核心机制,它会完全控制 <select></select> 元素的当前值——任何静态 selected 属性都会被忽略,除非其对应的值恰好与 v-model 绑定的数据一致。
✅ 正确方案:初始化表单时指定默认值
你应将默认选中项的 ID(例如最新创建分类的 ID)作为 useForm 初始状态的一部分,而非依赖 DOM 属性:
// 假设后端已按 created_at 降序返回 categories,并取第一个作为默认
const productForm = useForm("createProduct", {
category_id: $page.props.categories.length > 0
? $page.props.categories[0].id
: null,
title: null,
price: null,
// ... 其他字段
});同时,在 Blade 模板中,确保将分类数据正确传递给前端:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
// resources/views/products/create.blade.php
<script>
const pageProps = @json([
'categories' => auth()->user()
? App\Models\Category::where('user_id', auth()->user()->id)
->orderByDesc('created_at')
->get(['id', 'name'])
: [],
]);
</script>? 提示:推荐只传递必要字段(如
id和name),避免序列化完整模型,提升性能与安全性。
? 前端 Select 组件写法(精简可靠)
<select
v-model="productForm.category_id"
name="category_id"
class="min-w-max text-sm text-gray-900 bg-transparent border-2 rounded-xl"
>
<option value="">— 请选择分类 —</option>
<option
v-for="category in $page.props.categories"
:key="category.id"
:value="category.id"
>
{{ category.name }}
</option>
</select>✅ 关键点:
- 移除冗余的
selected属性; - 确保
v-model绑定的productForm.category_id在初始化时已赋值为有效 ID; - 若需“无默认选择”,可设为
null或空字符串,并添加占位选项(如上例中的value="")。
⚠️ 注意事项
- 不要混用
v-model和:value+@change手动更新,这会导致状态不一致; - 若分类列表异步加载(如搜索后动态获取),需配合
watch或onMounted更新productForm.category_id; - 使用
$page.props.categories而非全局变量或额外 API 请求,符合 Inertia 的服务端预加载最佳实践。
通过将默认逻辑前置到表单初始化阶段,你不仅能解决 selected 失效问题,还能让数据流更清晰、可预测,真正发挥 InertiaJS 响应式表单的优势。

















