【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定

news2024/11/17 7:38:18

文章目录

  • ✨什么是数据双向绑定
  • ✨数据双向绑定的原理
  • ✨Vue数据双向绑定原理
  • ✨实现数据双向绑定的步骤
  • ✨手动实现自定义组件的双向绑定的步骤
  • ✨写在最后

在这里插入图片描述
在这里插入图片描述

✨什么是数据双向绑定

我们先从单向绑定切入单向绑定非常简单,就是把Model绑定到View。

什么是双向绑定呢?当我们用JavaScript代码更新Model时,View就会自动更新,在单向绑定的基础上,用户更新了View,Model的数据也自动被更新了,这种情况就是双向绑定。

✨数据双向绑定的原理

数据双向绑定的原理之前,我们先来了解一下什么是MVVM。

MVVM是一种设计思想,它是Model-View-ViewModel的缩写。它也是MVC的增强版。

  • Model是代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑。
  • View是代表UI组件,它负责将数据模型转化成UI展现出来。
  • ViewModel是一个同步View和Model的对象。

ViewModel的主要职责:

  • 数据变化后更新视图
  • 视图变化后更新数据

当然,它还有两个主要部分组成

  • 监听器(Observer):对所有数据的属性进行监听
  • 解析器(Compiler):对每个元素节点的指令进行扫描跟解析,根据指令模板替换数据,以及绑定相应的更新函数

✨Vue数据双向绑定原理

Vue是采用数据劫持结合发布者-订阅者模式的方式,通过使用ES5中的Object.defineProperty()方法来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。

Object.defineProperty()允许在对象上定义新的属性,以及修改或删除现有属性的特性,其中包括get、set、enumerable和configurable等。

在这里插入图片描述

✨实现数据双向绑定的步骤

  1. 创建Vue实例时,在data属性中定义需要双向绑定的数据。
  2. 在模板中使用v-model指令将输入控件绑定到数据属性上。
    在Vue内部,使用Object.defineProperty()方法将数据属性转换为getter/setter形式,从而实现数据的响应式变化。
  3. 当输入控件的值发生变化时,Vue会自动调用数据属性的setter方法,从而更新数据的值。
  4. 当数据的值发生变化时,Vue会自动更新相关的DOM元素,从而实现数据与视图的双向绑定。

示例代码如下:

html

<div id="app">
  <input v-model="message">
  <p>{{ message }}</p>
</div>

javascript

var vm = new Vue({
  el: '#app',
  data: {
    message: ''
  }
});

在上面的代码中,v-model指令将输入框和message属性进行了双向绑定。当输入框的值发生变化时,message属性的setter方法会被调用,从而更新数据。当message属性的值发生变化时,相关的DOM元素也会自动更新,从而实现了数据与视图的双向绑定。

需要注意的是,Vue的双向绑定仅适用于一些特定的输入控件,如input、textarea和select等。对于自定义组件,需要手动实现数据的双向绑定。

如何手动实现数据的双向绑定呢?请继续往下看。

✨手动实现自定义组件的双向绑定的步骤

  1. 在自定义组件中,通过props属性接收父组件传递的数据,并在组件中定义一个内部变量来保存这些数据。
  2. 在组件内部使用v-model指令将输入控件绑定到内部变量上。
  3. 在组件内部监听输入控件的变化事件,并在事件处理函数中更新内部变量的值。
  4. 在组件内部通过$emit()方法触发一个自定义事件,并将内部变量作为参数传递给父组件。
  5. 在父组件中使用自定义事件的处理函数来更新父组件中的数据。

示例代码如下:

<!-- 父组件 -->
<template>
  <div>
    <my-component v-model="message"></my-component>
    <p>{{ message }}</p>
  </div>
</template>

<script>
  import MyComponent from './MyComponent.vue';

  export default {
    components: {
      'my-component': MyComponent
    },
    data() {
      return {
        message: ''
      }
    }
  }
</script>

<!-- 自定义组件 -->
<template>
  <div>
    <input type="text" v-model="internalValue">
  </div>
<template>
<script>
  export default {
    props: ['value'],
    data() {
      return {
        internalValue: ''
      }
    },
    mounted() {
      this.internalValue = this.value;
    },
    watch: {
      internalValue() {
        this.$emit('input', this.internalValue);
      }
    }
  }
</script>

在上面的代码中,我们定义了一个名为value的props属性来接收父组件传递的数据,同时定义了一个名为internalValue的内部变量来保存这些数据。在组件挂载后,我们将value的值赋值给internalValue。

在组件内部使用v-model指令将输入控件绑定到internalValue上。当输入控件的值发生变化时,我们使用watch来监听internalValue的变化事件,并在事件处理函数中使用$emit()方法触发一个名为input的自定义事件,并将internalValue作为参数传递给父组件。

