父组件:
<template>
<div class="card flex justify-center">
<Form
:resolver
@submit="onFormSubmit"
class="flex flex-col gap-4 w-full sm:w-56"
>
<FormField
v-slot="$field"
name="username"
initialValue=""
class="flex flex-col gap-1"
>
<input
type="text"
placeholder="Username"
:class="[{ error: $field?.invalid }]"
v-bind="$field.props"
/>
<Message
v-if="$field?.invalid"
severity="error"
size="small"
variant="simple"
>{{ $field.error?.message }}
</Message>
</FormField>
<FormField
v-slot="$field"
name="password"
initialValue="PrimeVue"
class="flex flex-col gap-1"
>
<input
v-model="$field.value"
type="password"
placeholder="Password"
:class="[{ error: $field?.invalid }]"
@input="$field.onInput"
@blur="$field.onBlur"
@change="$field.onChange"
/>
<Message
v-if="$field?.invalid"
severity="error"
size="small"
variant="simple"
>{{ $field.error?.message }}
</Message>
</FormField>
<FormField v-slot="$field" name="testbind" initialValue="PrimeVu111e">
testbind 当前值:{{ $field.value }}
<!-- ✅ 正确绑定 -->
<TestBind :value="$field.value" v-bind="$field.props" />
<Message
v-if="$field?.invalid"
severity="error"
size="small"
variant="simple"
>{{ $field.error?.message }}
</Message>
</FormField>
<FormField v-slot="$field" name="testmodel" initialValue="PrimeVu111e">
testmodel 当前值:{{ $field.value }}
<p>使用props 接受value</p>
<!-- ✅ 正确绑定 -->
<TestModel v-model="$field.value" @input="$field.onInput" />
<Message
v-if="$field?.invalid"
severity="error"
size="small"
variant="simple"
>{{ $field.error?.message }}
</Message>
</FormField>
<FormField v-slot="$field" name="testmodel2" initialValue="PrimeVu111e">
testmodel2 当前值:{{ $field.value }}
<p>使用definedmodel</p>
<!-- ✅ 正确绑定 -->
<TestModel v-model="$field.value" @input="$field.onInput" />
<Message
v-if="$field?.invalid"
severity="error"
size="small"
variant="simple"
>{{ $field.error?.message }}
</Message>
</FormField>
<Button type="submit" severity="secondary" label="Submit" />
</Form>
{{ tesst1 }}
</div>
</template>
<script setup>
import { reactive, ref } from 'vue';
import { zodResolver } from '@primevue/forms/resolvers/zod';
import { z } from 'zod';
import { useToast } from 'primevue/usetoast';
import TestBind from '@/components/TestBind.vue';
import TestModel from '@/components/TestModel.vue';
const toast = useToast();
const tesst1 = ref();
const resolver = zodResolver(
z.object({
username: z.string().min(1, { message: 'Username is required.' }),
password: z.string().min(1, { message: 'Password is required.' }),
testbind: z.string(),
testmodel: z.string(),
testmodel2: z.string(),
})
);
const onFormSubmit = (res) => {
console.log(res);
console.log(res.values);
if (res.valid) {
toast.add({
severity: 'success',
summary: 'Form is submitted.',
life: 3000,
});
}
};
</script>
子组件:
<template>
<div>
<div>{{ model }}</div>
<Button @click="handleClick">切换</Button>
</div>
</template>
<script lang="ts" setup>
import { defineModel, watch } from 'vue';
const model = defineModel();
const emit = defineEmits(['input']);
// 模拟用户“输入”行为:比如点击改变值
function handleClick() {
emit('input', { target: { value: '1111111' } });
}
</script>
还有v-bind绑定$field.props
其他组件看源码:stackblitz.com/~/github.co…