# 常用 Composition API

# setup

setup 是 Vue3.0 中的一个新的配置项,值为一个函数

组件中所用到的:数据,方法等,均要配置在 setup 中

setup 函数的两种返回值 :

  1. 若返回一个对象,则对象中的属性,方法,在模板中可以直接使用
  2. 若返回一个渲染函数:则可以自定义渲染内容

** 注意 : **

  1. 尽量不要与 Vue2 配置混用
    • Vue2 配置 (data, methods, computed…) 中可以访问但 setup 中的属性,方法
    • 在 setup 中不能访问到 Vue2 配置 (data, methods, computed)
    • 如果有重名,setup 有限
  2. setup 不能是一个 async 函数,因为返回值不再是 return 的对象,而是 promise, 模板看不到 return 对象中的属性
  3. setup 执行的时机
    • 在 beforeCreate 之前执行一次,this 是 undefined
  4. setup 的参数
    • props : 值为对象,包含:组件外部传递过来,且组件内部声明接受了的属性
    • context : 上下文对象
      • attrs : 值为对象,包含:组件外部传递过来,但是没有在 props 配置中声明的属性,相当于 this.$attrs
      • slots : 收到的插槽内容,相当于 this.$slots
      • emit: 分发自定义事件的函数,相当于 this.$emit

# ref

ref 用于定义一个响应式的数据

语法 : const xxx = ref(initValue)

  • 创建一个包含响应式数据的引用对象 (reference 对象)
  • JS 中操作数据: xxx.value
  • 模板中读取数据:不需要.value, 直接: <div>{{xxx}}</div>

备注 :

  • 接收的数据可以是:基本类型,也可以是对象类型
  • 基本类型的数据:响应式依然是靠 Object.defineProperty()getset 完成的
  • 对象类型的数据:内部使用了 Vue3 中的一个新函数 ——reactive 函数

# reactive 函数

定义一个对象类型的响应式数据 (基本类型不要用它,要用 ref 函数)

语法 : const 代理对象 = reactive(源对象) 接收一个对象 (或数组), 返回一个代理对象 (proxy 对象)

reactive 定义的响应式数据是深层次的

# Vue 中的响应式原理

# vue2 中的响应式

  • 实现原理 :

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

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

      1
      2
      3
      4
      Object.defineProperty(data, 'count', {
      get(){},
      set(){}
      })
  • 存在问题

    • 新增属性,删除属性,界面不会更新
    • 直接通过下标修改数组,界面不会自动更新

# vue3 中的响应式

  • 实现原理 :
    • 通过 Proxy (代理) : 拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等
    • 通过 Reflect (反射) : 对被代理对象的属性进行操作

# ref 对比 reactive

  • 从定义数据角度对比 :
    • ref 用来定义:基本数据类型
    • reactive 用来定义:对象 (或数组) 数据类型
    • 备注 : ref 也可以用来定义对象 (或数组) 类型数据,它内部会自动通过 reactive 转为代理对象
  • 从原理角度对比 :
    • ref 通过 Object.defineProperty() 的 get 和 set 来实现响应式 (数据劫持)
    • reactive 通过使用 Proxy 来实现响应式 (数据劫持), 并通过 Reflect 操作源对象内部的数据
  • 从使用角度对比 :
    • ref 定义的数据:操作数据需要 .value , 读取数据时模板直接读取不需要 .value
    • reactive 定义的数据:操作数据与读取数据:军不需要 .value

# computed 函数

  • 与 vue2 中 computed 配置功能一致

  • 写法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import {computed} from 'vue'

    setup() {
    //简写形式, 未考虑计算属性的值被更改的情况
    let fullName = computed(() => {
    return person.firstName + '-' + person.lastName
    })

    //完整形式
    let fullName = computed({
    get() {
    return person.firstName + '-' + person.lastName
    },
    set(value) {
    const nameArr = value.split('-')
    person.firstName = nameArr[0]
    person.lastName = nameArr[1]
    }
    })
    }