手写实现el-form系列组件的核心逻辑 -- 练习组件通信
以前觉得element-ui肯定特别难写,最近在看组件通信,就试试写下el-form,当做练习了,这样以后自己也能试着看懂/开发高阶组件。
本文,一步步来,读者如果有耐心的话,最好也自己手敲一遍。
搭个架子
为了快捷方便,用vue create
创建个项目,因为喜欢pug,,装个npm i pug pug-plain-loader -D
先看看官网,关于el-form
使用的demo
,然后将重点复制到App.vue
,再新建相应的组件文件。
显示输入框
观察App.vue
el-form
起码有属性model
和rules
,还有个方法validate
- 因为
el-form-item
写在其内部,所以也肯定有slot
- 同理,
el-form-item
起码有属性label
和prop
,和slot
el-input
可以v-model
,而v-model
是value
和input
的语法糖
组件相互获取属性和事件
输入的时候,应该要判断输入值是不是有效。
输入是在el-input
那边,验证是在el-input-item
那边,那么就需要在el-input
调用el-input-item
的验证方法
但是呢,el-input-item
必须知道规则和值才能验证,换言之,需要知道el-form
的信息。
先考虑el-input-item
怎么拿到el-form
的属性
这两,这个demo里是父子组件的关系,但实际上,不一定,但起码是 前辈和后代的关系。
之前总结过,vue组件通信方式。
组件内部嵌套层级不确定,后代组件想要祖先组件数据的话,可考虑provide/inject
。
再考虑el-input
怎么调用el-input-item
的方法
同理,这两,这个demo里是父子组件的关系,但实际上,不一定,但起码是 前辈和后代的关系。
这里虽然也可用provide
,但是可以试试$parent
,毕竟一个el-input-item
通常只有一个el-input
。
$parent
很多时候需要用到递归,这里抛砖引玉下。
验证单个表单元素
这里引入async-validator,之前写过一个大概怎么使用
在el-form-item
里已经知道prop
/rule
,所以引入之后,就很简单了,这边加了一个显示错误信息的属性。
这样输入的时候,能实时验证。
当用户在App.vue
那边elForm.validate()
的时候,el-form
里的validate
是对所有表单元素的validate
进行了遍历,如果都是true,那就返回true
,否则就是false
。
所有表单元素,其实就是el-form-item
,综合组件通信方式,果断还是用下$children
,这里也一样要递归拿到el-form-item
。
至此,el-form的核心思路就完成了,重点是知道各种通信方式的方法和使用思路。
代码
github的代码这边用分支进行阶段操作,需要的话,可以练习下。
- 搭个架子 -
git checkout init
- 显示输入框 -
git checkout show-input
- 拿到el-form实例 -
git checkout provide
顺手写了个el-menu系列组件,实现核心逻辑,用到了递归组件,有兴趣可以看看