4.vue 的双向绑定的原理是什么?_Vue双向绑定原理

4.vue 的双向绑定的原理是什么?_Vue双向绑定原理Vue双向绑定原理及问题剖析,快速搞懂Vue双向绑定~

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

??????

哈喽!大家好,我是【Bug 终结者,【CSDN新星创作者】?,阿里云技术博主?,51CTO人气博主?,INfoQ写作专家?

一位上进心十足,拥有极强学习力的【Java领域博主】???

?【Bug 终结者】博客的领域是【面向后端技术】的学习,未来会持续更新更多的【后端技术】以及【学习心得】。 偶尔会分享些前端基础知识,会更新实战项目,面向企业级开发应用
? 如果有对【后端技术】、【前端领域】感兴趣的【小可爱】,欢迎关注【Bug 终结者】???

❤️❤️❤️ 感谢各位大可爱小可爱! ❤️❤️❤️

一、什么是Vue双向绑定?

所谓双向绑定,指的是vue实例中的data与其渲染的DOM元素的内容保持一致,无论谁被改变,另一方会相应的更新为相同的数据。

二、Vue的双向绑定

⌚双向绑定的原理

Vue数据双向绑定原理是通过数据劫持结合发布者-订阅者模式的方式来实现的,首先是对数据进行监听,然后当监听的属性发生变化时则告诉订阅者是否要更新,若更新就会执行对应的更新函数从而更新视图

通过Object.defineProperty()来劫持各个属性的settergetter,在数据发生变动时通
知Vue实例,触发相应的​getter​和​setter​回调函数。

当把一个普通 Javascript 对象传给Vue 实例来作为它的 data 选项时, Vue 将遍历它的属性,用 Object.defineProperty
它们转为 ​getter/setter​。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。

⚡双向绑定的核心

关于VUE双向数据绑定,其核心是 Object.defineProperty() 方法

⌚介绍 Object.defineProperty() 方法

Object.defineProperty(obj, prop, descriptor)

这个方法内有三个参数,分别为 obj(要定义其上属性的对象)、prop(要定义或修改的属性)、descriptor(具体的改变方法)

简单来说,就是用这个方法定义一个值,当调用时我们使用了它里面的get方法,当我们给这个属性赋值时,同时又调用了里面的set方法

在这里插入图片描述

运行效果

在这里插入图片描述

三、单向绑定与双向绑定的区别,适合的场景?

❇️单向绑定

单向绑定的优点是相应的可以带来单向数据流,这样做的好处是所有状态变化都可以被记录、跟踪,状态变化通过手动调用通知,源头易追溯,没有“暗箱操作”。同时组件数据只有唯一的入口和出口,使得程序更直观更容易理解,有利于应用的可维护性

缺点则是代码量会相应的上升,数据的流转过程变长,从而出现很多类似的样板代码。同时由于对应用状态独立管理的严格要求(单一的全局store),在处理局部状态较多的场景时(如用户输入交互较多的“富表单型”应用),会显得啰嗦及繁琐。

♻️双向绑定

优点是在表单交互较多的场景下,会简化大量业务无关的代码

缺点就是由于都是“暗箱操作”,我们无法追踪局部状态的变化(虽然大部分情况下我们并不关心),潜在的行为太多也增加了出错时 debug 的难度。同时由于组件数据变化来源入口变得可能不止一个,新手玩家很容易将数据流转方向弄得紊乱,如果再缺乏一些“管制”手段,最后就很容易因为一处错误操作造成应用雪崩。

四、简单实现一个JS双向绑定

⏳效果图

在这里插入图片描述

✅核心源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <h1>演示JS实现Vue双向绑定</h1>
        <p>
            <label>请输入内容:</label>
            <input type="text" id="txt">
        </p>
        <p>
            <label>显示的内容:</label>
            <span id="show"></span>
        </p>
    </div>
</body>
</html>
<script type="text/javascript">
    var obj = { 
   };
    Object.defineProperty(obj, 'txt', { 
   
        get: function() { 
   
            return obj;
        },
        set: function(val) { 
   
            document.getElementById("txt").value = val;
            document.getElementById("show").innerText = val;
        }
    })
    document.addEventListener("keyup", function (e) { 
   
        obj.txt = e.target.value;
    })
</script>

五、Vue.js实现简单双向绑定

⏰效果图

在这里插入图片描述

✅核心源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
      <h1>演示Vue实现双向绑定</h1>
      <p>
          <label>请输入内容:</label>
          <input type="text" v-model="msg">
      </p>
      <p>
          <label>显示的内容:</label>
          <span>{
  
  {msg}}</span>
      </p>
    </div>
</body>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- 引入axios-->
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script type="text/javascript">
    new Vue({
        el:"#app",
        data() {
            return {
              msg:''
            }
        },
        mounted(){
        },
        methods: {
            
        }
    })

</script>
</html>

六、某些情况下对象或数组无法双向绑定的解决方案

♨️数组无法双向绑定的解决方案

修改数组中的内容,数组中的元素发生了变化,而页面没有发生变化

✨数组双向绑定解决效果图

在这里插入图片描述

♻️核心源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
      <h1>修改数组的内容后,数组发生了变化,而页面没有发生变化</h1>
      <div v-for="item in testArr">
        {
  
  {item}}
      </div>
      <button @click="clk1">点击1</button>
      <button @click="clk2">点击2</button>
    </div>
</body>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- 引入axios-->
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script type="text/javascript">
    new Vue({
        el:"#app",
        data() {
            return {
              testArr : [1,2,3],
            }
        },
        mounted(){
        },
        methods: {
            clk1() {
              console.log("修改第一个数字,页面没有修改");
              this.testArr[0] = 20;
              console.log("testArr:" + this.testArr)
            },
            clk2() {
              console.log("修改了数字,页面发生了修改")
              this.$set(this.testArr, 0, 12);
              console.log("testArr:" + this.testArr)
            }
        }
    })

