vue 2 实现自定义组件一到多个v-model双向数据绑定的方法(最新推荐)
作者:嘘嘘乖乖
前言
有时候我们需要对一个组件绑定自定义 v-model,以更方便地实现双向数据,例如自定义表单输入控件。
甚至有时候,我们想要实现绑定多个 “v-model”,也就是多个“双向绑定”,例如带表单输入的模块框,想同时控制模态框的显示状态与表单的输入状态。好在 vue 3 已经实现了多 v-model,那么在 vue 2 上我们可以如下实现。
1.单个“双向绑定”的实现
使用 model 实现
其实 v-model 只是 value + change 的语法糖,监听输入并触发改变,因此只要实现 “监听” + “触发” 就可以自定义 v-model 啦。
<!-- 父组件 -->
<template>
<Child v-model="value" />
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
<!-- 子组件 -->
<template>
<input v-model="input" />
</template>
<script>
export default {
props: {
value: String,
},
model: {
prop: 'value', // 指定 v-model 要绑定的参数叫什么名字,来自于 props 中定义的参数
event: 'change', // 指定要触发的事件名字,将被用于 $emit
},
computed: {
input: {
// 这里的计算属性使用了 getter、setter,可以简化代码
// 可参见链接 https://cn.vuejs.org/v2/guide/computed.html#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7%E7%9A%84-setter
get() {
return this.value;
},
set(val) {
this.$emit('change', val); // 触发
}
}
}
}
</script>这样一来,就实现了自定义组件的 v-model 实现,重点在于子组件中 model 的声明和 emit 事件。
2.使用 .sync 实现
除了上面 model 的方法,其实还可以通过 sync 来实现。同样也是处理“监听”和“触发”就行。
在官方文档中有写,https://cn.vuejs.org/v2/guide/components-custom-events.html#sync-修饰符
用上面相似的例子,可以这样来实现:
<!-- 父组件 -->
<template>
<Child :value.sync="value" />
</template>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
<!-- 子组件 Child -->
<template>
<input v-model="input" />
</template>
<script>
export default {
props: {
value: String,
},
computed: {
input: {
get() {
return this.value;
},
set(val) {
this.$emit('update:value', val); // 这里的事件名字一定是 'update:' + prop的名字
}
}
}
}
</script>很显然,使用这种方法的代码量比第1种要少,因为不用写 model 属性。只是比起 v-model,v-bind:value.sync 的写法还是不那么“引人注目”
多个“双向绑定”的实现
在 vue 3 出来之前,我们知道在一个标签里面最多只能有一个 v-model。但这并不意味着一个组件只能一次双向数据绑定。
根据上面 .sync 的方法,我们可以举一反三,多几个 update:xxxx 就可以了。
1.分开绑定
下面以一个带输入框的模态框为例子,需求是父组件能够打开模态框,子组件在输入确认后能够关闭模态框;子组件能够输入,确认后能够将值传给父组件。
<!-- 父组件 -->
<template>
<!-- 定义了两个v-bind:xxx.sync来实现两个双向绑定 -->
<ModalInput :value.sync="value" :show.sync="show" />
</template>
<script>
export default {
data() {
return {
value: '',
show: false
}
}
}
</script>
<!-- 子组件 ModalInput -->
<template>
<!-- 这里假设Modal是一个带“确认”按钮,点击触发confirm事件,并利用v-model来控制展示的模态框 -->
<Modal v-model="showModal" @confirm="onConfirm">
<input v-model="input">
</Modal>
</template>
<script>
export default {
props: {
value: String,
show: Boolean,
},
data() {
return {
input: '' // 在这个例子中,使用 data 来声明 input,
// 因为只有在点击了“确认”按钮后,才要把值传给父组件(而不是实时传)
}
},
computed: {
showModal: {
get() {
return this.show;
},
set(val) {
this.$emit('update:show', val);
}
}
},
methods: {
onConfirm() {
this.$emit('update:value', this.input);
this.showModal = false
}
}
}
</script>2.合并绑定
上面是绑定了两个独立变量的双向绑定,按照官方的文档,我们甚至还可以用 v-bind.sync 来绑定整个对象(的所有成员!)。下面假设一个表单组件,同时收集个人多个信息
<!-- 父组件 -->
<template>
<UserInfoForm v-bind.sync="inputs" />
</template>
<script>
export default {
data() {
return {
inputs: {
name: '',
age: 0,
addr: '',
phone: ''
}
}
}
}
</script>
<!-- 子组件 UserInfoForm -->
<template>
<form>
<input v-model="name">
<input v-model.number="age">
<input v-model="addr">
<input v-model="phone">
</form>
</template>
<script>
// 与上面例子实现方式相似,这里省略代码若干行。。。
// 其实就是声明入参 props 有哪些
// 用 computed 来声明各个变量的 getter 和 setter
// getter 返回传进来的 prop,setter 中触发 update:xxxx 事件
</script>到此这篇关于vue 2 实现自定义组件一到多个v-model双向数据绑定的方法(转)的文章就介绍到这了,更多相关vue 2 v-model双向数据绑定内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
