当前位置: 首页 > 科技观察

别再把Vue的响应式原理和双向数据绑定搞混了

时间:2023-03-13 15:05:57 科技观察

前言在公司招人之前,面试了一些前端同学。因为公司使用的前端技术是Vue,难免要问一下它的响应式原理和Vue双向数据绑定。但是这里80%采访的同学都会把两者混淆。通常如果我先问响应式原理,再问双向数据绑定原理,大部分来面试的同学都会认为是一回事,所以这里就说看看两者的区别.响应性原则是Vue的核心特性之一。数据驱动视图。我们修改数据视图并更新它作为响应。很优雅~Vue2.x是借助Object.defineProperty()实现的,Vue3.x是借助Proxy实现的,先看看2.x的实现。Object.defineProperty(obj,key,{enumerable:true,configurable:true,//拦截get,当我们访问data.key时,会被这个方法拦截get:functiongetter(){//我们在这里收集依赖returnobj[key];},//拦截set,当我们给data.key赋值的时候,会被这个方法拦截到set:functionsetter(newVal){//数据变化时,通知依赖改变UI}})CopyCode我们通过Object.defineProperty为对象obj添加属性,我们可以设置对象属性的getter和setter函数。之后我们每次通过点语法获取属性的时候都会在这里执行getter函数。在这个函数中,我们会将调用这个属性的依赖收集到一个集合中;而当我们给属性赋值(修改属性)的时候,会触发这里定义的setter函数,会在二级函数中通知集合中的依赖进行更新,这样数据的变化就可以带动视图的变化。3.x的核心思想和2.x一样,只是数据劫持使用的是Proxy而不是Object.defineProperty,但是Proxy在处理数组和响应式处理新属性方面比Object.defineProperty更方便。letnObj=newProxy(obj,{//拦截get,当我们访问nObj.key时,会被这个方法拦截得到:function(target,propKey,receiver){console.log(`getting${propKey}!`);returnReflect.get(target,propKey,receiver);},//拦截set,当我们给nObj.key赋值时,会被这个方法拦截到set:function(target,propKey,value,receiver){console.log(`setting${propKey}!`);returnReflect.set(target,propKey,value,receiver);}})复制代码Proxy的详细使用方法参考ES6教程。Vue的响应式原理的实现细节相信大部分同学都已经很熟悉了,这里就不赘述了。如果想深入了解,或者想做一个简单的Vue实现,可以参考这篇Vue原理。相信你会收获很多。双向数据绑定双向数据绑定通常是指我们使用的v-model指令的实现。它是Vue的一个特性,也可以说是输入事件和值的语法糖。Vue通过v-model指令为组件添加输入事件处理和value属性赋值。复制代码上面的组件相当于下面的代码复制代码这样当我们修改input输入框的值的时候,我们通过v-model绑定的值也会同步修改。基于以上原理,我们可以很容易的实现一个双向数据绑定组件。v-model实践首先我们定义一个Vue组件,相信大家都已经很熟悉了。clickme{{value}}

复制上面的组件代码确定我们在props中添加value属性,并在value更新时触发input事件。在创建的hook和watch中赋值localvalue的目的是为了将父组件的状态同步到子组件。通过以上