我们知道在 vue 中,我们有一个很方便的语法糖 v-model,它帮助我们实现的数据的双向绑定,当 js 变量有值的时候,填充到 input 输入框中,当输入框中输入值后,将新值传递回 js ,这就是 v-model 底层做的两件事
那么我为什么要重新定义一个双向绑定呢?
原因在于,我最近在设想一种新的表单验证方案,我希望下一代的 vue 验证器应该是这样的,由组件驱动,不带内置样式,开发者可以灵活的定义组件的布局,这样开发者可以用这个方案实现自己的各种各样的页面展示效果。
我查阅了市面上很有优秀的验证器解决方案,发现他们有很多共同的特点,那就是每个表单字段都需要有标签,有输入框,有帮助信息,当输入验证失败时,需要显示验证失败的提示信息等等。
但是要实现这些功能,有的库的实现方式是内置了一些很优秀的输入框组件,来跟上述这些信息进行互动。但是我希望下一代的库,应该能够使用自定义的输入框,比如使用 naive-ui ,element-ui 等第三方库等输入框
所以说,要实现这个功能,就需要定义一个 form-field 这样的组件,把各种输入框组件放到这个组件的 slot 中,在这个组件中就需要给 slot 暴露出 value, update 这两个数据,第一个是向输入框传递数据,第二个是输入框数据变动时,向 form-field 组件传递数据,用来实现表单的数据同步,将来可以在这个组件上实现表单验证,按这个思路讲,我们要实现的代码大体会是这样的:
<form-field v-slot="{ value, update }">
<input :value="value" @input="$event => update($event.target.value)" />
</form-field>
查询 vue 的官方文档我们可以发现,这里面的代码是可以用 v-model 来简化的,但是要是跟我们所谓的父组件进行双向数据绑定,就需要另外的语法糖了
所以为了实现上述功能,我就参考 vue-macros 来开发了一个 vite 的插件,来实现了一个 f-model 的语法糖,使用语法糖简化后的代码是这样的
<form-field v-slot="{value,update}">
<input f-model />
</form-field>
当然,input 输入框的文本输入是最简单的一种情况,比如像单选,多选,下拉选择等,还是需要特殊处理的
对于第三方组件来说,v-model 可以直接对应改成 f-model, 而有的组件比如 naive-ui 中的 n-input, 是这样写的 v-model:value,那我们就可以写成这样 f-model:value
具体的文档和实现方式,可以参考 github
附 GitHub链接 github.com/tu6ge/vue-u…