button组件还可以双向绑定,自定义组件也可以进行表单校验,当然了,element的表单验证是那么好用的,我们自定义的组件想向el-input等组件一样,肯定行的,今天就分享具体的实现
我想二次封装el-button组件,我还想双向绑定,我还想进行表单校验?可能吗,是可能的,先封装个button组件
1.组件的双向绑定
<template>
<el-button @click="clickHandle">{{ name }}</el-button>
</template>
<script>
export default {
model: {
prop: 'name',
event: 'change'
},
props: {
name: Number
},
data() {
return {
count: 1
};
},
methods: {
clickHandle() {
this.count++;
let value = this.name + this.count;
this.$emit('change', value);
}
}
};
</script>
我们实验一下这个组件有没有效果,引入这个组件vc-button组件,并进行双向绑定
<template> <vc-button v-model="name"></vc-button> <el-button @click="clickHandle">改变大小</el-button>
</template><script>
import VcButton from './vc-button';export default { components: { VcButton },
data(){
return {
name:0
}
},
methods: { clickHandle() { this.name = 2 } }
</script>
结果:
点击vc-button值在往上累加
点击el-button组件改变name值=2
这个说明啥,说明双向绑定成功了,感觉有点怪是吧,双向绑定不应该是表单组件想input checkbox那样的组件吗,No,只要你想都可以双向绑定,而举这个例子就是想告诉大家,双向绑定不是input的专利,不要局限自己的思维
2.表单验证
我们经常会遇到表单验证的情况,可表单就那几个,很多情况是我们自定义的组件,还有一些是我们二次封装的组件,很想和el-input这样的校验一样写个rule就可以了,这样即可以保持页面的整体一致,浑然天成
先写代码,给我们刚写的组件加入表单验证
<template> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px"> <el-form-item label="活动区域" prop="name"> <vc-button v-model="ruleForm.name"></vc-button> </el-form-item> <el-button @click="clickHandle">校验</el-button> </el-form></template><script>import VcButton from './vc-button';export default { components: { VcButton }, data() { const validateName = (rule, value, callback) => { if (value < 1) { callback(new Error('你小了')); } else if (value < 20) { callback(); } else { callback(new Error('你咋那么大')); } }; return { ruleForm: { name: 0 }, rules: { name: [{ validator: validateName, trigger: 'change' }] } }; }, methods: { clickHandle() { this.$refs['ruleForm'].validate((valid) => { if (valid) { this.$message.success('我成功了'); } else { this.$message.success('我没通过校验!'); return false; } }); } }};</script>
点击校验就是这个样子,可以校验啊,没毛病啊
确实是可以的,但这个只有在点击校验的时候才会去校验,那我想改变值得时候校验呢?
值变化了,但是提醒还是在,咋整?
看看elementui的官方的github中el-input的实现,一个是失去焦点的事件,一个是当值改变时的事件
dispatch('ElFormItem', 'el.form.blur', [this.value])
dispatch('ElFormItem', 'el.form.change', [val]);
是不是看到这个很有感觉,表单验证rules中的trigger取值是不是就这
handleBlur(event) {this.focused = false; this.$emit('blur', event); if (this.validateEvent) { this.dispatch('ElFormItem', 'el.form.blur', [this.value]); } },
value(val) { this.$nextTick(this.resizeTextarea); if (this.validateEvent) { this.dispatch('ElFormItem', 'el.form.change', [val]); } },
在vue1.0中有这个broadcast,vue2之后就抛弃了,用官方的话说就是:
因为基于组件树结构的事件流方式实在是让人难以理解,并且在组件结构扩展的过程中会变得越来越脆弱。这种事件方式确实不太好,我们也不希望在以后让开发者们太痛苦。并且 broadcast 也没有解决兄弟组件间的通信问题。
那elementui 为什么借鉴这个实现呢?
大家可以看一下github上的源码
首先先引入
import dispatch from 'element-ui/lib/mixins/emitter.js';
然后混入
mixins: [dispatch]
好了下面就可以直接使用dispatch了
改一下vc-button这个自定义组件
clickHandle() { this.count++; let value = this.name + this.count; this.$emit('change', value); this.dispatch('ElFormItem', 'el.form.change', [value]); }
来吧,见证一下奇迹:
你点击按钮就会发现,变了,验证有效果了
今天就介绍到这,掘金说我写多了,保存不了,删了一部分,全选粘贴后排版就成这样了,说实话,这个掘金编辑器真的不太好用,尤其这个代码编辑器,将就吧,喜欢就点个赞,关注一下,谢谢