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

news/2024/7/10 0:25:04 标签: vue

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名称。我上文引用中有详细的描述。

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


http://www.niftyadmin.cn/n/1382703.html

相关文章

Slog82_ArthurSlong个人网站后台管理页面GET!

ArthurSlog SLog-82 Year1 GuangzhouChina September 24th 2018 微信扫描二维码&#xff0c;关注我的公众号ArthurSlog.com MSDN: ArthurSlog GitHub: BlessedChild NPMJS.com: arthurslog 掘金主页 简书主页 segmentfault 慎终如始 终无败事 开发环境MacOS(High Sie…

POJ 1160 DP

题目&#xff1a; poj 1160 题意&#xff1a; 给你n个村庄和它的坐标&#xff0c;现在要在其中一些村庄建m个邮局&#xff0c;想要村庄到最近的邮局距离之和最近。 分析&#xff1a; 这道题。很经典的dp dp[i][j]表示建第i个邮局&#xff0c;覆盖到第j个村庄的距离之和。 问题…

高山火绒草

Its supposed to be the mark of a true soldier.转载于:https://www.cnblogs.com/feichengwulai/p/3685478.html

从类型系统看TypeScript中 interface与type的区别

文章目录前言使用上的区别本质区别参考文档前言 在TypeScript中&#xff0c;有两中声明类型的方式。即Interface与Type。 interface X {a: numberb: string }type X {a: numberb: string };上面两种方式均可&#xff0c;所以很让人困惑&#xff0c;到底 他们的区别是什么&a…

推荐几个前端开发插件

提高开发效率 简单的集成到了vue-cli生成的项目上 项目github地址 A Vue.js projectBuild Setup # install dependencies npm install# serve with hot reload at localhost:8080 npm run dev# build for production with minification npm run build# build for production an…

centos6.4下安装配置JDK+TOMCAT+MYSQL教程

2019独角兽企业重金招聘Python工程师标准>>> 一、系统环境和软件包 [rootlocalhost /]# uname -r 2.6.32-358.el6.x86_64 [rootlocalhost /]# cat /etc/centos-release CentOS release 6.4 (Final) 软件包 jdk-6u43-linux-x64-rpm.bin apache-tomcat-6.0.36.tar.gz …

QQ截图右键

1.CtrlAlt 2.右键 3.按下A键转载于:https://www.cnblogs.com/Bruce3555/p/5476622.html

二维树状数组的区间加减及查询 tyvj 1716 上帝造题的七分钟

详细解释见小结。http://blog.csdn.net/zmx354/article/details/31740985 #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <s…