Vue 的响应式原则与双向数据绑定

更新日期: 2022-08-22 阅读: 1.3k 标签: 响应式

反应性原则

它是 vue.js 的核心特性之一,一个数据驱动的视图,我们修改数据视图来响应更新,非常优雅。

Vue2.x 使用 Object.defineProperty() 实现,而 Vue3.x 使用 Proxy 实现。 我们先来看看2.x的实现。

Object.defineProperty(obj, key, {
   enumerable: true,
   configurable: true,
   get: function getter () {
       return obj[key];
   },
   set: function setter (newVal) {
       ...
    }  
})

我们通过Object.defineProperty给对象obj添加属性,可以设置对象属性的getter和setter函数

之后,我们每通过点语法获取一个属性,就会执行这里的getter函数。 在这个函数中,我们会将调用这个属性的依赖收集到一个集合中; 当我们给属性赋值时,这个定义就会被触发。 setter函数,在辅助函数中,会通知集合中的依赖更新,让数据变化驱动视图变化。

3.x的核心思想和2.x一样,只是在数据劫持上使用了Proxy而不是Object.defineProperty,但是在处理数组和响应式处理新属性时Proxy比Object.defineProperty更方便 .

let nObj=new Proxy(obj,{
 get: function (target, propKey, receiver) {
   console.log(`getting ${propKey}!`);
   return Reflect.get(target, propKey, receiver);
 },
 set: function (target, propKey, value, receiver) {
   console.log(`setting ${propKey}!`);
   return Reflect.set(target, propKey, value, receiver);
 }
})

Vue响应式原理的实现细节相信大部分人已经很熟悉了,这里不再赘述。

双向数据绑定

双向数据绑定通常是指我们使用的 v-model 指令的实现。 它是 Vue 的一个特性,也可以说是输入事件和值的语法糖。 Vue 通过 v-model 指令为组件添加输入事件处理和值属性赋值。

<template>
  <input v-model='localValue'/>
</template>

上面的组件等价于下面的代码

<template>
  <input @input='onInput' :value='localValue' />
  <span>{{localValue}}</span>
</template>
<script>
 export default{
   data(){
     return {
       localValue:'',
     }
   },
   methods:{
     onInput(v){
        this.localValue=v.target.value;
        console.log(this.localValue)
     }
   }
 }
</script>

因此,当我们修改输入框的值时,我们通过v-model绑定的值也会同步修改。 基于以上原理,我们可以轻松实现一个双向数据绑定组件。

v-model实践

首先,我们定义一个Vue组件:

<tempalte>
 <div class="count" @click="addCount">click me {{value}}</div>
</template>
<script>
export default{
     props:{
       value:{
         type:Number,
         default:0
       }
     },
     watch:{
       value(v){
         this.localvalue=v;
       }  
     },
     methods:{
       addCount(){
          this.localvalue++;
          this.$emit('input',this.localvalue);
       }
     },
     data(){
       return{
         localvalue:0
       }
     },
     created(){
       this.localvalue=this.value;
     }
   }
</script>

上面的组件指定我们在 props 中添加 value 属性,并在 value 更新时触发 input 事件。 在创建的 hook 和 watch 中对 localvalue 的赋值是将父组件的状态同步到子组件。

通过上面的组件定义,我们可以使用 v-model 指令对组件进行双向数据绑定。

<template>
 <add-one v-model="count"></add-one>
 <span>The parent component{{count}}</span>
</tempalte>
<script>
export default{
 data() {
   return {
      count: 0,
   };
 },
 methods: {
 },
  created(){    
 }
}
</script>

以下是实际效果。


当然,我们也可以不使用 value 和 input 事件的组合。 为了让组件的定义更加语义化,我们还可以自定义属性和事件,实现双向绑定。 我们可以在组件的模型选项中设置值和事件。 如下:

export default{
 model:{
   value:'count',
   event:'change'
 },
 props:{
   count:{
     type:Number,
     default:0
   }
 },
 methods:{
   addCount(){
      this.localvalue++;
      this.$emit('change',this.localvalue);
   }
 },
}

由上述组件定义。

<add-one v-model="count"></add-one>

相当于:

<template>
  <add-one @change='onChange' :count='count'></add-one>
  <span>{{count}}</span>
</template>
<script>
 export default{
   data(){
     return {
       count:0,
     }
   },
   methods:{
     onChange(v){
        this.count=v;
        console.log(this.count)
     }
   }
 }
</script>

只是v-model指令帮我们做了上面的事件添加、属性绑定和状态同步操作。

来源: web前端开发

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/12028

相关推荐

移动端web app要使用rem实现自适应布局:font-size的响应式

rem是相对于根元素html,这样就意味着,我们只需要在根元素确定一个px字号,则可以来算出元素的宽高。

使用现代CSS的响应式版面

通过模块化缩放,使用传统属性和calc()来动态缩放你的字体大小.为字体大小使用百分比.给文本内容和媒体查询使用em,针对不同视口尺寸使用不同缩放值.视口越小,缩放比例越小,使用媒体查询或者media()函数基于视口来改变比例和基础字号

HTML5+CSS3响应式垂直时间轴,高端,大气

HTML5+CSS3响应式垂直时间轴,使用了HTML5标签<section>,时间轴中所有的内容包括标题、简介、时间和图像都放在.cd-timeline-block的DIV中,多个DIV形成一个序列,并把这些DIV放在<section>中。

实现移动端响应式布局

我们选择了 rem 作为像素单位。因为本次开发的项目包含 ipad 与手机端,使用 rem 单位应对的根元素字体可以根据设备动态设置。因此 ipad 端与手机端公共的样式只需要写一套代码就能实现,而使用vw作为单位在无论什么情况

js+rem动态计算font-size的大小适配各种手机设备

需求:在不同的移动终端设备中实现,UI设计稿的等比例适配。使用js动态改变html的字体大小font-size+rem的特性,来保证最初的设计图中每个元素的尺寸比例不变

web响应式图片的5种实现

在目前的前端开发中,我们经常需要进行响应式的网站开发。本文着重介绍一下弹性图片,也就是响应式图片的解决方案:js或服务端、srcset 、sizes 、picture标签、svg图片

Vue 添加响应式属性

v-model 帮你把数据 set 了,自然一切正常;操作二,@input 先把属性直接静态添加了,到了 v-model 的时候 set 不会再劫持已经存在的属性。这就引出了一个需要注意的地方,若是先直接赋值,即使再用 set 也不能再劫持这个属性了

vue响应式原理及依赖收集

Vue通过设定对象属性的setter/getter方法来监听数据的变化,通过getter进行依赖收集,而每个setter方法就是一个观察者,在数据变更的时候通知订阅者更新视图。

深入响应式原理

说到响应式原理其实就是双向绑定的实现,说到 双向绑定 其实有两个操作,数据变化修改dom,input等文本框修改值的时候修改数据1. 数据变化 -> 修改dom;2. 通过表单修改value -> 修改数据

Responsive Web Design 响应式网页设计

常见的布局方案:固定布局:以像素作为页面的基本单位,不管设备屏幕及浏览器宽度,只设计一套尺寸;可切换的固定布局:同样以像素作为页面单位,参考主流设备尺寸

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!