vue2和vue3的区别

248 阅读3分钟

1. vue2和vue3响应式原理发生了改变

vue2 的响应式原理是利⽤es5 的⼀个 API ,Object.defineProperty()对数据进⾏劫持结合发布订阅模式的方式来实现的

vue3 中使⽤了 es6 的 proxy API 对数据代理,通过 reactive() 函数给每⼀个对象都包⼀层 Proxy,通过 Proxy 监听属性的变化,从而实现对数据的监控。

这⾥vue3相⽐于vue2版本,使⽤proxy的优势如下

1.defineProperty只能监听某个属性,不能对全对象监听

2.可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)

3.可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。 (vue3.x可以检测到数组内部数据的变化)

2. Vue3支持碎片(Fragments)

vue2:vue2的template里面不能直接放2到多个根节点,需要外面套个盒子

    <template>
      <div>
        <h2> zzz </h2>
        <text> aaa <text>
      </div>
    </template>

vue3:vue3的template里面不需要外面套个盒子,直接放入根节点即可

    <template>
      <div> 13213 </div>
      <h2> 大家好 </h2>
      <text> 我是xxx <text>
    </template>

3.数据和方法的定义

Vue2使用的是选项类型API(Options API),Vue3使用的是组合式API(Composition API)

旧的选项型API(vue2)在代码里分割了不同的属性: data,computed属性,methods,等等。 新的组合式API(vue3)能让我们用方法(function)来分割,相比于旧的API使用属性来分组,这样代码会更加简便和整洁。

setup函数可以说是Vue3的属性和方法入口。在Vue2中,使用的是data、methods、computed 在Vue3中我们把属性和方法都放在setup函数中。

setup函数中有以下几个特点:

  1. setup(props,context):接收两个参数
  • props :接收来自父组件传来的参数
  • context :上下文,主要包含3个使用参数:attrs,emits,slots,相当于Vue2中this的 attrs,emits,slots
  1. 有返回值,返回值可以是两种:
  • 返回 对象 ,返回的对象中的属性方法,可在模板中直接使用;
  • 返回 渲染函数 ,可以自定义渲染的内容;
  1. vue3 函数内部没有this, vue2函数内部有this

  2. vue3 当内部有异步函数,需要使用到await的时候,可以直接使用,不需要在setup前面加async

4.生命周期钩子

vue2vue3说明
beforeCreatesetup()组件创建之前
createdsetup()组件创建完成
beforeMountonBeforeMount组件挂载之前
beforeUpdateonBeforeUpdate数据更新,虚拟DOM打补丁之前
updatedonUpdated数据更新,虚拟DOM渲染完成
beforeDestroyonBeforeUnmount组件销毁之前
destroyedonUnmounted组件销毁后
activatedonActivated
deactivatedonDeactivated
  • 若组件被<keep-alive>包含,则多出下面两个钩子函数。
  1. onActivated(): 被包含的组件,会多出两个生命周期钩子函数。激活时执行 。

  2. onDeactivated(): 比如从 A组件,切换到 B 组件,A 组件消失时执行。

5.Vue3的父子通信

  1. 父传子 父组件提供数据,父组件将数据传递给子组件,子组件通过defineProps进行接收子组件渲染父组件传递的数据
 // 父组件
    
    <template>
      <view :data="data"></view>
    </template>
    
    <script setup>
    import { ref } from "vue"
    
    const data = ref(100)
    
    </script>

 // 子组件
    
    <template>
      {{data}}
    </template>
    
    <script setup>
    import { defineProps } from "vue"
    // 如果使用defineProps接收数据,这个数据只能在模板中渲染,
    // 如果想要在script中也操作props属性,应该接收返回值。

    const props = defineProps({
      data: {
        type: Number,
        default: 1
      }
    })

    console.log('setup', props.data)
    </script>

  1. 子传父 在子组件中获取emit , defineEmits()子组件中用emit发送事件,父组件要监听子组件的事件,父组件提供事件的处理函数
 // 父组件 
    <template>
      <view :data="data"  @dataFn='dataFn'></view>
    </template>
    
    <script setup>
        
    import { ref } from "vue"

    const data = ref(100)

    const dataFn = (value) => {
      console.log(value)
      data.value = value
    }

    </script>
 
// 子组件
    <template>
       {{data}}
      <button @click="dataFn"></button>
    </templete>
    
    <script setup>
    import { defineProps,defineEmits } from "vue"
    
    // 如果使用defineProps接收数据,这个数据只能在模板中渲染,
    // 如果想要在script中也操作props属性,应该接收返回值。
    const props = defineProps({
      data: {
        type: Number,
        default: 1
      }
    })

    console.log('setup', props.data)

    const emit = defineEmits(['dataFn'])  // 获取父组件的传过来的数
    const dataFn = () => {
      emit('dataFn', 1000)
    }

    </script>