vue中v-model的白话讲解 & 在自定义组件中定义自己的双向数据绑定

v-model原理

你可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

以上是官方的讲解,其实就是v-bind@input语法糖而已。如下图:
在这里插入图片描述

正是通过v-bind指令将响应式的数据绑定到文本框上,之后再给文本框添加input事件,当文本框中的数据发生改变的时候,再去改变响应式数据value的值,进而实现双向数据绑定。

那么,想一下,我们如果实现自定义组件的v-model?

其实在自定义组件的时候,数据流转要比上边介绍的麻烦一些,因为自定义组件必然涉及到父子组件的数据绑定。也就是使用我们组件的地方(父组件)和自定义组件内部(子组件)的通信。

回想一下,父子组件是如何通信的?
在这里插入图片描述
如图所示:

  • 父组件通过传递Prop给子组件,进而子组件可以使用该数据
  • 子组件不可以直接修改父组件,而是需要派发事件,让父组件修改自身属性,子组件进而间接的修改了Prop。

而v-model只需封装一下上边的实现过程即可。同样是语法糖。
在这里插入图片描述
如上图,派发的事件为Input,而响应式数据定义为value。

其实,这个语法糖,vue已经帮你实现好了(真贴心),下面的解释摘自官方文档:

允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event,但是一些输入类型比如单选框和复选框按钮可能想使用 value prop 来达到不同的目的。使用 model 选项可以回避这些情况产生的冲突。

注意加粗字体的描述。这其实恰恰就对应着我上图画的模型。既然都有了思路,不妨用代码实现以下:

// 父组件
<template>
  <div id="app">
    <HelloWorld v-model="foo" />
    <div>外层组件:{{ foo }}</div>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
  components: {
    HelloWorld
  },
  data() {
    return  {
      foo: 1
    }
  },
}
</script>
// 子组件
<template>
  <div class="hello">
    <select @change="valueChanged">
      <option :value="1" :selected="foo === 1">1</option>
      <option :value="2" :selected="foo === 2">2</option>
    </select>
  </div>
</template>

<script>
export default {
  model: {
    event: 'change',
    prop: 'foo',
  },
  props: {
    foo: {
      type: Number
    }
  },
  methods: {
    valueChanged(e) {
      this.$emit('change', e.target.value)
    }
  }
}
</script>

在子组件中,我使用了model这个选项,他是vue官方API的一部分。他的作用是改变v-model默认绑定的事件类型以及prop名称。我上文引用中有详细的描述。

至此一个自定义的双向数据绑定就实现了 😃 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值