vue3学习笔记

30 阅读5分钟

一. setup

  1. setup是一个函数
  2. Vue2.x中可以访问到setup的数据和函数,而setup不能访问Vue2.x,如果重名以setup优先
  3. setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性

二. ref函数

  1. 定义响应式数据
  2. 接收数据可以是基本类型和对象类型
  3. 基本类型的数据响应式依然是依靠Object.defineProperty()的get和set完成的
  4. 对象类型的数据响应式内部求助了Vue3.0中的一个新函数reactive函数
setup(){
    let name = ref('张三')
    function log(){
    console.log(name.value)
}}

三. reactive函数

  1. 定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
  2. reactive函数定义的响应式数据是深层次的
  3. 内部基于ES6的Proxy实现,通过代理对象操作源对象内部数据进行操作

四. Vue3.0中响应式原理

  1. Vue2.x的响应式

    • 实现原理:

      普通类型:通过Object.defineProperty()对属性的读取、修改进行拦截(数据劫持)。

      数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)。

    Object.defineProperty(data,'count',{
            get(){},
            set(){}
    })
    
    • 存在问题:

      新增属性、删除属性界面不会更新。

      直接通过下标修改数组,界面不会自动更新。

  2. Vue3.0的响应式

    • 实现原理:

      通过Proxy(代理):拦截对象中任意属性的变化,包括:属性的读写、属性的添加、属性的删除等。

      通过Reflect(反射):对被代理对象的属性进行操作。

五. setup注意点

  • setup执行的时机

    在beforeCreate之前执行一次,this是undefind

  • setup的参数

    props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。

    context:上下文对象

    attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于this.$attrs。

    slots:收到的插槽内容,相当于this.$slots。

    emit:分发自定义事件的函数,相当于this.$emit。

六. watch函数

  • 与Vue2.x中watch配置功能一致

  • 两个小“坑”:

    • 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
    • 监视reactive定义的响应式数据中某个属性时:deep配置有效。
  //情况一:监视ref定义的响应式数据
  watch(sum,(newValue,oldValue)=>{
    console.log('sum变化了',newValue,oldValue)
  },{immediate:true})
  
  //情况二:监视多个ref定义的响应式数据
  watch([sum,msg],(newValue,oldValue)=>{
    console.log('sum或msg变化了',newValue,oldValue)
  }) 
  
  /* 情况三:监视reactive定义的响应式数据
    若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
    若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
  */
  watch(person,(newValue,oldValue)=>{
    console.log('person变化了',newValue,oldValue)
  },{immediate:true,deep:false}) //此处的deep配置不再奏效
  
  //情况四:监视reactive定义的响应式数据中的某个属性
  watch(()=>person.job,(newValue,oldValue)=>{
    console.log('person的job变化了',newValue,oldValue)
  },{immediate:true,deep:true}) 
  
  //情况五:监视reactive定义的响应式数据中的某些属性
  watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
    console.log('person的job变化了',newValue,oldValue)
  },{immediate:true,deep:true})
  
  //特殊情况
  watch(()=>person.job,(newValue,oldValue)=>{
      console.log('person的job变化了',newValue,oldValue)
  },{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效

七. watchEffect函数

  • watch的套路是:既要指明监视的属性,也要指明监视的回调。

  • watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

  • watchEffect有点像computed:

    • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
    • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
  //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
  watchEffect(()=>{
      const x1 = sum.value
      const x2 = person.age
      console.log('watchEffect配置的回调执行了')
  })

八. 生命周期

  • beforeDestroy改名为 beforeUnmount

  • destroyed改名为 unmounted

  • Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:

    • beforeCreate===>setup()
    • created=======>setup()
    • beforeMount ===>onBeforeMount
    • mounted=======>onMounted
    • beforeUpdate===>onBeforeUpdate
    • updated =======>onUpdated
    • beforeUnmount ==>onBeforeUnmount
    • unmounted =====>onUnmounted

九. 更多Composition API

  1. shallowReactive 与 shallowRef

  2. readonly 与 shallowReadonly

  3. toRaw 与 markRaw

    • toRaw:

      • 作用:将一个由reactive生成的响应式对象转为普通对象
      • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
    • markRaw:

      • 作用:标记一个对象,使其永远不会再成为响应式对象。

      • 应用场景:

        1. 有些值不应被设置为响应式的,例如复杂的第三方类库等。
        2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。
  4. customRef

    作用:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。

  5. provide 与 inject

    • 作用:实现祖与后代组件间通信
    • 套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据
  6. 响应式数据的判断

    • isRef: 检查一个值是否为一个 ref 对象
    • isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
    • isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
    • isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

十. 新组件

  1. Fragment:根标签
  2. Teleport:组件移动
  3. Suspense