</script>
</html>

✅问题解决

第一个按钮修改后无法显示是因为直接用下标赋值会出现数据不一致情况,可见,数组中的元素已经修改,但页面元素无法显示

解决方案如下

解决方案是通过$set方法来设置数组的值,该方法有三个参数,第一个是要被设置值的目标对象,第二个是设置值在数组中的索引,第三个是设置的值

this.$set(obj, index, value)

第二个按钮就是这样实现了数组的内容修改以及双向绑定的正确显示

♨️对象无法双向绑定的解决方案

✨对象双向绑定解决效果图

在这里插入图片描述

♻️核心源码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div id="app">
      <h1>修改对象的属性,但页面中没有发生改变</h1>
      {
  
  {obj.name}}
      <button @click="clk1">修改对象的属性1</button>
      <button @click="clk2">修改对象的属性2</button>
    </div>
</body>
<!-- 引入vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<!-- 引入axios-->
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script type="text/javascript">
    new Vue({
        el:"#app",
        data() {
            return {
              obj:{
                //初始化属性
                name: ''
              }
            }
        },
        mounted(){

        },
        methods: {
            clk1() {
              console.log("修改对象的属性,未发生变化!");
              this.obj.name = 'zhangsan';
              console.log(this.obj);
            },
            clk2() {
              this.$set(this.obj, "name", "zhangsan");
              console.log("属性添加成功~")
              console.log(this.obj);
            }
        }
    })

</script>
</html>

✅问题解决

由于在data函数中未定义对象的属性,所以导致双向绑定失败!

解决方案如下

  1. 在data函数中的对象初始化对象的属性

在这里插入图片描述

  1. 使用$set设置属性

在这里插入图片描述

至此双向绑定完美解决

♨️往期精彩热文回顾

✈️ Netty进阶 – WebSocket长连接开发

✈️ Netty进阶 – 非阻塞网络编程 实现群聊+私聊+心跳检测系统

✈️ Postman测试工具调试接口详细教程【向后端发送Json数据并接收返回的Json结果】

✈️ Java面向对象 — 吃货联盟订餐系统(完整版)

✈️ 一分钟教你快速 搭建Vue脚手架(Vue-Cli)项目并整合ElementUI

⛵小结

以上就是【Bug 终结者】对Vue双向绑定及详解简单的概述,Vue双向绑定原理就是如此,也是很常见的面试题,大家多看上几遍,并结合自己的理解,相信你很快就可以掌握的~

如果这篇【文章】有帮助到你,希望可以给【Bug 终结者】点个赞?,创作不易,如果有对【后端技术】、【前端领域】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【Bug 终结者】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】???!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/180885.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • mysql长轮询_ajax的轮询和长轮询

    mysql长轮询_ajax的轮询和长轮询概念:轮询(polling):客户端按规定时间定时像服务端发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接。概念总是枯燥的,只有代码方能解心头之快前段代码:index.html:vargetting={url:’server.php’,dataType:’json’,success:function(res){console.log(res);}};//关键在这里,Ajax定时…

    2022年10月9日
    1
  • Jenkins(3)拉取git仓库代码,执行python自动化脚本[通俗易懂]

    Jenkins(3)拉取git仓库代码,执行python自动化脚本[通俗易懂]前言python自动化的脚本开发完成后需提交到git代码仓库,接下来就是用Jenkins拉取代码去构建自动化代码了新建项目打开Jenkins新建一个自由风格的项目源码管理Repository

    2022年7月29日
    7
  • 电脑设备管理器没有调制解调器_电脑里没有调制解调器

    电脑设备管理器没有调制解调器_电脑里没有调制解调器泼冷水丶回答数:5138|被采纳数:532017-01-0910:55:29打开控制面板。我们的很多操作都在控制面板里实现完成的。查看是否安装过BlueSoleil驱动。首先确定你的电脑上曾经装过BlueSoleil驱动。如果没有装过这个,装过其他提供调制解调器的驱动也可以。安装的蓝牙调制解调器使用情况。在网上邻居里观察下我们的BluetoothPANNetWorkAdapte…

    2025年5月31日
    7
  • Java获取当前年月日、时间[通俗易懂]

    Java获取当前年月日、时间[通俗易懂]两种方法,通过Date类或者通过Calendar类。Date类比较简单,但是要得到细致的字段的话Calendar类比较方便。importjava.text.DateFormat;importjava.text.SimpleDateFormat;importjava.util.Calendar;importjava.util.Date;importjava.util.L

    2025年8月24日
    3
  • linux命令之groupadd_linux umask命令

    linux命令之groupadd_linux umask命令usermod[选项]登录名usermod修改用户基本信息。(1).常用选项(2).实例修改用户UID修改登录shell修改主目录并转移主目录内容,-m-d选项修改说明信息(注释信

    2022年8月5日
    5
  • SLAM算法解析[通俗易懂]

    SLAM算法解析[通俗易懂]【嵌牛导读】:SLAM(SimultaneousLocalizationandMapping)是业界公认视觉领域空间定位技术的前沿方向,中文译名为「同步定位与地图构建」,它主要用于解决机器人在未知环境运动时的定位和地图构建问题。【嵌牛鼻子】:有人就曾打比方,若是手机离开了WIFI和数据网络,就像无人车和机器人,离开了SLAM一样。【嵌牛正文】:目前科技发展速度飞快,想让用户在AR/VR、机器人、无人机、无人驾驶领域体验加强,还是需要更多前沿技术做支持,SLAM就是其中之一。实际上

    2022年6月29日
    42

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号