首页 > 其他分享 >vue2 与 vue3应用对比

vue2 与 vue3应用对比

时间:2024-10-22 23:18:59浏览次数:9  
标签:vue2 DOM 钩子 Vue3 Vue2 vue3 组件 对比 函数

  1. 生命周期对比

    • Vue2生命周期
      • beforeCreate:实例刚在内存中被创建出来,此时数据观测(data observer)和事件机制(event/watcher)都未初始化。主要用于一些插件的初始化工作,如在这个阶段可以引入一些全局的工具函数等。
      • created:实例已经创建完成,数据观测(data observer)和事件机制(event/watcher)已经初始化。可以进行数据的获取、初始化一些非DOM相关的数据等,比如发起Ajax请求获取数据来填充组件的数据。
      • beforeMount:在挂载开始之前被调用,相关的render函数首次被调用。可以对挂载前的DOM结构进行最后的调整,或者在挂载前对数据做一些检查和预处理。
      • mounted:实例挂载到DOM上,el被新创建的vm.$el替换。这是最常使用的生命周期钩子,用于操作DOM元素,如添加事件监听器、执行基于DOM的动画等。
      • beforeUpdate:数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前。可以在这里比较更新前后的数据,用于优化更新逻辑或者记录数据变化的日志。
      • updated:由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。应该避免在这个钩子中修改数据,否则可能会导致无限循环更新。主要用于在DOM更新后执行一些依赖于DOM状态的操作,如获取更新后的DOM元素尺寸等。
      • beforeDestroy:实例销毁之前调用。在这个阶段可以清除定时器、解绑事件监听器、取消订阅等操作,以防止内存泄漏。
      • destroyed:实例销毁后调用,此时所有的事件监听器和子组件都已经被移除。
    • Vue3生命周期
      • setup:这是Vue3新增的函数,在组件创建之前执行,用于组合式API的入口。在这里可以定义响应式数据、计算属性、方法等,返回的对象属性会暴露给模板和其他组件选项。
      • onBeforeMount:和Vue2的beforeMount类似,在组件挂载到DOM之前调用。
      • onMounted:和Vue2的mounted类似,组件挂载到DOM后调用。
      • onBeforeUpdate:和Vue2的beforeUpdate类似,在组件更新之前调用。
      • onUpdated:和Vue2的updated类似,在组件更新之后调用。
      • onBeforeUnmount:和Vue2的beforeDestroy类似,在组件卸载之前调用。
      • onUnmounted:和Vue2的destroyed类似,在组件卸载之后调用。
    • 主要区别
      • Vue3使用组合式API,将相关逻辑通过setup函数集中管理,生命周期钩子变成了基于函数的导入方式,使得代码逻辑更清晰,更易于理解和维护。而Vue2是通过选项对象的方式定义生命周期钩子。
  2. 全局钩子函数与组件钩子函数及应用场景

    • Vue2
      • 全局钩子函数:例如Vue.mixin可以定义全局混入,它会影响到所有组件。应用场景包括全局的错误处理、全局的数据预处理等。
      • 组件钩子函数:就是前面提到的各个生命周期钩子函数,应用场景主要是围绕组件自身的初始化、更新和销毁过程中的各种操作。
    • Vue3
      • 全局钩子函数:可以通过app.config.globalProperties来添加全局属性和方法,这些属性和方法可以在任何组件中访问。应用场景如添加全局的工具函数、全局状态管理等。
      • 组件钩子函数:通过导入onMounted等生命周期钩子函数在setup函数中使用,应用场景和Vue2类似,用于组件特定阶段的操作。
  3. 自定义指令用法

    • Vue2
      • 定义:通过Vue.directive('directiveName', { inserted: function (el, binding, vnode) {... } })来定义全局自定义指令,其中inserted是指令插入到DOM时触发的钩子函数。可以在对象中定义bind(指令绑定到元素时调用)、update(组件更新且指令所在的模板更新时调用)等钩子。
      • 应用:在模板中使用v - directiveName来应用指令。
      • 场景:用于操作DOM元素,如实现权限控制下的元素显示隐藏、实现拖拽功能等。
    • Vue3
      • 定义:通过const myDirective = { mounted(el, binding, vnode) {... }, updated(el, binding, vnode) {... } }定义指令对象,然后使用app.directive('directiveName', myDirective)来注册指令(app是应用实例)。
      • 应用:和Vue2类似,在模板中使用v - directiveName
      • 场景:同样用于操作DOM,如自定义表单验证的指令等。
  4. 混入与组合式API的区别及Vue3中的混入

    • 区别
      • 混入(Vue2和Vue3):是一种分发Vue组件中可复用功能的方式。它通过将一个对象的选项(如datamethodsmounted等)合并到组件选项中来实现复用。但是可能会导致命名冲突,并且逻辑分散,难以理解组件真正的行为来源。
      • 组合式API(Vue3):将组件的逻辑关注点(如响应式数据、计算属性、方法等)通过setup函数组合在一起。使得代码结构更加清晰,逻辑更易追踪,避免了混入的命名冲突问题。
    • Vue3中的混入:Vue3仍然支持混入,但是在新的项目中推荐使用组合式API。混入的用法和Vue2类似,通过Vue.mixin(全局)或者在组件选项中定义mixins属性(局部)来使用。
  5. Slot插槽用法对比

    • Vue2
      • 默认插槽:在子组件中使用<slot></slot>定义插槽位置,在父组件使用子组件标签内的内容填充。例如:
      <!-- 子组件 -->
      <template>
          <div>
              <slot></slot>
          </div>
      </template>
      <!-- 父组件 -->
      <template>
          <child - component>
              <p>这是插槽内容</p>
          </child - component>
      </template>
      
      • 具名插槽:在子组件中使用<slot name="slotName"></slot>定义具名插槽,在父组件通过v - slot:slotName或者#slotName(缩写)来指定内容填充。
    • Vue3
      • 默认插槽:基本用法和Vue2类似,不过在父组件使用v - slot的缩写#更推荐,例如 <child - component> #default { <p>这是插槽内容</p> } </child - component>
      • 具名插槽:和Vue2类似,但是缩写形式#slotName使用更广泛,并且语法更加简洁统一。同时,Vue3支持动态插槽名,通过v - slot:[dynamicSlotName]或者#[dynamicSlotName]来实现。
    • 改进:Vue3的插槽语法更加简洁明了,特别是缩写形式的广泛使用,使得模板代码更易读。动态插槽名的支持也增加了灵活性。
  6. 全局组件注册与局部组件注册用法

    • Vue2
      • 全局组件注册:使用Vue.component('component - name', Component)来注册全局组件,其中Component是组件的构造函数或者对象。注册后可以在任何组件的模板中使用<component - name></component - name>
      • 局部组件注册:在组件选项中定义components属性,例如components: { 'component - name': Component },然后在该组件的模板中使用。
    • Vue3
      • 全局组件注册:通过app.component('component - name', Component)来注册全局组件(app是应用实例),使用方式和Vue2类似。
      • 局部组件注册:和Vue2类似,在setup函数或者组件选项的components属性中定义组件。
  7. 数据的传递方式

    • Vue2
      • 父子组件数据传递:父组件通过props向子组件传递数据,子组件通过$emit触发事件来向父组件传递数据。
      • 兄弟组件数据传递:可以通过共同的父组件作为中间人,子组件A通过$emit向父组件传递数据,父组件再通过props将数据传递给子组件B。
      • 跨层级数据传递(非Vuex):可以使用provideinject,父组件通过provide提供数据,子孙组件通过inject获取数据。
    • Vue3
      • 父子组件数据传递:和Vue2类似,通过propsemit。不过emit的使用方式在setup函数中有一些语法上的变化,需要通过const emit = defineEmits(['event - name'])来获取emit函数。
      • 兄弟组件数据传递:同样可以借助共同的父组件或者使用Vuex等状态管理工具。
      • 跨层级数据传递(非Vuex):和Vue2类似,通过provideinject,并且在setup函数中使用更加方便,const data = inject('data - key')
  8. DOM操作的方式以及forceUpdate强制更新

    • Vue2
      • DOM操作:在mounted等生命周期钩子中可以通过this.$el来获取组件的根DOM元素,然后使用原生DOM API或者像jQuery这样的库来操作DOM。
      • 强制更新:可以通过this.$forceUpdate()来强制组件重新渲染,不过应该谨慎使用,因为这会绕过响应式系统的优化。
    • Vue3
      • DOM操作:在onMounted等生命周期钩子中获取ref引用的DOM元素来操作,例如const myDom = ref(null);在模板中通过ref="myDom"绑定,在onMounted中可以通过myDom.value来操作DOM。
      • 强制更新:Vue3没有$forceUpdate方法。一般情况下,如果数据是响应式的,数据变化会自动触发更新。如果确实需要强制更新,可以通过修改一个响应式数据来触发更新,例如const triggerUpdate = ref(0); triggerUpdate.value++;
  9. 响应式系统

    • Vue2
      • 使用Object.defineProperty()来进行数据劫持,实现响应式。这种方式对于对象新增属性需要使用Vue.set方法才能保证其响应式,对于数组的一些变异方法(如pushpop等)进行了重写来实现响应式更新。
    • Vue3
      • 采用Proxy对象来实现响应式。它可以直接代理整个对象,包括新增属性和删除属性都能很好地响应。这使得响应式数据的处理更加直观和灵活,减少了一些特殊情况的处理。例如:
      const data = {
          name: 'John',
          age: 30
      };
      const proxyData = new Proxy(data, {
          get(target, key) {
              console.log(`Getting ${key}`);
              return target[key];
          },
          set(target, key, value) {
              console.log(`Setting ${key} to ${value}`);
              target[key] = value;
              return true;
          }
      });
      
      • 改进点Proxy-based的响应式系统解决了Vue2响应式的一些限制,如新增属性需要特殊处理的问题,提供了更完整的对象代理能力,使得响应式数据的操作更加符合直觉。
  10. 生命周期钩子

    • Vue2
      • 生命周期钩子是通过选项对象的方式定义,如createdmounted等钩子函数是在组件选项中定义。
    • Vue3
      • 采用组合式API,新增setup函数作为组件逻辑的入口,生命周期钩子变成了基于函数的导入方式,如onMountedonUpdated等。这些函数需要从vue模块中导入并在setup函数中使用。例如:
      import { onMounted } from 'vue';
      export default {
          setup() {
              onMounted(() => {
                  console.log('Component mounted');
              });
              return {};
          }
      };
      
      • 改进点:组合式API的生命周期钩子使得代码逻辑更加集中,避免了在选项对象中分散定义生命周期钩子的情况,使得组件的逻辑结构更加清晰,尤其是在复杂组件中更容易理解和维护。
  11. 模板语法(部分改进)

    • Vue2
      • 已经有比较成熟的模板语法,如v - ifv - forv - bind(缩写为:)和v - on(缩写为@)等指令来实现条件渲染、列表渲染和事件绑定等功能。
    • Vue3
      • 延续了大部分Vue2的模板语法,但在一些细节上有所改进。例如,在插槽语法上更加简洁,v - slot的缩写#被更广泛地使用,并且支持动态插槽名,像v - slot:[dynamicSlotName]或者#[dynamicSlotName]这种形式。
      • 改进点:插槽语法的改进使得模板代码更加简洁明了,动态插槽名的支持增加了组件复用的灵活性,让开发者能够更方便地构建可复用的组件。
  12. 组件通信与数据传递

    • Vue2
      • 父子组件通过props$emit进行通信,兄弟组件可以借助共同的父组件或者事件总线来传递数据,跨层级组件(非Vuex)可以使用provideinject
    • Vue3
      • 基本的组件通信方式和Vue2类似,不过在setup函数中emit的使用方式有所变化,需要通过const emit = defineEmits(['event - name'])来获取emit函数。provideinjectsetup函数中使用更加方便,例如const data = inject('data - key')
      • 改进点:在组合式API下,组件通信的相关操作在setup函数中更加统一和规范,使得数据传递的逻辑更加清晰,尤其是在复杂的组件嵌套和通信场景下更容易管理。
  13. 性能优化

    • Vue2
      • 有一些性能优化的策略,如虚拟DOM的比较和更新。在更新组件时,会对新旧虚拟DOM树进行比较,通过最小化DOM操作来提高性能。
    • Vue3
      • 进一步优化了虚拟DOM的更新算法,提高了更新性能。同时,由于响应式系统的改进,数据更新和组件重新渲染的效率也有所提升。
      • 改进点:通过对虚拟DOM算法的优化和响应式系统的升级,Vue3在性能上有了显著的提升,尤其是在大型应用和频繁数据更新的场景下,能够提供更流畅的用户体验。
  14. TypeScript支持

    • Vue2
      • 对TypeScript的支持相对较弱,需要通过一些额外的工具和配置来更好地使用TypeScript,如vue - class - component库来以类组件的方式编写Vue2组件,以方便类型检查。
    • Vue3
      • 从设计之初就考虑了TypeScript的支持,组合式API与TypeScript配合得很好。在setup函数中,可以方便地定义和使用类型,使得代码的类型安全性大大提高。例如:
      import { ref } from 'vue';
      export default {
          setup() {
              const count: Ref<number> = ref(0);
              return { count };
          }
      };
      
      • 改进点:更好的TypeScript支持使得大型项目的开发更加稳健,减少了类型相关的错误,提高了代码的可维护性和可读性,符合现代前端开发对类型安全的要求。
  15. Vue2中的activateddeactivated

    • 定义
      • activated:这是一个组件生命周期钩子函数。当一个被keep - alive包裹的组件被激活时调用,即从缓存中重新显示时触发。
      • deactivated:同样是组件生命周期钩子函数。当一个被keep - alive包裹的组件失活时调用,即组件被缓存起来,从页面上隐藏时触发。
    • 应用场景
      • 数据缓存与恢复:在activated钩子中,可以检查组件的状态是否需要更新或恢复。例如,当一个包含表单的组件被缓存后重新激活,可能需要重新获取数据或者恢复之前的表单输入状态。假设我们有一个用户编辑表单组件:
      export default {
          data() {
              return {
                  user: {
                      name: '',
                      age: 0
                  }
              };
          },
          activated() {
              // 重新获取用户数据,更新user对象
              this.fetchUser();
          },
          methods: {
              fetchUser() {
                  // 模拟获取用户数据的API调用
                  const userData = api.getUser();
                  this.user.name = userData.name;
                  this.user.age = userData.age;
              }
          }
      };
      
      • 组件状态管理:用于处理组件内部状态,如定时器、动画状态等。例如,在activated中启动一个定时器,在deactivated中清除定时器,避免内存泄漏。
      export default {
          data() {
              return {
                  timer: null
              };
          },
          activated() {
              this.timer = setInterval(() => {
                  // 执行定时任务
                  console.log('Component is active');
              }, 1000);
          },
          deactivated() {
              clearInterval(this.timer);
          }
      };
      
  16. Vue3中的activateddeactivated

    • 定义
      • 从功能上来说和Vue2类似。在Vue3中,这些钩子函数是在setup函数内部通过导入来使用的。需要从vue模块中导入onActivatedonDeactivated函数。
    • 应用场景
      • 与Vue2类似的数据缓存和恢复:例如,对于一个包含大量数据请求的复杂组件,在onActivated中可以触发数据的重新加载。假设我们有一个数据展示组件:
      import { onActivated, ref } from 'vue';
      export default {
          setup() {
              const dataList = ref([]);
              onActivated(() => {
                  // 重新获取数据列表
                  getDataList().then((response) => {
                      dataList.value = response;
                  });
              });
              return {
                  dataList
              };
          }
      };
      
      • 资源管理和性能优化:和Vue2一样,在onDeactivated中可以清理一些不必要的资源占用,如停止正在运行的动画、释放网络请求等。例如,在一个具有动画效果的组件中:
      import { onDeactivated, ref } from 'vue';
      export default {
          setup() {
              const animationRunning = ref(true);
              onDeactivated(() => {
                  animationRunning.value = false;
                  // 清理动画相关资源
                  clearAnimationResources();
              });
              return {
                  animationRunning
              };
          }
      };
      

