1.双向数据绑定原理不同
- vue2通过Object.definedProperty()的get()和set()来做数据劫持、结合和发布订阅者模式来实现,Object.definedProperty()会遍历每一个属性。
- vue3通过proxy代理的方式实现。
Vue3 使用数据代理的优势有以下几点:1)definePropert 只能监听某个属性,不能对整个对象进行监听 2)可以省去for in,闭包等内容来提升效率(直接绑定整个对象即可)3)可以监听数组,不用再单独的对数组做特异性操作,Vue3可以检测到数组内部数据的变化
2.是否支持碎片
- vue2中必须要有根标签
- vue3中可以没有根标签,会默认将多个根标签包裹在一个fragement虚拟标签中,有利于减少内存。
3.API 类型不同
Vue2 使用选项类型api,选项型api 在代码里分割了不同的属性:data,computed,method等。
Vue3 使用组合式api,组合式api 能让我们使用方法来分割,相比于旧的api 使用属性来分组,这样代码会更加简便和整洁。
4.定义数据变量和方法不同
Vue2是把数据放到了data 中,在 Vue2中 定义数据变量是data(){},创建的方法要在method:{}
Vue3 就需要使用一个新的setup()方法,此方法在组件初始化构造的时候触发。使用以下三个步骤来建立反应性数据:1)从vue 引入 reactive;2)使用 reactive ()方法来声明数据为响应性数据;3) 使用setup()方法来返回我们的响应性数据,从而template 可以获取这些响应性数据。
5.生命周期钩子函数不同
Vue2 中的生命周期:beforeCreate 组件创建之前;created 组建创建之后;beforeMount 组件挂载到页面之前执行;Mounted 组件挂载到页面之后执行,beforeUpdate 组件更新之前;updated组件更新之后
Vue3 中的生命周期:setup 开始创建组件;onBeforeMount 组件挂载到页面之前执行;onMounted 组件挂载到页面之后执行;onBeforeUpdate 组件更新之前;onUpdated 组件更新之后;
而且 Vue3 生命周期在调用前需要先进行引入。除了这些钩子函数外,Vue3 还增加了 onRenderTracked 和onRenderTriggered 函数。
6.父子传参不同
Vue2 父传子,用props ;子传父用事件Emitting Events。在Vue2 中,会调用this$emit 然后传入事件名和对象。
Vue3 父传子,用props;子传父用Emitting Events 。在Vue3 中的setup()中的第一参数content 对象中就有 emit,那么我们只要在setup()接收第二个参数中使用分解对象法取出emit 就可以在setup 方法中随意使用了。
7.指令与插槽不同
Vue2 中使用slot 可以直接使用slot ;v-for 与v-if 在Vue2中优先级高的是v-for 指令,而且不建议一起使用。
Vue3 中必须是使用v-slot的形式;vue 3中v-for 与v-if ,只会把当前v-if 当作v-for 的一个判断语句,不会相互冲突;
移除keyCode作为v-on的修饰符,不支持config.keyCodes
移除v-on.native修饰符
移除过滤器filter
不允许直接使用slot,正确格式为 v-slot
8.diff算法不同
vue2中的diff算法
遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。
用patch记录的消息去更新dom
缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。
特点:特别要提一下Vue的patch是即时的,并不是打包所有修改最后一起操作DOM,也就是在vue中边记录变更新。(React则是将更新放入队列后集中处理)。
vue3中的diff算法
在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识。
只会比较patchFlags发生变化的节点,进行识图更新。而对于patchFlags没有变化的元素作静态标记,在渲染的时候直接复用。
9.setup
在 Vue 3 中,setup 函数是一个新的组件选项,用于替代 Vue 2 中的 beforeCreate 和 created 钩子函数。它是组件的入口点,并负责设置响应式数据、引入外部库等操作。
setup 函数接收两个参数:props 和 context。props 是组件的属性对象,可以通过解构的方式取得具体的属性值。context 是一个包含了一些常用方法和属性的对象,比如 attrs(非响应式属性)、emit(触发父组件事件方法)、slots(插槽)等。
在 setup 函数中,你可以通过返回一个对象来向模板中暴露响应式数据、方法和计算属性。这个对象中的属性将会被注入到模板中,并且可以直接在模板中使用。
setup执行的时机
在beforeCreate之前执行一次,this是undefined
setup的参数
props:值为对象,包含: 组件外部传递过来,且组件内部声明接收了属性
context:上下文对象
attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于 this.$attrs
slots:收到插槽的内容,相当于$slots
emit: 分发自定义事件的函数,相当于this.$emit
例如,下面是一个使用 setup 函数的示例:
import { ref } from 'vue';
export default {
setup(props, context) {
// 定义一个响应式数据
const count = ref(0);
// 定义一个方法
const increment = () => {
count.value++;
};
return {
count,
increment
};
}
}
在模板中,你可以直接使用 count 和 increment:
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
</div>
</template>
这样,每次点击按钮时,count 的值就会增加,并且模板中的数据也会相应地更新。
10.vuex和pinia的区别
11.Teleport瞬移组件
<Teleport> 是一个内置组件,它可以将一个组件内部的一部分模板"传送"到该组件的 DOM 结构外层的位置去。
<Teleport> 是一个内置组件,它可以将一个组件内部的一部分模板"传送"到该组件的 DOM 结构外层
的位置去。
<template>
<el-button @click="dialogVisible = true">打开弹窗</el-button>
<el-dialog
v-model="dialogVisible"
append-to-body
title="我是弹窗"
width="30%">
</el-dialog>
</template>
<script>
import { ref } from 'vue';
export default {
setup(){
const dialogVisible = ref(false);
return {
dialogVisible
}
}
}
</script>
<template>
<el-button @click="dialogVisible = true">打开弹窗</el-button>
<el-dialog
v-model="dialogVisible"
title="我是弹窗"
width="30%">
</el-dialog>
</template>
<script>
import { ref } from 'vue';
export default {
setup(){
const dialogVisible = ref(false);
return {
dialogVisible
}
}
}
</script>
<template>
<div class="app">
App组件
<Teleport to="body">
<div>我是被 teleport 包裹的元素</div>
</Teleport>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>
<template>
<div class="app">
App组件
<Teleport to="body">
<div>我是被 teleport 包裹的元素</div>
</Teleport>
</div>
<Teleport to="#customDom">
<p>我是被 teleport 包裹的一号元素</p>
</Teleport>
<Teleport to="#customDom">
<p>我是被 teleport 包裹的二号元素</p>
</Teleport>
</template>
禁用传送功能
在某些场景下可能需要视情况禁用 < Teleport >,我们可以通过对 < Teleport > 动态地传入一个 disabled prop 来处理这两种不同情况( disabled 属性接收一个 Boolean 值,true 代表不允许传送,false 代表传送)。
<Teleport to="body":disabled="true">
<p>我是被 teleport 包裹的元素</p>
</Teleport>
to 允许接收值:
期望接收一个 CSS 选择器字符串或者一个真实的 DOM 节点。
提示:
<Teleport> 挂载时,传送的 to 目标必须已经存在于 DOM 中。理想情况下,这应该是整个 Vue 应用 DOM 树外部的一个元素。
如果目标元素也是由 Vue 渲染的,你需要确保在挂载 <Teleport> 之前先挂载该元素。
< Teleport > 只改变了渲染的 DOM 结构,它不会影响组件间的逻辑关系。
多个 < Teleport > 组件可以将其内容挂载在同一个目标元素上,而顺序就是简单的顺次追加,后挂载的将排在目标元素下更后面的位置上。