1.vue2和vue3的区别(vue3与vue2的区别(你不知道细节全在这)_vue2和vue3区别-CSDN博客)参考
- Vue3 在组合式(Composition )API,中使用生命周期钩子时需要先引入,而 Vue2 在选项API(Options API)中可以直接调用生命周期钩子
// vue3
<script setup>
import { onMounted } from 'vue'; // 使用前需引入生命周期钩子
onMounted(() => {
// ...
});
// 可将不同的逻辑拆开成多个onMounted,依然按顺序执行,不会被覆盖
onMounted(() => {
// ...
});
</script>
// vue2
<script>
export default {
mounted() { // 直接调用生命周期钩子
// ...
},
}
</script>
-
vue2只能有一个根节点,vue3支持多个根节点
-
vue2和vue3的响应式原理 :(浅析一下vue2.0 和 vue3.0 响应式原理 - 掘金 (juejin.cn))参考
Vue 2 的响应式原理
在 Vue 2 中,响应式系统是基于
Object.defineProperty实现的。当你把一个普通的 JavaScript 对象传给 Vue 实例的data选项,Vue 将遍历此对象所有的属性,并使用Object.defineProperty把这些属性全部转为 getter/setter,使数据变得“响应式”。
- getter:用于依赖收集。当组件渲染时,会访问到这些数据,此时 Vue 会记录这些组件作为依赖。
- setter:当数据改变时,setter 会被触发,然后通知所有依赖这个数据的组件重新渲染。
此外,Vue 2 提供了
watch选项,用于观察和响应 Vue 实例上的数据变动。但watch本身并不是响应式系统的核心部分,它只是 Vue 提供的一个工具,用于在数据变化时执行异步或开销较大的操作。Vue 3 的响应式原理
在 Vue 3 中,响应式系统得到了重构,基于 ES2015 的
Proxy对象来实现。相比于Object.defineProperty,Proxy提供了更多的灵活性,可以监听对象属性的添加、删除、修改等操作。
- Proxy:Vue 3 使用
Proxy来包装原始数据对象,创建一个代理对象。这个代理对象会拦截对原始数据的读取和修改操作,并在需要时触发相应的响应式逻辑。Vue 3 提供了
ref和reactive两个函数来创建响应式数据。
- ref:用于创建基本类型(如数字、字符串等)的响应式引用。
ref返回的是一个对象,其value属性包含实际的值。- reactive:用于创建复杂类型(如对象、数组等)的响应式引用。
reactive返回的是一个代理对象,可以直接操作这个代理对象来修改原始数据。总结
- Vue 2 的响应式系统基于
Object.defineProperty,通过 getter/setter 来实现数据的依赖收集和变化通知。- Vue 3 的响应式系统基于
Proxy,提供了更强大的数据监听能力。它使用ref和reactive来创建响应式数据。
watch在 Vue 2 和 Vue 3 中都是存在的,但它并不是响应式系统的核心部分,而是一个用于观察数据变化并触发相应逻辑的工具。
vue2 Object.defineProperty 和 vue 3 Proxy 区别:
Object.defineProperty:数据劫持
Proxy:数据代理 语法:Proxy构造函数:var proxy = new Proxy(target, handler);
常用生命周期对比如下表所示:

