Files
vue-formkit-example/src/App.vue
严浩 f9677d87b9
All checks were successful
/ surge (push) Successful in 38s
FormKitSchemaDefinition;
2024-11-15 15:25:11 +08:00

193 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { FormKitSchemaDefinition, getNode, type FormKitNode } from '@formkit/core';
import { onMounted } from 'vue';
async function submit(...args: any[]) {
console.debug('submit', `args :>> `, args);
await new Promise(r => setTimeout(r, 1000))
alert('Submitted! 🎉')
}
const castNumber = (node: FormKitNode) => {
node.hook.input((value, next) => next(Number(value)))
}
onMounted(() => {
const agreeNode = getNode('agreeNodeId')
Object.assign(window, { agreeNode })
console.debug('[onMounted]', `agreeNode :>> `, agreeNode);
const nameNode = agreeNode?.context?.node.at('attributes.name')
console.debug('[onMounted]', `nameNode :>> `, nameNode);
agreeNode!.on('commit', ({ payload }) => {
console.debug('[agreeNode] [on commit]', `payload :>> `, payload);
let newValue = (nameNode?.value as string)?.replace(' 👍', '')?.replace(' 👎', '')
nameNode!.input(`${newValue} ${payload ? '👍' : '👎'}`)
})
})
const addressSchema: FormKitSchemaDefinition = [
{
$formkit: 'group',
name: 'address',
children: [
{
$formkit: 'text',
name: 'street',
label: '街道地址',
validation: 'required',
validationLabel: '街道地址'
},
{
$formkit: 'text',
name: 'city',
label: '城市',
validation: 'required',
validationLabel: '城市'
},
{
$formkit: 'text',
name: 'zipCode',
label: '邮政编码',
validation: 'required|number|length:6',
validationLabel: '邮政编码',
errors: ['显式错误'] // 显式设置的错误是非阻塞的,这意味着它们不会像验证错误那样阻止表单提交。您可以在表单文档中了解更多有关错误处理的信息。
// :errors="errors"
}
]
}
];
</script>
<template>
<div class="bg-white rounded-xl shadow-xl p-8 mx-auto my-16 max-w-[450px]">
<FormKit
type="form"
#default="{ value }"
@submit="submit"
submit-label="提交 "
>
<div class="character-attributes">
<FormKit
type="group"
name="attributes"
id="attributes"
:validation-rules="{
validateGroup: (node) => {
const name = (node.value as Record<string, any>).name
return name?.includes('测试') ? true : false
}
}"
validation-visibility="live"
validation="validateGroup"
:validation-messages="{
validateGroup: ({ name/* , args */ }) => {
return `字段 ${name} 必须包含 '测试' 字符串。`
},
}"
#default="{ id, messages, fns, classes }"
>
<FormKit
type="text"
name="name"
label="姓名"
help="别人都叫你什么"
/>
<div
v-if="!((value?.attributes as any)?.name)?.includes('测试')"
class="text-red-500 mb-4 p-2 border border-red-500 rounded"
>
输入的姓名必须包含 '测试' 字符串。
</div>
<FormKit
type="checkbox"
name="flavors"
label="最喜欢的冰淇淋口味"
:options="{
'vanilla': '香草',
'chocolate': '巧克力',
'strawberry': '草莓',
}"
validation="required|min:2"
/>
<FormKit
type="range"
name="strength"
id="strength"
label="力量"
value="5"
validation="min:2|max:9"
validation-visibility="live"
min="1"
max="10"
step="1"
help="这个角色应该有多少力量点"
:plugins="[castNumber]"
class="mb-4"
/>
<!-- By default groups do not show validation messages, so we need to add it manually -->
<ul
class="error-box"
:class="classes.messages"
v-if="fns.length(messages)"
>
<li
v-for="message in messages"
:key="message.key"
:id="`${id}-${message.key}`"
:data-message-type="message.type"
>
{{ message.value }}
</li>
</ul>
</FormKit>
</div>
<div class="character-attributes">
<FormKitSchema :schema="addressSchema" />
</div>
<FormKit
type="checkbox"
name="agree"
id="agreeNodeId"
label="我同意FormKit是最好的表单开发框架"
class="mb-4"
/>
<pre class="font-mono text-sm p-4 bg-slate-100 mb-4">{{ value }}</pre>
</FormKit>
</div>
</template>
<style scoped>
.character-attributes {
padding: 1.5rem;
border: 1px solid #e5e7eb;
border-radius: 0.5rem;
margin-bottom: 1rem;
background-color: #f9fafb;
}
ul.error-box {
padding: 0.75rem;
border: 1px solid #ef4444;
border-radius: 0.375rem;
background-color: #fee2e2;
color: #b91c1c;
font-size: 0.875rem;
line-height: 1.25rem;
}
ul.error-box p {
font-weight: 500;
}
</style>