在父组件中,我们可以通过v-model指令将message属性与自定义组件的value属性进行双向绑定。当自定义组件的input事件被触发时,我们可以在事件处理函数中将事件的参数作为message属性的值进行更新。

示例代码如下:

<!-- 父组件 -->
<template>
  <div>
    <my-component v-model="message"></my-component>
    <p>{{ message }}</p>
  </div>
</template>

<script>
  import MyComponent from './MyComponent.vue';

  export default {
    components: {
      'my-component': MyComponent
    },
    data() {
      return {
        message: ''
      }
    }
  }
</script>

<!-- 自定义组件 -->
<template>
  <div>
    <input type="text" v-model="internalValue">
  </div>
</template>

<script>
  export default {
    props: ['value'],
    data() {
      return {
        internalValue: ''
      }
    },
    mounted() {
      this.internalValue = this.value;
    },
    watch: {
      internalValue() {
        this.$emit('input', this.internalValue);
      }
    }
  }
</script>

在上面的代码中,我们定义了一个名为message的数据属性,并将它与自定义组件的value属性进行了双向绑定。

同时,在自定义组件中,我们实现了数据的双向绑定,并通过$emit()方法触发了一个名为input的自定义事件来与父组件进行通信。这样就实现了自定义组件的双向绑定。

✨写在最后

✨ 原创不易,希望各位大佬多多支持。

👍 点赞,你的认可是我创作的动力。

⭐️ 收藏,感谢你对本文的喜欢。

✏️ 评论,你的反馈是我进步的财富。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/410281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于pytorch+Resnet101加GPT搭建AI玩王者荣耀

本源码模型主要用了SamLynnEvans Transformer 的源码的解码部分。以及pytorch自带的预训练模型"resnet101-5d3b4d8f.pth"本资源整理自网络&#xff0c;源地址&#xff1a;https://github.com/FengQuanLi/ResnetGPT注意运行本代码需要注意以下几点 注意&#xff01;&a…

【Unity】Button基础-按钮更换图片样式

话说&#xff0c;今天修改了一下项目中的内容&#xff0c;发现按钮不怎么好看&#xff0c;想用图片的方式改一改&#xff0c;然后点开Button&#xff0c;忽然发现好多内容都忘记了。。。 Transition&#xff08;过渡方式&#xff09;&#xff1a;按钮在状态改变时自身的过渡方式…

P2E游戏《西游降魔》站在元宇宙风口 打造高效、完整且可持续的GameFi2.0体系

引言&#xff1a;当人类大步迈入元宇宙时代&#xff0c;链上P2E游戏《西游降魔》正与元宇宙生态相伴相生&#xff0c;带领人们开启Play to Earn的变革之旅。 区块链结合游戏组成新的 GameFi 赛道&#xff0c;在 2021 年迎来爆炸式增长。各大公链如&#xff1a;ETH、BSC、OKCha…

【蓝桥杯】X进制减法、贪心思想、小白专用

问题描述&#xff1a; 解题分析&#xff1a; 首先要搞明白 X 进制与 十 进制是如何转换的&#xff0c;以 X 进制321为例 题中说明&#xff0c;3 的进制为8&#xff0c;2的进制为10&#xff0c;1的进制为2 那么开始计算&#xff1a; 1就代表一个1 2的话是十进制&#xff0c…

【论文精读】COLING 2020 -带有对偶关系图注意力网络的事件检测模型

【论文精读】COLING 2020 -带有对偶关系图注意力网络的事件检测模型 【论文原文】&#xff1a;Event Detection with Dual Relational Graph Attention Networks 【作者信息】&#xff1a;Jiaxin Mi and Po Hu and Peng Li 论文&#xff1a;https://aclanthology.org/2022.c…

Spring系列(六) --- SpringBoot 与 Servlet 的比较及 Spring 读取配置文件的方式

SpringSpringBoot VS ServletSpring 读取配置文件的方式yml 和 properties 的区别SpringBoot VS Servlet Spring 读取配置文件的方式 1 Value 注解获取单个配置项 如在 yml 中定义一个 qq 音乐的 token; 然后输出, 如下: 2 针对对象的读取: ConfigurationProperties 在 yml 中…

笔记本电脑连接不上WiFi怎么办?4个实用解决方法!

案例&#xff1a;笔记本电脑连接不上WiFi怎么办 “朋友们&#xff0c;想问问大家知道为什么我的笔记本电脑连接不上WiFi呢&#xff1f;试了好几遍还是无法连接&#xff0c;遇到这种情况我应该怎么解决呢&#xff1f;感谢大家&#xff01;” 在现代生活中&#xff0c;笔记本电…

HTTP协议详解(二)

