本人是后端开发工程师,但最近几个项目用到了微服务加前后端分离的技术,于是接触学习了vue.js。对于前端开发只能算是了解+可以应用,vue高级复杂的用法也不是很了解,所以有说的不准确的地方,还希望大家多多指点。之前项目前端工程是采用Vue+Element的框架,当前项目框架是Vue+Ant Design。最近发现Element 和 antdesign这两个组件库还是存在一些细微区别的。今天针对Form表单中自定义组件这个方面,想把我自己的解决方案分享给大家,希望可以帮助到需要的人。
首先代码如下:
子组件:
<template>
<a-select showSearch
:filterOption="filterOption"
:placeholder="placeholder"
@change="handleChange"
:value="seletedValue">
<a-select-option value>{{ placeholder }}</a-select-option>
<a-select-option v-for="(item, code) in dictOptions"
:key="code"
:value="item.code">{{ item.code }}-{{ item.name }}</a-select-option>
</a-select>
</template>
<script>
import { getDictData } from './dict'
export default {
name: 'DictSelect',
props: {
dictType: {
required: true,
type: String
},
placeholder: String,
value: ""
},
data () {
return {
dictOptions: [],
seletedValue: this.value
}
},
created () {
this.initDictData()
},
methods: {
initDictData () {
getDictData(this.dictType).then(r => {
this.dictOptions = r.data.rows
})
},
filterOption (input, option) {
return (
option.componentOptions.children[0].text
.toLowerCase()
.indexOf(input.toLowerCase()) >= 0
)
},
handleChange (val) {
this.$emit('change', val)
//this.$emit('dataChanged', val)
}
},
watch: {
value: function () {
this.seletedValue = this.value
}
}
}
</script>
父组件:
<DictSelect dictType="currencyType"
v-decorator="['currency']"></DictSelect>
遇到的问题:
由于之前VUE+Element 表单中都是使用v-model指令进行数据的双向绑定,子组件中触发input回调将选中的值返回。但是现在父组件中使用的是v-decorator指令的方式(这种方式的双向绑定具体原理及实现建议参考Ant Design of Vue官网)。导致子组件this.$emit('input')只可以将选中的值返还给父组件的v-model,但是在修改需要回显的时候值却不能回显。后来发现官网中这段话提醒了我:
这段话提醒我使用了v-decorator
双向绑定后,就不应该再用v-model,同时子组件默认要通过onChange来回传选中的值,所以相应的修改了代码,问题迎刃而解。
另外分享一个小彩蛋,Vue的v-model这个语法糖做的是两件事,一是给表单控件元素绑定value(所以子组件prop中要用value接收),第二个是当输入值时,更新绑定的值。具体如下:
vue语法:
<input v-model="message">
相当于
<input v-bind:value="message" v-on:input="message = $event.target.value">
最后声明一下,本人第一次写博客,自己接触前端时间也不长,可能写的很浅显,也可能有理解错误的地方,希望大家多多指正,相互学习。