vue2和vue3的监听有什么区别 :
Vue2和Vue3在监听功能上存在一些明显的区别,这些区别主要体现在监听机制、语法和性能优化等方面。以下是详细的比较:
- 监听机制:
- Vue2使用
Object.defineProperty进行数据的劫持,实现双向绑定。但这种方式对于新添加的属性无法直接进行监听,需要通过Vue.set或this.$set方法手动添加响应式属性。在Vue 2中,如果你需要在数据对象上添加新的属性,并且希望这个新属性也是响应式的(即当它的值改变时,视图也会更新),你需要使用Vue.set方法或实例的this.$set方法。这是因为Vue 2使用Object.defineProperty来劫持对象的属性,但这种方式只能对已经存在的属性进行劫持,对于后来添加的属性则无法直接进行劫持。 下面是一个使用Vue.set或this.$set添加响应式属性的例子: new Vue({ el: '#app', data: { // 初始数据对象 person: { name: 'John', age: 30 } }, mounted() { // 使用 Vue.set 添加响应式属性 Vue.set(this.person, 'address', '123 Street'); // 或者使用实例的 $set 方法添加响应式属性 // this.$set(this.person, 'city', 'New York'); } }); 在上面的例子中,person对象最初只有两个属性:name和age。在组件挂载后(mounted钩子中),我们使用Vue.set方法向person对象添加了一个新属性address。现在,address是一个响应式属性,当它的值改变时,任何依赖于它的视图都会更新。 如果你使用的是Vue实例内部,更常见的是使用this.$set方法,因为this指向了Vue实例本身: mounted() { this.$set(this.person, 'city', 'New York'); }- Vue3则采用了Proxy来代理对象,它可以直接监听对象上的所有属性,包括后续添加的属性,无需手动添加响应式属性。
在Vue 3中,由于使用了Proxy来创建响应式对象,你可以直接向数据对象添加新属性,而不需要使用Vue.set或this.$set。Proxy会拦截对对象属性的访问和修改,使得新添加的属性也能保持响应式。 以下是一个Vue 3的示例,展示如何在组件中直接添加新属性: <template> <div> <p>Name: { { person.name }}</p> <p>Age: { { person.age }}</p> <p>New Property: { { person.newProperty }}</p> <button @click="addNewProperty">Add New Property</button> </div> </template> <script> import { ref, onMounted } from 'vue'; export default { setup() { const person = ref({ name: 'John', age: 30 }); // 添加新属性的方法 function addNewProperty() { // 直接添加新属性,不需要使用Vue.set或this.$set person.value.newProperty = 'This is a new property!'; } onMounted(() => { // 组件挂载后,你可以看到新属性已经被添加并且是响应式的 console.log(person.value.newProperty); // 初始为undefined,因为还没有添加 }); // 直接调用方法来添加新属性 addNewProperty(); return { person, addNewProperty }; } }; </script> 在上面的示例中,我们定义了一个响应式对象person,并在addNewProperty方法中直接向其添加了一个新属性newProperty。当按钮被点击时,这个新属性就会被添加到person对象中,并且因为它是直接添加到响应式对象上的,所以它是响应式的——即当它的值改变时,视图也会自动更新。 请注意,虽然你不需要使用Vue.set或this.$set来添加新属性,但如果你想要确保在添加新属性时触发视图更新(即使新属性的值没有变化),你可能需要强制Vue重新评估相关的计算属性或方法。这通常不是必要的,因为当你直接修改响应式对象的属性时,Vue会自动触发必要的更新。- 监听语法:
- Vue2中的监听主要通过
watch选项或this.$watch方法来实现,用于监听data中的属性变化,并在变化时执行相应的回调函数。- Vue3同样提供了
watch和watchEffect函数来监听数据变化,但它们的用法更加灵活和强大。watch函数可以监听特定的数据源,并在其变化时执行回调函数;而watchEffect则会自动收集其依赖,并在依赖变化时重新执行该函数。- 深度监听与立即执行:
- 在Vue2中,使用
watch监听对象时,如果需要深度监听对象内部属性的变化,需要设置deep: true选项。另外,如果需要监听器在创建时立即执行一次,可以设置immediate: true选项。- Vue3中的
watch函数也支持深度监听和立即执行,但语法和用法可能与Vue2有所不同。- 以下是Vue 2和Vue 3中
watch的示例代码,以展示深度监听和立即执行的不同语法和用法在Vue 2中,你可以使用watch选项来监听数据的变化,并可以通过设置deep: true来实现深度监听,以及设置immediate: true来让监听器在创建时立即执行一次。 new Vue({ el: '#app', data: { obj: { a: 1, b: 2 } }, watch: { obj: { handler(newVal, oldVal) { console.log('obj changed'); // 注意:这里不会深度监听obj内部属性的变化 }, deep: true, // 深度监听 immediate: true // 立即执行 } }, created() { // 由于设置了immediate: true,这里会打印'obj changed' } }); 但是,请注意,上面的watch只会告诉你obj对象本身是否发生了变化(比如,是否替换了整个对象),而不是它内部属性的变化。要监听obj内部属性的变化,你需要一个更具体的watch或者使用computed属性来配合。在Vue 3中,watch函数的使用方式有所不同,并且更灵活。你可以通过watch函数来监听单个数据或计算属性,也可以监听多个数据源。 以下是Vue 3中深度监听和立即执行的示例: import { ref, watch, onMounted } from 'vue'; export default { setup() { const obj = ref({ a: 1, b: 2 }); // 使用watch函数来监听obj的变化,并设置深度监听和立即执行 watch( () => obj.value, // 监听obj.value的变化 (newVal, oldVal) => { console.log('obj changed', newVal, oldVal); }, { deep: true, // 深度监听obj内部属性的变化 immediate: true // 立即执行监听器 } ); // 注意:由于Vue 3的setup是同步执行的,immediate: true会在watch函数被调用时立即执行 onMounted(() => { // setup中的代码是同步执行的,所以这里不会看到因为immediate: true而打印的日志 }); return { obj }; } }; 在Vue 3中,watch函数接受三个参数: 第一个参数是监听的数据源,可以是一个getter函数,也可以直接是ref或reactive对象的属性。 第二个参数是当数据源变化时要执行的回调函数。 第三个参数是一个选项对象,其中可以包含deep和immediate等选项。 请注意,Vue 3的setup函数是同步执行的,所以immediate: true会在watch函数被调用时立即执行,而不是在组件挂载(onMounted)时。- 性能优化:
- Vue2的监听机制在性能上可能存在一定的开销,尤其是在处理大量数据或复杂逻辑时。
- Vue3通过引入Proxy和Composition API等新技术,对性能进行了优化和提升,使得监听功能更加高效和灵活。
- 其他特性:
- Vue3中的监听功能还支持一些其他特性,如监听多个数据源、使用异步函数作为回调函数等。这些特性使得Vue3的监听功能更加强大和灵活。
综上所述,Vue2和Vue3在监听功能上存在明显的区别。Vue3通过引入Proxy和Composition API等新技术,对监听机制进行了改进和优化,使得其性能更加高效、语法更加灵活、功能更加强大。因此,在开发Vue项目时,建议根据项目需求和技术栈选择合适的Vue版本进行使用。
2.vue2和vue3中组件之间的传值方式
1.父传子
v2和v3的父传子差不多
// ParentComponent.vue
<template>
<ChildComponent :message="parentMessage" /> 父组件定义的变量parentMessage用message来绑定
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from Parent'
};
}
};
</script>
// ChildComponent.vue
<template>
<div>{
{ message }}</div>
</template>
<script>
export default {
props: ['message'] 用props来接收父组件绑定的方法
};
</script>
2.子传父
子传父
// ChildComponent.vue
<template>
<button @click="notifyParent">Notify Parent</button>
</template>
<script>
export default {
methods: {
notifyParent() {
this.$emit('child-event', '