vue3 响应式API toRef()和toRefs()

111 阅读2分钟

isRef()和## isReactive()

isRef()检查某个值是否为 ref函数创建的,返回布尔值。

isReactive()检查一个对象是否是由 reactive() 或 shallowReactive() 创建的代理,返回布尔值。

isReadonly()检查一个对象是否是由 readonly() 或 shallowReadonly() 创建的代理,返回布尔值。

isProxy()检查一个对象是否是由 reactive()、readonly()、shallowReactive() 或 shallowReadonly() 创建的代理,返回布尔值。

toRef()

基于响应式对象上的一个属性,将对象中的该属性转化为响应式数据。即可用于解构对象的属性并且使创建的变量成为响应式数据。

<script setup>
  import {ref,reactive} from 'vue'
  let obj=reactive({name:"jzx",age:26});
  let {name}=obj;
  //隐式代码:let name=obj.name;  解构赋值就是用于创建变量
  let fn=()=>{
    name='jessica';
  }
  let look=()=>{
    console.log(name);
  }
</script>

<template>
  <div class="app">
    <p>{{name}}</p>
    <button @click="fn">change</button>
    <button @click="look">look</button>
  </div>
</template>

<style scoped lang='scss'>

</style>

2.gif

这样响应式对象解构的变量不是响应式的,变量的值改变了页面却没有刷新,就需要用到toRef()

<script setup>
  import {ref,reactive, toRef} from 'vue'
  let obj=reactive({name:"jzx",age:26});
  let name=toRef(obj,'name');
  let fn=()=>{
    name.value='jessica';
  }
  let look=()=>{
    console.log(name.value);
  }
</script>

<template>
  <div class="app">
    <p>{{name}}</p>
    <button @click="fn">change</button>
    <button @click="look">look</button>
  </div>
</template>

<style scoped lang='scss'>

</style>

2.gif

注意

  • toRef()参数:第一个参数是需要解构的对象,第二个参数是需要转化为响应式的属性名,注意属性名要加引号否则就是变量。

  • 转化为ref后setup函数内部js代码操作变量需要用.value来操作

toRefs()

toRefs(obj)是将整个对象转化成响应式数据,对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的,所以需要用.value来操作变量。只有一个参数是需要转化的对象。

响应式对象普通解构创建的变量不具有响应式

//响应式对象普通解构创建的变量不具有响应式
<script setup>
  import {ref,reactive, toRef,toRefs} from 'vue'
  let obj=reactive({name:"jzx",age:26,player:'actress'});
  let {name,age,player}=obj;
  let fn=()=>{
    name='jessica';
    age=33;
    player='singer';
  }
  let look=()=>{
    console.log(name,age,player);
  }
</script>

<template>
  <div class="app">
    <p>{{name}}---{{age}}----{{player}}</p>
    <button @click="fn">change</button>
    <button @click="look">look</button>
  </div>
</template>

<style scoped lang='scss'>

</style>

2.gif

let {name,age,player}=obj;
表示创建变量,let name=obj.name;
obj对象是响应式对象,但是obj.name取出的数据再赋值给name变量。
name变量在setup函数中创建的一个普通变量,用于页面显示时,只会在页面初始渲染时,会运行setup函数取出变量的值渲染在页面上,所以name变量不具有响应性。

响应式对象响应式解构创建的变量具有响应式

//响应式对象响应式解构创建的变量具有响应式
<script setup>
  import {ref,reactive, toRef,toRefs} from 'vue'
  let obj=reactive({name:"jzx",age:26,player:'actress'});
  let {name,age,player}=toRefs(obj);
  let fn=()=>{
    name.value='jessica';
    age.value=33;
    player.value='singer';
  }
  let look=()=>{
    console.log(name.value,age.value,player.value);
  }
</script>

<template>
  <div class="app">
    <p>{{name}}---{{age}}----{{player}}</p>
    <button @click="fn">change</button>
    <button @click="look">look</button>
  </div>
</template>

<style scoped lang='scss'>

</style>

2.gif

readonly

readonly()接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。即把readonly()返回的数据变为只读功能,不能给返回的数据做修改值的操作,做修改值的操作会得到一个警告。

<script setup>
  import {reactive, readonly} from 'vue'
  let person=reactive({name:'jessica',player:'singer'});
  let person1=readonly(person);
  let change=()=>{
  person1.name='hyomin';
};
let look=()=>{
  console.log(person1.name);
}
</script>

<template>
  <div class="app">
    <p>{{person.name}}---{{person.player}}</p>
    <button @click="change">change</button>
    <button @click="look">look</button>
  </div>
</template>

<style scoped lang='scss'>

</style>

image.png