前面的话

虽然v-model和.sync之间的区别,是非常明显的,但是通过这个去研究下去,就有点意思了。首先说明v-model是.sync的一种特殊情况,也就是当prop是value,vm.$emit('update:input'),这个时候就是传统意义上的v-model,也就是说v-model是model为prop等于value,event为input的特殊情况。

概念

双向数据传递

为了和绑定区分我把他称为传递,也就是父子组件之间的传递

双向数据绑定

和双向数据绑定不同,双向数据绑定则是数据驱动dom,dom反作用于数据,vue通过Object.defineProperty(),实现了数据驱动dom,而通过dom驱动数据很容易实现了,举个例子当<input>,发生变化的时候把变化后的值赋给一个当前页面的局部变量,周而复始的实现双向的数据绑定

v-modle

引用官网上的一句话:通过使用自定义事件可以在自定义的组件中创建v-modle(注意Input中I大写,是因为这个是自定义的一个包装input标签的组件)

<Input v-model="searchText">

等价于,也就是说当使用v-model的时候默认会调用父级组件中的一个用input触发的事件,这个事件就是为了给当前的prop进行重新赋值。

<Inputv-bind:value="searchText"v-on:input="searchText = $event.target.value"
>

如果想顺利的使用v-model还需要对组件进行以下的处理

Vue.component('Input', {props: ['value'],template: `<inputv-bind:value="value"v-on:input="$emit('input', $event.target.value)">`
})

详情

双向数据传递

概念:父子组件之间可以相互修改数据

应用:弹窗、表单

实现:v-model,.sync,model

我们先从概念入手,什么是相互修改,我们都知道的是,父子沟通用的是props,子父沟通用的是$emit,那双向传递就显而易见了,就是在父组件使用props传值给子组件,子组件再通过$emit可以调整父组件。

三种实现的差异

v-modle是最特殊的一个,他其实是model和.sync的特殊情况,有代码为证

model

