本文主要涉及vue2.2版本新增的自定义组件的 v-model
下面以自定义的select组件为例
1.子组件模板代码:
<template>
<div id="app" @click="hiddenSelection">
<div class="form_select">
<input
v-model="selection"
type="text"
:placeholder="placeholder"
@click="showAccountList($event)"
/>
<img
src="../assets/arrow-down.svg"
:class="hasClass==='1' ? 'openlist': (hasClass==='0'?'foldlist':'')"
@click="showAccountList($event)"
/>
<ul v-if="isShowUserList" class="list">
<li
v-for="item in list"
:key="item.value"
:class="{'selected':item.value===value}"
@click="changeValue(item)"
>
{{ item.name }}
</li>
</ul>
</div>
</div>
</template>
2.子组件逻辑代码
<script>
export default {
model: {
prop: 'value',
event: 'changeValue'
},
props: {
list: {
type: Array,
default: () => [{
name: '张三',
value: 1
}, {
name: '李四',
value: 2
}]
},
value: {
type: String,
default: null
},
placeholder: {
type: String,
default: '请选择'
}
},
data() {
return {
isShowUserList: false,
hasClass: '',
selection: null
}
},
watch: {
value: {
handler(val) {
this.list.map(item => {
if (item.value === val) {
this.selection = item.name
}
})
},
immediate: true
}
},
methods: {
showAccountList(e) {
e.stopPropagation()
this.isShowUserList = !this.isShowUserList
if (this.isShowUserList) {
this.hasClass = '1'
} else {
this.hasClass = '0'
}
},
changeValue(data) {
// 实际执行的是:this.value = data.value,不需要在父组件定义此方法
this.$emit('changeValue', data.value)
this.hasClass = '0'
this.isShowUserList = false
},
hiddenSelection() {
this.hasClass = '0'
this.isShowUserList = false
}
}
}
</script>
子组件的关键代码为:
1. 定义双向绑定的属性value, 此属性需要在props中声明。
注:prop:双向绑定的属性名称;event:更改绑定属性的方法名
2.更改双向绑定的属性值
触发changeValue方法更改value值
3. 父组件使用
<template>
<my-select v-model="id" :list="list"/>
</template>
<script>
import mySelect from '../components/mySelect'
export default {
components: {
mySelect
},
data() {
return {
id: '', // 选中值
list: [] // 列表数组
}
}
}
</script>
4.注意点
子组件中,用于和父组件双向绑定的属性value不可以再与子组件的输入框双向绑定。即子组件中不可以
<input
v-model="value"
type="text"
:placeholder="placeholder"
@click="showAccountList($event)"
/>
上面的代码里,value不能再与input输入框双向绑定,所以这样写是有问题的。