标签:vue2,DOM,钩子,Vue3,Vue2,vue3,组件,对比,函数
From: https://blog.csdn.net/m0_51244077/article/details/143170970

相关文章

  • Vue2 项目实战:打造一个简易倒计时计时器工具 Vue2 实践教程:如何实现一个工作与休息倒
    效果图Vue2倒计时计时器工具教程在本教程中,我们将一步步实现一个Vue2倒计时计时器工具。这个工具允许用户在工作和休息模式之间切换,并设置倒计时时间。倒计时结束时,系统会发出提醒,提示用户切换工作或休息状态。非常适合初学者练习Vue的数据绑定、计算属性和事件处理......
  • Yolo系列 V1和V2的对比
    在计算机视觉领域中,目标检测是一个核心问题,旨在识别图像中所有感兴趣的目标,并给出它们的类别和位置。近年来,随着深度学习技术的发展,目标检测领域取得了巨大的进步。Yolo(YouOnlyLookOnce)系列算法以其出色的速度和合理的精度,在实时目标检测任务中占据了重要的地位。本文将详细......
  • 开源表格识别模型对比
    引言表格结构识别功能是智能文档中很重要的一个模块,又加之表格种类繁多,且复杂,又进一步让表格识别任务变得更加困难。现阶段,开源的表格识别模型众多,但却难以有一个公平的对比,来方便我们在日常使用时选择合适的模型。因此,我们就以此为出发点,旨在解决评估开源表格模型评估问题,通过......
  • 低代码开发工具与传统开发工具的性能对比
    随着信息技术的不断发展,软件开发工具也在不断演进。低代码开发工具近年来逐渐兴起,与传统开发工具相比,它们在性能方面有着不同的特点。低代码开发工具的特点易用性高:低代码开发工具通常提供可视化的开发界面,用户可以通过拖拽、配置等方式快速构建应用程序,无需编写大量的代码......
  • vue3 使用swiper轮播组件
    1.本地环境信息参考node版本:nodejs:v18.20.4npm:10.7.0vue版本"dependencies":{"vue":"^3.2.13",...}2.安装swiper依赖执行命令:npmiswiper安装后,查看工程中的package.json文件,新增了swiper依赖(默认最新版):"dependencies":{......
  • micro-app【微前端实战】主应用 vue3 + vite 子应用 vue3+vite
    micro-app官方文档为https://micro-zoe.github.io/micro-app/docs.html#/zh-cn/framework/vite子应用无需任何修改,直接启动子应用即可。主应用1.安装微前端框架microAppnpmi@micro-zoe/micro-app--save2.导入并启用微前端框架microAppsrc/main.tsimp......
  • vue3 setup lang=ts实现router-link的动态传参
    一、实现目标 可以通过router-link在url里面配置参数然后传递给markdown页面 二、页面配置主页面,即配置router-link的页面templates:<router-link:to="{path:`/mark/${itemId}`}">fff</router-link>script:constitemId=ref('333'); 接收数据页面,即mark页面......
  • VMD-DBO-CNN-BiLSTM四模型多变量时间序列光伏功率预测一键对比 Matlab代码
    基于VMD-DBO-CNN-BiLSTM、VMD-CNN-BiLSTM、VMD-BiLSTM、BiLSTM四模型多变量时间序列光伏功率预测一键对比(仅运行一个main即可)[原创未发表]Matlab代码每个模型的预测结果和组合对比结果都有!运行步骤:1.先运行main1进行VMD分解2.在运行main2进行四模型一键对比代码......
  • 基于NRBO、CPO、TTAO、FVIM-CNN-LSSVM/CNN-LSSVM回归预测 5 模型一键对比 Matlab
    基于NRBO-CNN-LSSVM、CPO-CNN-LSSVM、TTAO-CNN-LSSVM、FVIM-CNN-LSSVM、CNN-LSSVM五模型多变量回归预测一键对比(仅运行一个main即可)Matlab代码代码解释:(优化算法均为24年算法)优化参数为:批次数、正则化系数、学习率【牛顿拉夫逊算法、冠豪猪算法、三角拓扑聚合算法、四向......
  • vue2组件
    模块和组件的区别1、模块化从代码逻辑的角度划分;方便代码分层开发,保证每个功能模块的职能单一2、组件化从UI界面的角度划分;前端的组件化,方便UI组件的重用父子组件传参1、父传子1、在父组件的子标签中自定义一个属性2、在子组件中使用props接收参数2、子传父1、在......