<style>input.i911-model-input {color: #f747ff;border-radius: 4px;border: 3px solid #fa4dde;}
</style><template><div><inputclass="i911-model-input":value="modelInput"@click="handleInput"/></div>
</template><script>export default {name: "ModelInput",model:{prop:'modelInput',//为了和v-model默认的value区分,将prop改为自定义的名称event:'click'//为了和v-model默认的input区分,将event改为click},props: {modelInput: {type: String,default: 'modelInput'}},methods:{handleInput(event){this.$emit('click',event.target.value)//自定义组件中使用v-model都需要通过$emit触发}}}
</script>

sync

<style>input.i911-sync{color: #801a27;border-radius: 4px;border: 3px solid #ff375a;}
</style>
<template><main><input class="i911-sync":value="msg"@input="handleInput"></main>
</template><script>export default {name: "SyncInput",props: {msg: {type: String,default: ''}},methods:{handleInput(event){this.$emit('update:msg',event.target.value)}}}
</script>

v-model

<style>input.i911-v-model{color:green;border-radius: 4px;border: 3px solid #36ff7a;}
</style>
<template><main><input class="i911-v-model":value="value"@input="handleInput"></main>
</template><script>export default {name: "VModel",props: {value: {type: String,default: ''}},methods:{handleInput(event){this.$emit('input',event.target.value)//这里$emit调用的是默认的input}}}
</script>

子组件贴完了该我们的父组件了

<style>
input.temp-normal-input{color: #1ab0ff;border: 3px solid #faf847;
}input{float: left;}
</style><template><div>TEMP//直接通过v-model绑定,通过input触发V-MODEL-INPUT:<VMolde v-model="value"></VMolde>//这里使用了默认input标签的v-model,因此不需要绑定@input='handleInput',便可以对value修改V-MODEL-INPUT-PARENT:<input v-model="value">//通过:msg.sync绑定,它实质上是@update:msg='val=>valueSync=val',的语法糖,因此可不用绑定SYNC-INPUT:<SyncInput :msg.sync="valueSync"></SyncInput>SYNC-INPUT-PARENT:<input v-model="valueSync"><br>//直接通过v-model绑定,通过input触发NORMAL-INPUT-1:<input class="temp-normal-input" v-model="normalValue"/><br>NORMAL-INPUT-2:<input v-model="normalValue"/><br>MODEL-INPUT:<model-input v-model="modelValue"></model-input>MODEL-INPUT-parent:<input v-model="modelValue"/></div>
</template><script>import VMolde from '@/components/VMolde'import SyncInput from '@/components/SyncInput'import ModelInput from '@/components/ModelInput'export default {name: "temp",data() {return {value:'value',valueSync:'valueSync',normalValue:'normalValue',modelValue:'modelValue'}},methods: {handleSyncInput(event){this.valueSync=event.target.value;}},components: {VMolde,SyncInput,ModelInput}}
</script>

对比

model&.sync

双向数据绑定

后续总结,可以先看双向数据绑定原理

双向数据传递与双向数据绑定的区别详解

有个问题可能会比较疑惑,v-model不是用来双向数据绑定的吗,为什么也可以用来做双向数据传递,这是什么鬼。但是如果把默认的标签也想成一个组件的话这个问题就迎刃而解了,当使用input标签时,input的内部也有一段类似于上文中自定义Input的代码。

现在我们具体分析,首先我们来分析下在父组件中修改一个被v-model绑定的input标签(也就是子组件)时候发生了什么?

1.双向数据传递(子组件传递给父组件)

核心部分也就是通过$emit调用父组件的input方法去改变输入的value,这一步是干嘛呢?其实就是将子组件的value通过$emit传递给了父级组件,这部分属于数据传递中子组件传递给父组件;

2.双向数据绑定(dom修改value)

而调用的input方法中的对value进行的修改,这个时候就是双向数据绑定中的dom去修改value

反之如果通过父组件直接修改数据使得子组件发生变化这经历了下面的过程

3.双向数据传递(父组件传递给子组件)

当父组件的数据发生变化后,父组件通过prop将数据传递给了子组件

4.双向数据绑定(value修改value)

子组件数据变化后要去动态的修改dom,这个时候就是用到了Object.defineProperty()中的set,监听其数据变化,并且修改dom,vue具体dom修改方式还没有看,不过可以理解为通过jquery或者原生js进行修改

Vue中从v-model,model,.sync到双向数据传递,再到双向数据绑定相关推荐

  1. vue中前进刷新、后退缓存用户浏览数据和浏览位置的实践

    vue中,我们所要实现的一个场景就是: 1.搜索页面==>到搜索结果页时,搜索结果页面要重新获取数据, 2.搜索结果页面==>点击进入详情页==>从详情页返回列表页时,要保存上次已经 ...

  2. Vue 中 props 传值,父组件向子组件传递对象/数组可以直接修改的问题

    vue 中父子组件通信最常用的方式是 props 和 $emit,所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行.这 ...

  3. 七十、Vue城市页面Ajax动态渲染和兄弟组件数据传递

    2020/10/29. 周四.今天又是奋斗的一天. @Author:Runsen 写在前面:我是「Runsen」,热爱技术.热爱开源.热爱编程.技术是开源的.知识是共享的.大四弃算法转前端,需要每天的 ...

  4. Vue中JS遍历后台JAVA返回的Map数据,构造对象数组数据格式

    场景 SpringBoot+Vue+Echarts实现选择时间范围内数据加载显示柱状图: SpringBoot+Vue+Echarts实现选择时间范围内数据加载显示柱状图_BADAO_LIUMANG_ ...

  5. vue 传递 对象 路由_javascript – 如何在Vue中提交表单,重定向到新路由并传递参数?...

    < form>的默认行为是重新加载页面onsubmit.在实施SPA时,最好避免调用< form>的默认行为. 利用nuxtjs中现成的路由器模块,可以使所有重定向控件在应用程 ...

  6. vue 中的el表达式_解释el页面数据表达式

    java web开发人员经常使用标签 struts标签库 国际化配置 配置国际化 1.国际化配置 在struts自带的app中的struts-config.xml中的<message-resou ...

  7. Vue中实现特效下拉加载更多数据

    1.功能需求 其实在很多的页面开发过程中,有些页面尤其是评论页面,在第一次加载的时候并不会加载很多的相关数据,而是加载一部分,当用户下拉旁边的滚动条时,尤其是滚动条移动到底部的时候,就会出现行的相关内 ...

  8. 使用vue中的transition标签实现点击缓慢展开,再点缓慢关闭

    <div><div @click="show=!show">我是列表</div><transition name="fade&q ...

  9. 老式Android中碎片Fragment之间的跳转和数据传递

    随着jetpack组件的使用,fragment之间的跳转和传值已经有相应的demo了.但是有时候难免不用Navigation,或者一些老项目的维护.这里,简单记录下老式fragment怎么跳转和传值. ...

最新文章

  1. cocos2d-js开发环境的搭建
  2. CentOS 7 快速部署 ELK
  3. android fragment+ FragmentTabHost+viewpager 切换状态不保存的问题
  4. 使用代码获得所有适用于创建的transaction type
  5. 在.NET Core 中收集数据的几种方式
  6. java从端口接收数据_java - Java中通过串行端口接收数据的效率更高 - 堆栈内存溢出...
  7. CSS animation 与 transition 有何区别?
  8. android ndk 头文件,笔记:Android源码和NDK目录及头文件
  9. 樊正伦教授的养生之道中医文化与养生之---调情志
  10. VMware Horizon Client剪贴板异常问题解决
  11. HTML5 之 FileReader(图片上传)
  12. 64位win10下usb转485驱动
  13. win10自带微软拼音输入法卡死卡顿解决方法汇总
  14. 【Gym - 101350M Make Cents?】 STL - map
  15. 不是忽悠?国产16nm八核处理器来了
  16. 2013年微软校园招聘笔试题
  17. python3如何实现一行输入,空格隔开
  18. 小猪的Python学习之旅 —— 14.项目实战:抓取豆瓣音乐Top 250数据存到Excel中
  19. 【Blog】Hexo_Next_博客搭建记 (by onlychristmas)
  20. 边缘融合 边缘计算_生活在科技边缘

热门文章

  1. linux命令kill9的含义,[整理]kill -9的含义
  2. 拉格朗java_逻辑炸弹通常是通过_______。
  3. 云风Skynet——skynet非官方网站
  4. 依图胸部CT新冠肺炎智能评价系统:三大智能功能精准辅助医学分析|百万人学AI评选
  5. 计算机科学与技术 研究生 缩招,2021考研招生最新信息汇总(扩招、缩招、停招、首招)...
  6. 基于php022公司企业网站设计-计算机毕业设计
  7. OSError: /home/yukang/anaconda3/envs/fsgan/lib/python3.9/site-packages/torch/lib/../../nvidia/cublas
  8. zao AI换脸,说说自己对人脸识别的一些理解
  9. python自动发邮件报554错误_python smtplib使用163发送邮件 报错 554 DT:SPM
  10. odoo之审批 流程管理 模块