Vue3 ref和reactive 的使用

681 阅读3分钟

ref和reactive的使用

1.ref

  • ref 通常用来声明基础类型的数据,也可以用来声明对象、数组等引用类型、且声明的值是响应式的,使用ref 声明的引用类型可以直接进行整体的赋值替换 (reactive声明的不可以被整体替换) ,ref 的修改需要.value 的形式,需要.value的形式来操作的目标是ref左边最近的属性,但在模板渲染时可直接使用不需要.value。

    ref声明变量:

    // 声明基础类型
    const a = ref(1)
    const flag = ref (true)
    // 声明对象类型
    const obj = ref({
      a:1
    })
    // 被整个替换和单独修改属性
    obj.value.a = 2  // a =2 
    obj.value = {} // {}
    // 声明数组 
    const arr = ref([111,2222])
    // 可以被整个替换和单独修改
    arr.value = [333,555]   // [333,555] 
    arr.value[2] = 3333  // [111,2222,3333]
    arr.value.push(5555)  // [111,2222,5555]
    

    注意: 需要.value的形式来操作的目标是ref左边最近的属性,例如:

    const obj = ref(1) //操作 obj.value
    const obj = {  //操作  obj.c.value
      c:ref(1)     
    }
    const obj = ref({ //操作  obj.value.c
      c:1
    })
    ​
    

    注意: 如果需要在DOM模板中进行简单的表达式操作时,官方说: 被操作的属性必须暴露在最顶层。我自己说或者是在DOM模板中使用.value的形式进行操作

    例如:

    const obj = { 
      foo: ref(1) 
    }
    // 仅渲染
    {{ obj.foo }}
    // 操作时  错误的操作 
    {{ obj.foo + 1   }} 
    // 操作时 正确的操作
    // 1.暴露在最顶层
    const {foo} = obj
    {{foo+1}}
    // 2.或者使用.value
    {{obj.foo.value+1}}
    

    注意: 当一个ref声明的变量被reactive声明的对象用来嵌套赋值时,它会自动解包(当其作为浅层响应式对象(shallowReactive())的属性被访问时不会解包),不需要.value。此时如果直接去修改reactive声明的对象内的值,被用来嵌套的ref声明的变量也会随之改变,但是如果声明一个新的ref变量去更改reactive声明的对象内的值,之前的ref 变量的值不会被改变,因为此时reactive 声明的对象和之前的ref是 失去了联系。

    const a = ref(1)
    const obj = reactive({
      a
    })
    obj.a = 2  // 此时 a = 2   obj.a = 2
    // 如果
    const b = ref(3)
    obj.a = b // 此时 a = 1   obj.a = 2 
    

    注意: 当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时,不会进行解包。

    // 需要 .value 
    const books = reactive([ref('2222'),ref(3333)])
     <div v-for="item in books">
        {{item.value}}
      </div>
    ​
    // 需要 .value
    const map = reactive(new Map([['count', ref(2222)]]))
    console.log(map.get('count').value)
    ​
    // 不需要 .value
    const books = reactive(['2222',3333])
     <div v-for="item in books">
        {{item.value}}
      </div>
    

    疑问:(.value引起有疑问的地方): 我的猜测:.value的时候直接取的是值 相当于直接赋值3 没有.value 取的是proxy代理对象

    const foo = ref(1)
    const str = reactive({
      foo
    })
    const otherCount = ref(3)
    str.foo = otherCount.value
    // 此时 foo = 3   str.foo=3  otherCount=3
    const foo = ref(1)
    const str = reactive({
      foo
    })
    const otherCount = ref(3)
    str.foo = otherCount
    // 此时 foo = 1   str.foo=3  otherCount=3
    

2.reactive

  • reactive 用来声明 数组、对象、Map、Set等,对 stringnumberboolean 这样的原始类型无效,我们可以使用push 和 a.b.c =1 的形式修改值,但是我们不可以对使用reactive 声明的对象进行整体的赋值替换,这样响应式会失效。
  • shallowReactive() 是reactive的浅层作用形式。 shallowReactive声明的对象,只有第一层才是响应式的。

    const state = shallowReactive({
      foo: 1, // 改变时会响应
      nested: { // 改变时 不会响应
        bar: 2
      }
    })
    

结束

以上仅为学习笔记本,如有不对还望不吝指正,如对各位朋友有所帮助还请点赞和评论,谢谢~~