Vue双向数据绑定与响应式原理深入探究

 更新时间:2022年08月05日 10:13:47   作者:饭啊饭°  
本节介绍双向数据绑定以及响应式的原理,回答了双向数据绑定和数据响应式是否相同,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

一、双向数据绑定和数据响应式是相同的吗

不相同,原因如下:

响应式是指通过数据区驱动DOM视图的变化,是单向的过程。

双向数据绑定就是无论用户更新View还是Model,另一个都能跟着自动更新。

  • 例如:当用户填写表单时,View的状态就被更新了,如果此时可以自动更新Model的状态,那就相当于我们把Model和View做了双向绑定。
  • 双向数据绑定的数据和DOM是一个双向的关系。
  • 响应式是双向绑定的一环。

二、双向数据绑定的原理

双向绑定由三个重要部分(MVVM)构成:

  • 数据层(Model):应用的数据及业务逻辑;
  • 视图层(View):应用的展示效果,各类UI组件;
  • 业务逻辑层(ViewModel):框架封装的核心,它负责将数据与视图关联起来。

ViewModel的主要职责是:数据变化后更新视图;视图变化后更新数据。

ViewModel有两个主要组成部分:

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

Vue中体现出的双向绑定有两种方式:v-model属性和.sync修饰符

v-model属性:v-model也有两种使用场景,一是作用在表单元素上,二是作用在组件上

(1)作用在表单元素上:动态绑定了input的value指向了变量,并且在触发input事件的时候动态的把变量设置为目标值:

<input type="text" v-model="message">
//相当于
<input type="text" v-bind:value="message" v-on:input="message=$event.target.value">

(2)作用在组件上:在自定义组件中,v-model 默认会利用名为 value 的 prop和名为 input 的事件。通过子组件中的 $emit 方法派发 input 事件,父组件监听 input 事件中传递的 value 值,并存储在父组件 data 中;然后父组件再通过 prop 的形式传递给子组件 value 值,再子组件中绑定 input 的 value 属性即可。

<child :value="message" @input="function(e){message = e}"></child>

.sync修饰符:父组件向子组件传递数据的方式有很多种,props是其中的一种,但是它只能单向传递,使用.sync可以实现子组件修改父组件的数据。

<!-- 父组件给子组件传入一个setNum函数 -->
<child :num.sync="numParent">
<script>
//子组件通过调用这个函数来实现修改父组件的状态
methods: {
    changNum(){
      this.$emit('update:num',666)
}
</script>

三、数据响应式的原理与实现

流程:

  1. new Vue()首先执行初始化,对data执行响应化处理,这个过程发生Observe中;
  2. 同时对模板执行编译,找到其中动态绑定的数据,从data中获取并初始化视图,这个过程发生在Complie中;
  3. 同时定义一个更新函数和Watcher,将来对应数据变化时Watcher会调用更新函数;
  4. 由于data的某个key在一个视图中可能出现多次,所以每个key都需要一个管家Dep来管理多个Watcher;
  5. 将来data中数据一旦发生变化,会首先找到对应的Dep,通知所有Watcher执行更新函数。

主要解决两个问题

1. app.message修改数据,Vue内部是如何监听message数据的改变的;

——Object.defineProperty ->监听对象属性的改变

2. 当数据发送改变,Vue是如何知道要通知哪些人,界面发生刷新

——发布订阅者模式

实现:

原代码:

<body>
    <div id="app">
        {{message}}
        {{message}}
        {{message}}
        {{name}}
    </div>
</body>
<script>
    const app = new Vue({
        el:'#app',
        data:{
            message:'哈哈哈',
            name:'fanafan'
        }
    })
</script>

问题1:app.message修改数据,Vue内部是如何监听message数据的改变的

const obj = {
    message:'哈哈哈',
    name:'fanafan'
}
Object.keys(obj).forEach(key => {
    let value = obj[key]
    Object.defineProperty(obj,key,{
        set(newValue){
            console.log("监听" + key +"的改变");
            value = newValue
        },
        get(){
            console.log("获取" + key + "对应的值");
            return value
        }
    })
})

问题2:当数据发送改变,Vue是如何知道要通知哪些人,界面发生刷新

// 发布者订阅者
class Dep{
    constructor(){
        this.subs = []
    }
    addSub(watcher){
        this.subs.push(watcher)
    }
    notify(){
        this.subs.forEach(item=>{
            item.update()
        })
    }
}
class Watcher {
    constructor(name){
        this.name = name;
    }
    update(){
        console.log(this.name + '发生update');
    }
}
const dep = new Dep()
const w1 = new Watcher('张三')
dep.addSub(w1)
const w2 = new Watcher('李四')
dep.addSub(w2)
const w3 = new Watcher('王五')
dep.addSub(w3)
dep.notify()

到此这篇关于Vue双向数据绑定与响应式原理深入探究的文章就介绍到这了,更多相关Vue双向数据绑定内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据

    vue+vuex+axio从后台获取数据存入vuex实现组件之间共享数据

    这篇文章主要介绍了vue+vuex+axio从后台获取数据存入vuex,组件之间共享数据,非常具有实用价值,需要的朋友可以参考下
    2017-04-04
  • vue.js基于v-for实现批量渲染 Json数组对象列表数据示例

    vue.js基于v-for实现批量渲染 Json数组对象列表数据示例

    这篇文章主要介绍了vue.js基于v-for实现批量渲染 Json数组对象列表数据,结合实例形式分析了vue.js使用v-for遍历json格式数据渲染列表相关操作技巧,需要的朋友可以参考下
    2019-08-08
  • 使用Vue实现防篡改的水印

    使用Vue实现防篡改的水印

    我们在平时上网的时候会看到有些图片是加水印的,一般水印往往是后端来做的,不过有些站点要保护的知识产权类型比较多,不光是图片,可能还有视频或者文字,所以我们水印的作用,就是给他做一个适当的限制,本文就给大家介绍一下如何使用Vue实现防篡改的水印
    2023-08-08
  • vue如何使用swiper插件修改左右箭头的默认样式

    vue如何使用swiper插件修改左右箭头的默认样式

    这篇文章主要介绍了vue如何使用swiper插件修改左右箭头的默认样式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • vue3利用store实现记录滚动位置的示例

    vue3利用store实现记录滚动位置的示例

    这篇文章主要介绍了vue3利用store实现记录滚动位置的示例,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下
    2021-04-04
  • 详解Vscode中使用Eslint终极配置大全

    详解Vscode中使用Eslint终极配置大全

    这篇文章主要介绍了详解Vscode中使用Eslint终极配置大全,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • Vue 打包体积优化方案小结

    Vue 打包体积优化方案小结

    这篇文章主要介绍了Vue 打包体积优化方案小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • vue如何使用async、await实现同步请求

    vue如何使用async、await实现同步请求

    这篇文章主要介绍了vue如何使用async、await实现同步请求,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Vue组件通信的四种方式汇总

    Vue组件通信的四种方式汇总

    这篇文章主要给大家介绍了关于Vue组件通信的四种方式,分别是父子组件通信、非父子组件的eventBus通信、利用localStorage或者sessionStorage以及利用Vuex等方法,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2018-02-02
  • Vue 调试访问本地后端接口配置

    Vue 调试访问本地后端接口配置

    记录一下本地测试前端的时候怎么访问本地后端接口,文中给大家提到了vue如何做调试后台接口的配置和proxy的工作原理以及为什么能解决跨域,感兴趣的朋友跟随小编一起看看吧
    2023-06-06

最新评论