Vue3技术6
- toRef和toRefs
- toRef
- App.vue
- Demo.vue
 
- toRefs
- App.vue
- DemoTwo.vue
 
- 总结
 
- shallowReactive与shallowRef
- shallowReactive
- App.vue
- Demo.vue
 
- shallowRef
- Demo.vue
 
- 总结
 
- readonly与shallowReadonly
- App.vue
- Demo.vue
- DemoTwo.vue
- 总结
 
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>

总结
- 作用:创建一个ref对象,其value值指向另一个对象中的某个属性
- 语法:const name=toRef(person,‘name’)
- 应用:要将响应式对象中的某个属性单独提供给外部使用时
- 扩展:toRefs与toRef功能一致,但可以批量创建多个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>

总结
- shallowReactive:只处理对象最外层属性的响应式(浅响应式)
- shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理
- 什么时候使用?
 (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>

总结
- readonly:让一个响应式数据变为只读的(深只读)
- shallowReadonly:让一个响应式数据变为只读的(浅只读)
- 应用场景:不希望数据被修改时








![[MLIR] 转换流程详解(以Toy接入为例)](https://img-blog.csdnimg.cn/img_convert/d9fb759eaf89d4b80c121b2eba0aea38.png)