目录 1.HTTP 响应详解 1.1认识状态码(status code) 1.2 认识响应报头(header) 1.3 认识响应正文(body) 2.构造 HTTP 请求 2.1 通过form表单构造请求 2.2 通过ajax构造请求 2.3 使用第三方工具构造请求 开始之前我们先复习一下http协议格式 1.HTTP 响应详解 我们先抓包…

【JavaScript】四个常用功能/案例:表格排序 | 替换链接 | 倒计时 | 双色球机选一注

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 &#x1f5a5;️ NodeJS专栏&#xff1a;Node.js从入门到精通 &#x1f5a5;️ 博主的前端之路&#xff08;源创征文一等奖作品&#xff09;&#xff1a;前端之行&#xff0c;任重道远&#xff08;来自大三学长的万字自述&am…

《文章复现》考虑用户舒适度的冷热电多能互补综合能源系统优化调度

说明书 免费&#xff1a;https://download.csdn.net/download/qq_50594161/87625438 MATLAB代码&#xff1a;考虑用户舒适度的冷热电多能互补综合能源系统优化调度 关键词&#xff1a;用户舒适度 综合能源 PMV 优化调度 参考文档&#xff1a;《冷热电气多能互补的微能源网鲁…

点击开关按钮,js实现电灯开关效果

初识js&#xff0c;跟大家分享js实现电灯开关灯效果的具体代码&#xff0c;利用简单的htmljs模拟电灯开关的小案例。 首先进行案例分析&#xff1a; 1.获取图片属性 2.判断变量的值 3.点击时切换图片 通过点击按钮实现电灯开关 以下是两张需要的图片&#xff0c;接下来添加…

vue3路由配置及路由跳转传参

1、安装路由 npm i vue-router 2、编写需要展示的路由 在src目录下创建pages文件夹&#xff0c;里面创建两个vue文件命名为student.vue,person.vue 分别编写两个vue文件 student.vue和person.vue <template>学生 </template><script setup></script…

后端架构token授权认证机制:spring security JSON Web Token(JWT)简例

后端架构token授权认证机制&#xff1a;spring security JSON Web Token&#xff08;JWT&#xff09;简例 在基于token的客户端-服务器端认证授权以前&#xff0c;前端到服务器端的认证-授权通常是基于session&#xff0c;自从token机制出现并流行起来后&#xff0c;基于token…

微信小程序详细登录流程(图解+代码流程)

&#x1f482; 个人网站:【紫陌】【笔记分享网】&#x1f485; 想寻找共同学习交流、共同成长的伙伴&#xff0c;请点击【前端学习交流群】微信小程序的登录和web端的登录有一点是不同的&#xff0c;小程序需要和微信的服务通信验证。1.小程序登录流程官网图官网图地址2.认识op…

【node进阶】深度解析Express框架--路由、中间件

✅ 作者简介&#xff1a;一名普通本科大三的学生&#xff0c;致力于提高前端开发能力 ✨ 个人主页&#xff1a;前端小白在前进的主页 &#x1f525; 系列专栏 &#xff1a; node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 &#x1f340; 学习格言: ☀️ 打不倒你的会使你更强&a…

完全卸载vscode

背景 由于插件崩溃、不正确操作等导致vscode出现异常现象&#xff0c;如&#xff1a;代码高亮失效、无法进行转到定义等&#xff0c;此时的vscode就需要重新完全卸载删除再安装&#xff0c;恢复初始化。 步骤 1、卸载vscode&#xff1a; 任何方法都可以&#xff0c;比如win…

vue 遍历数组

1.forEach(): 遍历数组 需要一个回调函数作为参数 回调函数的形参: ①. value: 遍历数组的内容 ②.index: 对应数组的索引 ③.array: 数组本身 forEach() 方法主要是用于调用数组的每个元素&#xff0c;并将元素传递给回调函数。 注:对于空数组不会执行回调函数 语法: ar…

jsoup 框架的使用指南

概述 参考&#xff1a; 官方文档jsoup的使用JSoup教程jsoup 在 GitHub 的开源代码 概念简介 jsoup 是一款基于 Java 的 HTML 解析器&#xff0c;它提供了一套非常省力的 API&#xff0c;不但能直接解析某个 URL 地址、HTML 文本内容&#xff0c;而且还能通过类似于 DOM、CS…

刷题日常计~JS①

作者 : SYFStrive 博客首页 : 点击跳转HomePage &#x1f4dc;&#xff1a; 初编程JavaScript之每天10题 &#x1f449; 从质变到量变&#x1f4aa; &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f5…

Vue常见报错及解决方案

写代码的过程中一定会遇到报错&#xff0c;遇到报错不要担心&#xff0c;认真分析就可以解决报错&#xff0c;同时积累经验&#xff0c;早日成为大牛&#x1f44d; 本文会整理一些在编码过程中遇到的常见报错&#xff0c;共同学习。 一、报错结构 二、常见问题总结及解决方法 …