关键词搜索

全站搜索
×
密码登录在这里
×
注册会员

已有账号? 请点击

忘记密码

已有账号? 请点击

使用其他方式登录

Vue2 diff算法和Vue3 diff算法区别

发布2022-06-14 浏览1045次

详情内容

虚拟dom 是根据模板生成一个js对象(使用createElement方法),根据这个js对象再去生成真实的dom,对复杂的文档DOM结构,提供一种方便的工具,
进行最小化的DOM操作diff算法。 当data发生改变 会根据新的数据生成一个新的虚拟dom ,新的虚拟dom和旧的虚拟dom进行对比,这个对比的过程就是diff算法,  
但是因为这种机制也给代码运行带来了一些压力 效率低 消耗内存。一些不变的数据,例如常量,不会去修改它是不需要对比的,vue3是将变量赋值flag1,不变的值赋值flag,只会对比变动的值,因此比vue2性能更好他会查找模板中不同的数据,如果发现数据有不同就重新渲染模板。

附上理解图

Vue3 diff 势必会成为流行趋势 

在Vue3中diff是找变量判断不同处,如果是一个写死的值,根本不会变,
  所以不需要diff判断,变量绑定flag1,
  死值是flag,diff只找flag1的判断是否不同,在渲染操作,所以Vue2速度要快



v-model 通常使用在表单元素中 他是一个数据双向绑定的指令
一、vue和vue3的双向数据绑定
Vue2是采用observer观察者对数据劫持结合发布者-订阅者模式,
通过Object.defineProperty()将data中的所有的数据包括子属性对象的属性
都添加上了getter/setter方法,,通过compile去解析模板和"{{}}" ,
当数据发生变化利用watcher里面的update方法通知compile更新模板 ,
watcher就是用来监听页面数据变化的,wacther结合了observer观察者和complie指令解析器


二、 Vue2使用Object.defineProperty()的缺点
对于数组而言,大部分操作都是拦截不到的,只是 Vue 源码中通过重写函数的方式解决了这个问题。
七个编译数组的方法
比如通过下标方式修改数组数据或者给对象新增属性,这都不能触发组件的重新渲染,因为 Object.defineProperty 不能拦截到这些操作。

三、Vue3是通过Object.define.proxy 对对象进行代理,从而实现数据劫持。
使用Proxy 的好处是它可以完美的监听到任何方式的数据改变,唯一的缺点是兼容性的问题,
因为 Proxy 是 ES6 的语法

当然他可以绑定到组件上:
在大部分情况下, v-model 等价于 :value 和 @input事件的组合,
比如:下拉框 单选框 多行文本textarea绑定的就是@input=valueOfText=$event.target.value
在编程思想上,这种帮助使用者『隐藏细节』的方式叫封装

冷知识: 如果v-model绑定了相应式对象里不存在的值,vue会自动增加这个属性,并且是响应式的,
通俗总结:data中的user对象有name属性,没有age属性,但是v-model="user.age",user中就会增加一个相应式属性age

面试官: 如何让你开发的组件支持 v-model
答:组件使用v-model相当于在组件上添加:value @input事件,可以通过model属性自定义设置,
与data、props同级
在定义 vue 组件时,你可以提供一个 model 属性,用来定义该组件以何种方式支持 v-model。
model 属性本身是有默认值的,如下:


// 默认的 model 属性
export default {
  model: {
    prop: 'value',
    event: 'input'
  }
}


/*
   子组件
*/
<template>
<div>
  我几岁:{{ propsAge }}
  <el-button @click="age(1)">加</el-button>
  <el-button @click="age(-1)">减</el-button>
  <!-- 5+(-2)=3 -->
</div>
</template>
<script>
export default {
  props: {
    propsAge: {
    // 子组件接受的类型
      type: Number,
    }
  },
  model: { // 自定义v-model的格式
    prop: 'propsAge', // 代表 v-model 绑定的prop数据名
    event: 'ev' // 代码 v-model 通知父组件更新属性的事件名
  },
  methods: {
    age(num) {
      const sum = this.propsAge + num
      // 传到父组件,让父组件可以操作
      this.$emit('ev', sum)
    }
  }
}
</script>


/*
  父组件
*/
<template>
  <div id="about">
    <Hello-world v-model="d"></Hello-world>
  
  </div>
</template>
 
<script>
import HelloWorld from '../components/HelloWorld.vue'
export default {
  data() {
    return { d: 8 };
  },
  components: {HelloWorld},
};
</script>
点击QQ咨询
开通会员
上传资源赚钱
返回顶部
×
  • 微信支付
  • 支付宝付款
扫码支付
微信扫码支付
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载