- Proxy和definedProperty对比
- Proxy 作为新标准将受到浏览器厂商重点持续的性能优化。
- Proxy 不兼容IE,也没有 polyfill, defineProperty 能支持到IE9。
- Proxy 能观察的类型比 defineProperty 更丰富。
- Object.definedProperty 是劫持对象的属性,新增元素需要再次 definedProperty。而 Proxy 劫持的是整个对象,不需要做特殊处理。
- 使用 defineProperty 时,我们修改原来的 obj 对象就可以触发拦截,而使用 proxy,就必须修改代理对象,即 Proxy 的实例才可以触发拦截。
- defineProperty只能监听某个属性,不能对全对象监听,可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)。
- proxy 可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。
- vue2是把数据放入data中;
- vue3就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。
- vue3 ref 跟 reactive 都是响应系统的核心方法,作为整个系统的入口。
vue3使用以下三个步骤来建立响应数据:
- 从vue引入reactive;( import {ref , reactive} from ‘vue’ //按需引入)
- 使用reactive() 方法来声明数据为响应性数据;(const _name= reactive({a:1,b:2}))
- 使用setup()方法来返回我们的响应性数据,从而template可以获取这些响应性数据。
- 生命周期对比
vue2 vue3
beforeCreate -> setup()
Created -> setup()
beforeMount -> onBeforeMount
mounted -> onMounted
beforeUpdate -> onBeforeUpdate
updated -> onUpdated
beforeDestroyed -> onBeforeUnmount
destroyed -> onUnmounted
activated -> onActivated
deactivated -> onDeactivated
vue2是选项式API: data,computed,methods等;
data() { return {}; }, methods:{ }
vue3是组合式API:数据和⽅法都定义在setup中,并统⼀进⾏return{}
vue3:setup(props,context){ console.log(‘props’,props)return{} }
- 父子传参对比
- vue3:setup()函数接收两个参数:props、context(包含attrs、slots、emit);
- vue3:因为setup函数中,props是响应式得,当传入新的prop时,它将会被更新,所以不能使用es6解构,因为它会消除prop得响应性。在组合式API中,如果想在子组件中用其它变量接收props的值时需要使用toRef将props中的属性转为响应式。
- 给父组件传值emit对比
vue2:this.$emit()
vue3:setup(props,context){context.emit()}
- 组件通信对比
- attrs和listeners对比
- vue2:子组件使用$attrs可以获得父组件除了props传递的属性。
- vue2:子组件使用$listeners可以获得父组件(不含.native修饰器的)所有v-on事件监听器。
- vue3:attrs不仅可以获得父组件传来的属性也可以获得父组件v-on事件监听器。
- v-for和v-if的优先级对比
- vue2:v-for的优先级高于v-if,可以放在一起使用,但增加性能开销。
- vue3:v-if的优先级高于v-for,一起使用会报错;通过在外部添加一个标签,将v-for放在外层。
- diff算法对比
vue2:diff算法遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。用patch记录的消息去更新dom。缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。
vue3:在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识,只会比较patchFlags发生变化的节点,进行视图更新,而对于patchFlags没有变化的元素作静态标记,在渲染的时候直接使用。
- 插槽方式对比
vue2:匿名插槽
//子组件:
<div><slot></slot>
</div>
//父组件:
<child><span>我是插槽插入的内容</span>
</child>
vue2:具名插槽
//子组件:
<div><slot name="person"></slot>
</div>
//父组件:
<child><span slot="person">插槽插入的内容</span>
</child>
vue2:作用域插槽:父组件模板的所有代码都在父级作用域内编译;子组件模板的所有代码都在子级作用域内编译。可以在父组件中使用slot-scope 特性从子组件获取数据。
<div><slot :data="data"></slot>
</div>
//父组件:
<child><span slot-scope="data">插槽插入的内容</span>
</child>
vue3:匿名插槽和vue2一样。
具名插槽:使用v-slot:
//子组件:
<div><slot name="person"></slot>
</div>
//父组件:
<child><template v-slot:person><span>插槽插入的内容</span></template>
</child>
vue3作用域插槽:
//子组件:
<div><slot :data="data"></slot>
</div>
//父组件:
<child><span #data>插槽插入的内容</span> 或者 <span #default="{data}">插槽插入的内容</span>
</child>
总结:
具名插槽使用方式不同:vue2使用slot=‘’,vue3使用v-slot:‘’
作用域插槽使用方式不同:vue2中在父组件中使用slot-scope=“data"从子组件获取数据,vue3中在父组件中使用 #data 或者 #default=”{data}"获取。
- 样式穿透对比
vue2
/deep/ 样式名{}
::v-deep 样式名{}
vue3
:deep (样式名{})
::v-deep(样式名{})