<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: tu6ge</title>
    <description>The latest articles on DEV Community by tu6ge (@tu6ge).</description>
    <link>https://dev.to/tu6ge</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F882615%2Fd29385aa-f178-4437-adac-dc8d9b3f4fcf.jpeg</url>
      <title>DEV Community: tu6ge</title>
      <link>https://dev.to/tu6ge</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tu6ge"/>
    <language>en</language>
    <item>
      <title>I’ve Decided to Redefine Two-Way Binding in Vue</title>
      <dc:creator>tu6ge</dc:creator>
      <pubDate>Tue, 26 Aug 2025 12:47:29 +0000</pubDate>
      <link>https://dev.to/tu6ge/ive-decided-to-redefine-two-way-binding-in-vue-3e5m</link>
      <guid>https://dev.to/tu6ge/ive-decided-to-redefine-two-way-binding-in-vue-3e5m</guid>
      <description>&lt;p&gt;In Vue, we already have the very convenient v-model syntax sugar. It handles two essential things for us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a JavaScript variable has a value, it fills the input field.&lt;/li&gt;
&lt;li&gt;When the input changes, the new value is passed back to JavaScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s basically what v-model does under the hood.&lt;/p&gt;

&lt;p&gt;So why redefine two-way binding?&lt;/p&gt;

&lt;p&gt;The reason is that I’ve been exploring a new approach to form validation. I believe the next generation of Vue form validators should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component-driven – the form behavior is powered by components, not configuration.&lt;/li&gt;
&lt;li&gt;Style-agnostic – no built-in styling, leaving developers free to define layouts.&lt;/li&gt;
&lt;li&gt;Flexible with UI libraries – should work seamlessly with input components from libraries like Naive UI, Element Plus, or even fully custom ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What existing validators do&lt;/p&gt;

&lt;p&gt;When I looked at existing solutions, I found a common pattern: each form field usually comes with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A label&lt;/li&gt;
&lt;li&gt;An input&lt;/li&gt;
&lt;li&gt;A help message&lt;/li&gt;
&lt;li&gt;An error message (shown when validation fails)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some libraries solve this by bundling their own input components and tightly integrating them with validation. While this works, it reduces flexibility.&lt;/p&gt;

&lt;p&gt;I wanted something different: a validator that lets developers use their own UI components, while still handling value binding and validation logic cleanly.&lt;/p&gt;

&lt;p&gt;The idea: u-field component&lt;/p&gt;

&lt;p&gt;To achieve this, I introduced the idea of a u-field component.&lt;br&gt;
You can put any input component into its slot.&lt;/p&gt;

&lt;p&gt;The u-field exposes two key bindings to its slot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;value&lt;/strong&gt; passes the form data down to the input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;update&lt;/strong&gt; sends the new input value back up to the form.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes synchronization possible, and sets the stage for validation.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;u-field&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ value, update }"&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"($event) =&amp;gt; update($event.target.value)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/u-field&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why not just v-model?&lt;/p&gt;

&lt;p&gt;Looking at Vue’s official docs, this is exactly the kind of code v-model was meant to simplify.&lt;br&gt;
But when binding with parent components (not just local state), we need another kind of syntax sugar.&lt;/p&gt;

&lt;p&gt;So, inspired by vue-macros, I created a Vite plugin to introduce a new directive: &lt;code&gt;f-model&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;f-model&lt;/code&gt;, the example above becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;u-field&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ value, update }"&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;f-model&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/u-field&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond text inputs&lt;/p&gt;

&lt;p&gt;Of course, text inputs are the simplest case.&lt;br&gt;
For other components like radio buttons, checkboxes, or selects, special handling is still needed.&lt;/p&gt;

