我刚刚开始第一次一起使用 PrimeVue 和 VeeValidate,我正在为两种情况而苦苦挣扎。
InputNumber
,我尝试添加一个v-bind
数字,但是当我点击离开时该字段被清除,不确定这里发生了什么Dropdown
和MultiSelect
,它们分别是键/值对对象和键/值对对象数组,我似乎也无法验证它们。我什至无法在组件中正确选择数据...我尝试了 v-bind 和 v-model 但无法让它工作。我错过了什么?
<script setup lang="ts">
import { Form, Field } from 'vee-validate';
import { PropType } from 'vue';
import Button from 'primevue/button';
import InputText from 'primevue/inputtext';
import InputNumber from 'primevue/inputnumber';
import Textarea from 'primevue/textarea';
import Dropdown from 'primevue/dropdown';
import MultiSelect from 'primevue/multiselect';
import * as yup from 'yup';
import { categoryToLabel, availabilityToLabel } from '@/helpers/dishes';
import { useRouter } from 'vue-router';
import { Dish, DishCategory, DishAvailability } from '@/types/Dish';
import { createOrUpdateDish } from '@/api/Dish';
const router = useRouter();
const { dish } = defineProps({
// Optional - Dish to update
dish: {
type: Object as PropType<Dish>,
},
});
const initialValues = {
name: dish?.name || '',
description: dish?.description || '',
price: dish?.price || null,
category: dish?.category
? {
name: categoryToLabel.get(dish.category),
value: dish.category,
}
: {},
availability: dish?.availability
? dish.availability.map((availability) => ({
name: availabilityToLabel.get(availability),
value: availability,
}))
: [],
waitingTime: dish?.waiting_time || null,
};
const schema = yup.object({
name: yup.string().required(),
description: yup.string().required(),
price: yup.number().required().positive().integer(),
category: yup.object().shape({ name: yup.string(), value: yup.string() }),
availability: yup.array().required().min(1),
waitingTime: yup.number().required().positive().integer(),
});
const categoryOptions = ['starter', 'main_course', 'dessert', 'beverage'].map(
(category: DishCategory) => ({
name: categoryToLabel.get(category),
value: category,
})
);
const availabilityOptions = [
'breakfast',
'lunch',
'dinner',
'weekdays',
'weekends',
].map((availability: DishAvailability) => ({
name: availabilityToLabel.get(availability),
value: availability,
}));
const onCancelClicked = () => {
router.push('/');
};
const onFormSubmitted = async (values: typeof initialValues) => {
console.log('values :>> ', JSON.stringify(values, null, 2));
};
</script>
<template>
<div class="max-width-container dish-creation">
<h2 class="title">Dish {{ dish ? 'update' : 'creation' }} form</h2>
<Form
class="form"
:initial-values="initialValues"
:validation-schema="schema"
@submit="onFormSubmitted"
>
<Field name="name" v-slot="{ field, errorMessage }">
<div class="form__row">
<label for="name">Name</label>
<InputText
v-bind="field"
aria-describedby="name-help"
:class="{ 'p-invalid': errorMessage }"
/>
<small id="name-help" class="p-error">{{ errorMessage }}</small>
</div>
</Field>
<Field name="description" v-slot="{ field, errorMessage }">
<div class="form__row">
<label for="description">Description</label>
<Textarea
id="description"
v-bind="field"
autoResize
rows="5"
cols="30"
aria-describedby="descripition-help"
:class="{ 'p-invalid': errorMessage }"
/>
<small id="description-help" class="p-error">{{
errorMessage
}}</small>
</div>
</Field>
<Field name="price" v-slot="{ field, errorMessage }">
<div class="form__row">
<label for="price">Price</label>
<InputNumber
id="price"
v-bind:number="field"
inputId="withoutgrouping"
:useGrouping="false"
:class="{ 'p-invalid': errorMessage }"
aria-describedby="price-help"
/>
<small id="price-help" class="p-error">{{ errorMessage }}</small>
</div>
</Field>
<Field name="category" v-slot="{ value, errorMessage, handleChange }">
<div class="form__row">
<label for="category">Category</label>
<Dropdown
@update:model-value="handleChange"
:model-value:="value"
:options="categoryOptions"
id="category"
optionLabel="name"
optionValue="value"
placeholder="Category"
aria-describedby="category-help"
:class="{ 'p-invalid': errorMessage }"
/>
</div>
</Field>
<Field name="availability" v-slot="{ value, errorMessage, handleChange }">
<div class="form__row">
<label for="availability">Availability</label>
<MultiSelect
@update:model-value="handleChange"
:model-value:="value"
:maxSelectedLabels="3"
:options="availabilityOptions"
optionLabel="name"
placeholder="Availability"
:class="{ 'p-invalid': errorMessage }"
/>
</div>
</Field>
<Field name="waitingTime" v-slot="{ field, errorMessage }">
<div class="form__row">
<label for="waiting-time">Waiting time (in mins)</label>
<InputNumber
id="waiting-time"
v-bind:number="field"
inputId="withoutgrouping"
:useGrouping="false"
aria-describedby="waiting-time-help"
:class="{ 'p-invalid': errorMessage }"
/>
<small id="waiting-time-help" class="p-error">{{
errorMessage
}}</small>
</div>
</Field>
<div class="form__row">
<Button
type="button"
label="Cancel"
severity="secondary"
icon="pi pi-times"
iconPos="right"
@click="onCancelClicked"
raised
/>
<Button
type="submit"
:label="dish ? 'Update' : 'Create'"
icon="pi pi-check"
iconPos="right"
raised
/>
</div>
</Form>
</div>
</template>
也在寻找如何做到这一点的答案(示例)。