Vue3中Ref和Reactive的区别(简单清楚)

91 阅读2分钟

1.Ref

  1. 作用:定义一个数据的响应式
  2. 语法:const xx = ref(initValue)
  • 创建一个包含响应式数据的引用对象
  • js中操作数据:xxx.value
  • 模板中操作数据:不需要.value
  1. 一般用来定义一个基本类型的响应式数据
<template>
  <h2>{{count}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>

<script>
import {
  ref
} from 'vue'


export default {

  /* 在Vue3中依然可以使用data和methods配置, 但建议使用其新语法实现 */
  // data () {
  //   return {
  //     count: 0
  //   }
  // },
  // methods: {
  //   update () {
  //     this.count++
  //   }
  // }

  /* 使用vue3的composition API */
  setup () {

    // 定义响应式数据 ref对象
    const count = ref(1)
    console.log(count)

    // 更新响应式数据的函数
    function update () {
      // alert('update')
      count.value = count.value + 1
    }

    return {
      count,
      update
    }
  }
}
</script>

2.Reactive

  1. 作用:定义多个数据的响应式
  2. const proxy = reactive(obj):接收一个普通对象然后返回该普通对象的响应式代理器对象
  3. 响应式转换是“深层的”:会影响对象内部所有嵌套的属性
  4. 内部基于ES6的proxy实现,通过代理对象操作源对象内部数据都是响应式的
<template>
  <h2>name: {{state.name}}</h2>
  <h2>age: {{state.age}}</h2>
  <h2>wife: {{state.wife}}</h2>
  <hr>
  <button @click="update">更新</button>
</template>
<script>
/* 
reactive: 
    作用: 定义多个数据的响应式
    const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
    响应式转换是“深层的”:会影响对象内部所有嵌套的属性
    内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
*/
import {
  reactive,
} from 'vue'
export default {
  setup () {
    /* 
    定义响应式数据对象
    */
    const state = reactive({
      name: 'tom',
      age: 25,
      wife: {
        name: 'marry',
        age: 22
      },
    })
    console.log(state, state.wife)

    const update = () => {
      state.name += '--'
      state.age += 1
      state.wife.name += '++'
      state.wife.age += 2
    }

    return {
      state,
      update,
    }
  }
}
</script>

3.reactive与ref的细节(重要)

  1. 是Vue3的组合式API中2个最重要的响应式API
  2. ref用来处理基本类型数据,reactive用来处理对象(递归深度响应式)
  3. ref创建的变量必须使用.value(可以使用volar插件自动添加.value);reactive重新分配一个新对象,会失去响应式(可以使用object.assign去整体替换)
  4. 如果用ref对象/数组,内部会自动将对象转换为reactive的代理对象
  5. ref内部:通过给value属性添加getter/setter来实现对数据的劫持
  6. reactive内部:通过使用proxy来实现对对象内部所有数据的劫持,并通过Reflect操作对象内部数据
  7. ref的数据操作:在js中要.value,在模板中不需要(内部解析模板时会自动添加.value)

4.reactive与ref的使用原则

  1. 若需要一个基本类型的响应式数据,必须使用ref
  2. 若需要一个响应式对象,层级不深,ref、reactive都可以
  3. 若需要一个响应式对象,且层级较深,推荐使用reactive