&lt;p&gt;For third-party components, it’s straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;With a regular input:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;f-model&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;With Naive UI’s n-input (which uses v-model:value):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;n-input&lt;/span&gt; &lt;span class="na"&gt;f-model:value&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;vue-uform is still evolving, but I’d love to hear your feedback. Try it out on GitHub or play with the StackBlitz demos, and let me know what you think!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/tu6ge/vue-uform/" rel="noopener noreferrer"&gt;https://github.com/tu6ge/vue-uform/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;StackBlitz: vue-uform &amp;amp; tailwind &lt;a href="https://stackblitz.com/edit/vue-uform-tailwind?file=src%2FApp.vue" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/vue-uform-tailwind?file=src%2FApp.vue&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;StackBlitz: vue-uform &amp;amp; scheme &lt;a href="https://stackblitz.com/edit/vue-uform-tailwind-scheme?file=src%2FApp.vue" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/vue-uform-tailwind-scheme?file=src%2FApp.vue&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vue</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>vue-uform: A Component-First, Unstyled Form Validation Library for Vue 3</title>
      <dc:creator>tu6ge</dc:creator>
      <pubDate>Mon, 11 Aug 2025 12:23:42 +0000</pubDate>
      <link>https://dev.to/tu6ge/vue-uform-a-component-first-unstyled-form-validation-library-for-vue-3-2ijc</link>
      <guid>https://dev.to/tu6ge/vue-uform-a-component-first-unstyled-form-validation-library-for-vue-3-2ijc</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. The Problem with Most Form Libraries&lt;/strong&gt;&lt;br&gt;
When building forms in Vue, I’ve often found that existing solutions fall into one of two camps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Overly opinionated – They ship with a lot of styling and layout assumptions that don’t match your UI framework or design system.&lt;/li&gt;
&lt;li&gt;Too much boilerplate – Setting up form values, validation rules, and event handlers requires a ton of JS/TS code for even basic forms.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you’ve worked with frameworks like VeeValidate or FormKit, you know they are powerful, but sometimes you just want complete control over markup and styling, while still getting a declarative, maintainable form API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Enter vue-uform&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/tu6ge/vue-uform" rel="noopener noreferrer"&gt;vue-uform&lt;/a&gt; is my attempt to solve these pain points.&lt;br&gt;
It’s a unstyled, component-first form library for Vue 3.&lt;/p&gt;

&lt;p&gt;Key ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Component-first API – Fields, forms, and submit buttons are all Vue components.&lt;/li&gt;
&lt;li&gt;No built-in styles – You write your own HTML &amp;amp; CSS or use your favorite UI framework (Element Plus, Naive UI, Vuetify…).&lt;/li&gt;
&lt;li&gt;Composable validation – Built-in rules for common needs, plus an easy API for custom validators.&lt;/li&gt;
&lt;li&gt;f-model directive – A tiny Vite plugin that gives you v-model-like syntax for form fields, without repetitive boilerplate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Quick Start Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Form submitted:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;u-form&lt;/span&gt; &lt;span class="na"&gt;:values=&lt;/span&gt;&lt;span class="s"&gt;"formValues"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"doLogin"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;u-field&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Username"&lt;/span&gt; &lt;span class="na"&gt;validation=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ value, update }"&amp;gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;f-model&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/u-field&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;u-field&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt; &lt;span class="na"&gt;validation=&lt;/span&gt;&lt;span class="s"&gt;"required|min:6"&lt;/span&gt; &lt;span class="na"&gt;v-slot=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ value, update }"&amp;gt;
      &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;f-model&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/u-field&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;u-submit&amp;gt;&lt;/span&gt;Login&lt;span class="nt"&gt;&amp;lt;/u-submit&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/u-form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;&amp;lt;u-field&amp;gt;&lt;/code&gt; handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tracking the field’s value&lt;/li&gt;
&lt;li&gt;Running validation rules&lt;/li&gt;
&lt;li&gt;Passing data to the form&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The f-model directive is provided by @vue-uform/vite-plugin, which compiles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;f-model&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;into&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"value"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;input=&lt;/span&gt;&lt;span class="s"&gt;"$event =&amp;gt; update($event.target.value)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Built-in Validation Rules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Out of the box, you get:&lt;br&gt;
required, number, email, between, max, min, alpha, alphanumeric, starts_with, ends_with, url, and more.&lt;/p&gt;

