v-model一些理解
用过vue同学,都知道v-model可以实现双向绑定,方便我们的赋值和获取。
<input v-model="value"/>
使用v-model可以轻松的获取我们输入的值。下面我们就来研究下其中的原理:
通常我们写一个组件,子组件要获取父组件的值,通过props传值,父组件要获取子组件要通过$emit绑定一个方法,通过调用这个方法获取相应的值。
子组件:zInput
<template>
<input type="text" @input="changValue" />
</template>
<script>
export default {
props: {
value: { type: String, default: '' }
},
methods: {
changValue(e) {
this.$emit('input', e.target.value)
}
}
}
</script>
父组件:
<template>
<div class="test">
<zInput :value="value" @input="getInput" />
</div>
</template>
<script>
import zInput from './zInput'
export default {
components: { zInput },
data() {
return {
value: ''
}
},
methods: {
// 获取子组件的值
getInput(val) {
console.log(val)
}
}
}
</script>
这是一般的写法,我们该怎么用v-model实现数据的双向绑定呢,首先我们要弄清楚model的原理:
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件
v-model 相当于 :value="value" @input="getInput" 那我我们就可以这样写父组件了:
<template>
<div class="test">
<zInput v-model="value"/>
</div>
</template>
<script>
import zInput from './zInput'
export default {
components: { zInput },
data() {
return {
value: ''
}
},
watch:{
value(val){
console.log(val)
}
}
}
</script>
现在是不是清晰了很多,v-model就是父组件默认传一个默认为value的值给子组件,并且默认获取input事件。如果你理解了就可以动手改造我们的代码,就可以解决之前的来回传值和获取的烦恼了。
如果你还是觉得这样满足不了你的需求,你可以尝试下自定义v-model:
vue2.2.0+ 新增
一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value attribute 用于不同的目的。model 选项可以用来避免这样的冲突:
先看下官网的例子:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
我们可以自定义prpo传入的值和$emit的事件,这样我们可以更加灵活的使用v-model,实现我们的需求。
我们可以用computed中的get和set更好的实现的我们的自定义的双向绑定,如果不是太了解,可以看下:计算属性 vs 侦听属性
下面我们用elment-ui中的单选框举例:
子组件zRadio
<template>
<div>
<el-radio-group v-model="radioValue">
<el-radio-button label="上海"></el-radio-button>
<el-radio-button label="北京"></el-radio-button>
<el-radio-button label="广州"></el-radio-button>
<el-radio-button label="深圳"></el-radio-button>
</el-radio-group>
</div>
</template>
<script>
export default {
props: {
radio: { type: String, default: '' }
},
model: {
props: 'radio',// 自定义传入的值
event: 'change'// 自定义我们的事件
},
computed: {
radioValue: {
get() {
return this.radio // 接收传进来的值
},
set(value) {
// 设置radio的值并通过model的change的事件传出改变的值
this.$emit('change', value)
}
}
}
}
</script>
父组件:我们可以直接获取radio的绑定的值,也可以用chang获取事件
<template>
<div class="test">
<zRadio v-model="value" :radio="value" @change="getValue" />
</div>
</template>
<script>
import zRadio from './zRadio'
export default {
components: { zRadio },
data() {
return {
value: ''
}
},
watch: {
value(val) {
console.log(val)
}
},
methods: {
getValue(val) {
console.log(val)
}
}
}
</script>
这样我们精简了我们的代码,也简化了我们的复杂的传值,自己动手改造下自己的代码吧。
了解更多,可以去我的博客,让我们共同学习进步!