By
被删
更新日期:
最近在使用 Vue2 作为项目中前端的框架,《Vue2 使用笔记》系列用于记录过程中的一些使用和解决方法。本文记录封装自定义的表单组件的过程。
自定义的表单组件
我们在很多场景下,需要对一些表单组件封装一些逻辑,如上一节的日期选择、常见的搜索功能等。本节我们来讲述下一个使用 select2 插件的自定义下拉组件的封装过程吧。
自定义事件
每个 Vue 实例都实现了事件接口,即:
- 使用
$on(eventName)
监听事件
- 使用
$emit(eventName)
触发事件
更多的时候,我们会组件封装的时候使用,例如我们这么一个组件,点击会触发 clickMe 事件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <div @click="clickMe">点击我啊</div> </template>
<script> export default { name: "ClickMe", methods: { clickMe(){ this.$emit('clickMe', 11111) } } }; </script>
|
我们可以这么去监听这个事件:
1
| <ClickMe @clickMe="dealWithClick($event)" />
|
我们绑定了一个dealWithClick
的方法,这里传进去的 $event 则是 11111。这是个简单的自定义事件的例子,当然我们也可以直接在父组件里面使用$on('dealWithClick')
来监听事件。
使用自定义事件的表单输入组件
自定义事件可以用来创建自定义的表单输入组件,使用 v-model 来进行数据双向绑定。但其实不管是在 Angular 还是在 Vue 中,双向绑定都只是语法糖。
在 Vue 里,我们常用的 v-model:
1
| <input v-model="something">
|
其实相当于下面的简写:
1
| <input @value="something" @input="something = $event.target.value">
|
所以我们如果需要自定义 v-model,需要做两个事情:
- 接受一个
value
prop。
- 在有新的值时触发
input
事件并将新值作为参数。
默认情况下,一个组件的 v-model 会使用value
prop 和input
事件。但是诸如单选框、复选框之类的输入类型可能把value
用作了别的目的。model
选项可以避免这样的冲突:
1 2 3 4 5 6 7 8 9 10 11 12
| Vue.component("my-checkbox", { model: { prop: "checked", event: "change" }, props: { checked: Boolean, value: String } });
|
Select2 组件封装
来来来我们直接看个 Select2 的组件封装:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| <template> <div> <select class="form-control" :placeholder="placeholder" :disabled="disabled"></select> </div> </template>
<script> export default { name: "Select2", data() { return { select2: null }; }, model: { event: "change", prop: "value" }, props: { placeholder: { type: String, default: "" }, options: { type: Array, default: [] }, disabled: { type: Boolean, default: false }, value: null }, watch: { options(val) { this.setOption(val); }, value(val) { this.setValue(val); } }, methods: { setOption(val = []) { this.select2.select2({ data: val }); if (!this.value && val.length) { const { id, text } = val[0]; this.$emit("change", id); this.$emit("select", { id, text }); this.select2.select2("val", [id]); } this.select2.trigger("change"); }, setValue(val) { this.select2.select2("val", [val]); this.select2.trigger("change"); } }, mounted() { this.select2 = $(this.$el) .find("select") .select2({ data: this.options }) .on("select2:select", ev => { const { id, text } = ev["params"]["data"]; this.$emit("change", id); this.$emit("select", { id, text }); }); if (this.value) { this.setValue(this.value); } }, beforeDestroy() { this.select2.select2("destroy"); } }; </script>
|
这个组件本骚年也弄了个npm package包包,可以直接安装使用:
1 2 3
| npm install v-select2-component --save
npm install jquery --save
|
你还可以到骚年的git上找:godbasin/vue-select2
结束语
之前一直以为,Vue中并没有自定义表单的功能。不过如果说Angular里面能使用的飞天入地,相比Vue里面也应该会有才对。
优秀的东西都可以拿来借鉴,其实合作共赢也是个不错的选择,当然竞争也是很激烈滴~
此处查看项目代码
此处查看页面效果
查看Github有更多内容噢:https://github.com/godbasin
更欢迎来被删的前端游乐场边撸猫边学前端噢
如果你想要关注日常生活中的我,欢迎关注“牧羊的猪”公众号噢