&lt;p&gt;Example custom validator with parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;FieldNode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-uform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;minWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FieldNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;`Please enter at least &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; words.`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;u-field&lt;/span&gt;
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"bio"&lt;/span&gt;
    &lt;span class="na"&gt;validation=&lt;/span&gt;&lt;span class="s"&gt;"min_words:5"&lt;/span&gt;
    &lt;span class="na"&gt;:rules=&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;{ min_words: minWords }"
    v-slot="{ value, update }"
  &amp;gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;f-model&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/u-field&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Why This Works Well&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI Freedom – Works equally well with native HTML inputs or  from Naive UI,  from Element Plus, etc.&lt;/li&gt;
&lt;li&gt;Declarative Structure – The form is defined entirely in the template; minimal JS/TS logic is needed.&lt;/li&gt;
&lt;li&gt;Extensible – Add custom validation logic without hacking the core.&lt;/li&gt;
&lt;li&gt;Consistent API – Every field gets the same slot props (value, update, hasError).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Installation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install &lt;/span&gt;vue-uform
pnpm &lt;span class="nb"&gt;install&lt;/span&gt; @vue-uform/vite-plugin &lt;span class="nt"&gt;-D&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vite.config.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vitejs/plugin-vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;uForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue-uform/vite-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;vue&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nf"&gt;uForm&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-uform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;createApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7. Link&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/tu6ge/vue-uform" rel="noopener noreferrer"&gt;https://github.com/tu6ge/vue-uform&lt;/a&gt;&lt;br&gt;
StackBlitz: &lt;a href="https://stackblitz.com/%7E/github.com/tu6ge/vue-uform-example" rel="noopener noreferrer"&gt;https://stackblitz.com/~/github.com/tu6ge/vue-uform-example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Closing Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you like the flexibility of writing your own HTML &amp;amp; CSS but want the convenience of declarative form handling and validation, vue-uform might be a good fit.&lt;br&gt;
I’d love to hear your feedback, ideas, and PRs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>vue</category>
    </item>
    <item>
      <title>valitron 0.2.0 release</title>
      <dc:creator>tu6ge</dc:creator>
      <pubDate>Mon, 25 Sep 2023 02:38:05 +0000</pubDate>
      <link>https://dev.to/tu6ge/valitron-020-release-2dab</link>
      <guid>https://dev.to/tu6ge/valitron-020-release-2dab</guid>
      <description>&lt;p&gt;Valitron is an ergonomics, functional and configurable validator&lt;/p&gt;

&lt;h1&gt;
  
  
  Major
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Support generics validate message, and the can be used with build-in rules.&lt;/li&gt;
&lt;li&gt;Support conversion between validators of different message types.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Features
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;add bail in Validator&lt;/li&gt;
&lt;li&gt;support same filed multi insert rule &lt;/li&gt;
&lt;li&gt;build-in rule optimize and add documents&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
    </item>
    <item>
      <title>Next rust validator, should be ergonomics and functional</title>
      <dc:creator>tu6ge</dc:creator>
      <pubDate>Fri, 15 Sep 2023 08:17:15 +0000</pubDate>
      <link>https://dev.to/tu6ge/next-rust-validator-should-be-ergonomics-and-functional-13a3</link>
      <guid>https://dev.to/tu6ge/next-rust-validator-should-be-ergonomics-and-functional-13a3</guid>
      <description>&lt;p&gt;valitron is an new validator, It has multiple features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ergonomics validation&lt;/li&gt;
&lt;li&gt;Build-in rule, e.g. Required, StartWith ...&lt;/li&gt;
&lt;li&gt;Closure validate&lt;/li&gt;
&lt;li&gt;Related validate, e.g. password confirm&lt;/li&gt;
&lt;li&gt;Custom rule with other parameter&lt;/li&gt;
&lt;li&gt;Check / modify input data&lt;/li&gt;
&lt;li&gt;Custom error message&lt;/li&gt;
&lt;li&gt;collect validate error messages&lt;/li&gt;
&lt;li&gt;Support all types data on #[dervic(Serialize, Deserialize)]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/tu6ge/valitron"&gt;https://github.com/tu6ge/valitron&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
    </item>
  </channel>
</rss>
