您现在的位置是:首页 >技术教程 >Vue3技术6之toRef和toRefs、shallowReactive与shallowRef、readonly与shallowReadonly网站首页技术教程

Vue3技术6之toRef和toRefs、shallowReactive与shallowRef、readonly与shallowReadonly

VillanelleS 2023-06-09 20:00:03
简介Vue3技术6之toRef和toRefs、shallowReactive与shallowRef、readonly与shallowReadonly

toRef和toRefs

toRef

App.vue

<template>
  <button @click="toggle=!toggle">切换显示/隐藏</button>
  <Demo v-if="toggle"></Demo>
</template>

<script>
import {ref} from 'vue'
import Demo from "@/components/Demo";
export default {
  name: 'App',
  components: {Demo},
  setup(){
    const toggle=ref(true)
    return{toggle}
  },
}
</script>

Demo.vue

<template>
  <h2>个人信息</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>薪资:{{salary}}K</h2>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增加年龄</button>
  <button @click="salary++">涨薪</button>
</template>

<script>
import {reactive,toRef} from 'vue'
export default {
  name: "Demo",
  setup(){
    //数据
    let person=reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })

    const name1=person.name
    console.log("person.name",name1)  //输出只是字符串
    const name2=toRef(person,'name')
    console.log("toRef(person,'name')",name2)    //输出指向是person的name属性的ref对象

    //返回一个对象(常用)
    return{
      name:toRef(person,'name'),
      age:toRef(person,'age'),
      salary:toRef(person.job.j1,'salary')
    }
  },
}
</script>

<style scoped>

</style>

请添加图片描述

原理:
在这里插入图片描述

toRefs

App.vue

<template>
  <button @click="toggle=!toggle">切换显示/隐藏</button>
  <Demo v-if="toggle"></Demo>
  <hr>
  <DemoTwo></DemoTwo>
</template>

<script>
import {ref} from 'vue'
import Demo from "@/components/Demo";
import DemoTwo from "@/components/DemoTwo";

export default {
  name: 'App',
  components: {DemoTwo, Demo},
  setup(){
    const toggle=ref(true)
    return{toggle}
  },
}
</script>

DemoTwo.vue

<template>
  <h2>个人信息</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>薪资:{{job.j1.salary}}K</h2>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增加年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import {reactive,toRefs} from 'vue'
export default {
  name: "Demo",
  setup(){
    //数据
    let person=reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })


    console.log("-------------------------------------")
    const x=toRefs(person)
    console.log("toRefs(person)",x)

    //返回一个对象(常用)
    return{
      //toRefs返回的是一个对象,所以不能直接对象包对象,应该将两个对象合并
      ...toRefs(person)
    }
  },
}
</script>

<style scoped>

</style>

请添加图片描述

总结

  1. 作用:创建一个ref对象,其value值指向另一个对象中的某个属性
  2. 语法:const name=toRef(person,‘name’)
  3. 应用:要将响应式对象中的某个属性单独提供给外部使用时
  4. 扩展:toRefstoRef功能一致,但可以批量创建多个ref 对象,语法:toRefs(person)

shallowReactive与shallowRef

shallowReactive

App.vue

<template>
  <button @click="toggle=!toggle">切换显示/隐藏</button>
  <Demo v-if="toggle"></Demo>
</template>

<script>
import {ref} from 'vue'
import Demo from "@/components/Demo";

export default {
  name: 'App',
  components: {Demo},
  setup(){
    const toggle=ref(true)
    return{toggle}
  },
}
</script>

Demo.vue

<template>
  <h2>个人信息</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>薪资:{{job.j1.salary}}K</h2>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增加年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import {reactive,toRefs,shallowReactive} from 'vue'
export default {
  name: "Demo",
  setup(){
    //数据
    /*let person=reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })*/

	//只考虑第一层数据的响应式
    let person=shallowReactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })

    //返回一个对象(常用)
    return{
      ...toRefs(person)
    }
  },
}
</script>

<style scoped>

</style>

请添加图片描述

shallowRef

Demo.vue

<template>
  <h2>当前的x值是:{{x}}</h2>
  <button @click="x++">给x++</button>
  <h2>当前的a.b的值是:{{a.b}}</h2>
  <button @click="a.b++">给a.b的值++</button>
  <hr>
  <h2>个人信息</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>薪资:{{job.j1.salary}}K</h2>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增加年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import {reactive,toRefs,shallowReactive,shallowRef} from 'vue'
export default {
  name: "Demo",
  setup(){
    //数据
    /*let person=reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })*/

    //只考虑第一层数据的响应式
    let person=shallowReactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })

    const x=shallowRef(0)
    const a=shallowRef({
      b:0
    })
    console.log("x",x)
    console.log("a",a)


    //返回一个对象(常用)
    return{
      x,
      a,
      ...toRefs(person)
    }
  },
}
</script>

<style scoped>

</style>

请添加图片描述

总结

  1. shallowReactive:只处理对象最外层属性的响应式(浅响应式)
  2. shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理
  3. 什么时候使用?
    (1)如果有一个对象数据,结构比较深,但变化时只是外层属性变化 ===> shallowReactive
    (2)如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===>shallowRef

readonly与shallowReadonly

App.vue

<template>
  <button @click="toggle=!toggle">切换显示/隐藏</button>
  <Demo v-if="toggle"></Demo>
  <hr>
  <br>
  <br>
  <DemoTwo></DemoTwo>
</template>

<script>
import {ref} from 'vue'
import Demo from "@/components/Demo";
import DemoTwo from "@/components/DemoTwo";

export default {
  name: 'App',
  components: {Demo,DemoTwo},
  setup(){
    const toggle=ref(true)
    return{toggle}
  },
}
</script>

Demo.vue

<template>
  <h2>当前求和为:{{sum}}</h2>
  <button @click="sum++">点我和++</button>
  <hr>
  <h2>个人信息</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>薪资:{{job.j1.salary}}K</h2>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增加年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import {reactive, toRefs,ref,readonly} from 'vue'
export default {
  name: "Demo",
  setup(){
    //数据
    let sum=ref(0)
    let person=reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })

    person=readonly(person)
    sum=readonly(sum)


    //返回一个对象(常用)
    return{
      sum,
      ...toRefs(person)
    }
  },
}
</script>

<style scoped>

</style>

DemoTwo.vue

<template>
  <h2>当前求和为:{{sum}}</h2>
  <button @click="sum++">点我和++</button>
  <hr>
  <h2>个人信息</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>薪资:{{job.j1.salary}}K</h2>
  <button @click="name+='~'">修改姓名</button>
  <button @click="age++">增加年龄</button>
  <button @click="job.j1.salary++">涨薪</button>
</template>

<script>
import {reactive, toRefs,ref,shallowReadonly} from 'vue'
export default {
  name: "Demo",
  setup(){
    //数据
    let sum=ref(0)
    let person=reactive({
      name:'张三',
      age:18,
      job:{
        j1:{
          salary:20
        }
      }
    })

    person=shallowReadonly(person)


    //返回一个对象(常用)
    return{
      sum,
      ...toRefs(person)
    }
  },
}
</script>

<style scoped>

</style>

请添加图片描述

总结

  1. readonly:让一个响应式数据变为只读的(深只读)
  2. shallowReadonly:让一个响应式数据变为只读的(浅只读)
  3. 应用场景:不希望数据被修改时
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。