个人技术分享

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> 

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.definePropertyProxy 提供了更多的灵活性,可以监听对象属性的添加、删除、修改等操作。

  • 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在监听功能上存在一些明显的区别,这些区别主要体现在监听机制、语法和性能优化等方面。以下是详细的比较:

  1. 监听机制
    • Vue2使用Object.defineProperty进行数据的劫持,实现双向绑定。但这种方式对于新添加的属性无法直接进行监听,需要通过Vue.setthis.$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会自动触发必要的更新。

  2. 监听语法
    • Vue2中的监听主要通过watch选项或this.$watch方法来实现,用于监听data中的属性变化,并在变化时执行相应的回调函数。
    • Vue3同样提供了watchwatchEffect函数来监听数据变化,但它们的用法更加灵活和强大。watch函数可以监听特定的数据源,并在其变化时执行回调函数;而watchEffect则会自动收集其依赖,并在依赖变化时重新执行该函数。
  3. 深度监听与立即执行
    • 在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)时。

  4. 性能优化
    • Vue2的监听机制在性能上可能存在一定的开销,尤其是在处理大量数据或复杂逻辑时。
    • Vue3通过引入Proxy和Composition API等新技术,对性能进行了优化和提升,使得监听功能更加高效和灵活。
  5. 其他特性
    • 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', '