Vue3 toRef、toRefs

news/2024/7/10 1:05:33 标签: vue

toRef

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

在 Vue3的响应式 中,我们写了一段 js 来模拟 vue3 的响应式

<script>
        //源数据
        let person = {
            name:"张三",
            age:18
        }
        const p = new Proxy(person,{
            //有人读取p的某个属性时调用
            get(target, p, receiver) {
                console.log(`有人读取了p身上的${p}属性`);
                //return target[p]
                return Reflect.get(target,p)
            },
            //有人修改、增加p的某个属性时调用
            set(target, p, value, receiver) {
                console.log(`有人修改了p身上的${p},我要去更新界面了`);
                //target[p] = value
                Reflect.set(target,p,value)
            },
            //有人删除p的某个属性时调用
            deleteProperty(target, p) {
                console.log(`有人删除了p身上的${p},我要去更新界面了`);
                //return delete target[p]
                return Reflect.deleteProperty(target,p)
            }
        })
    </script>

在这里插入图片描述
当修改 p 的属性时,会检测到然后打印相应信息,现在在刚才这段 js 最后增加一句以下代码,然后我们尝试修改 name 属性

let name = p.name

先输出 person 、 p 、name 看下结构,然后修改 name,发现只是修改了 name,p 中的值并未受到影响
在这里插入图片描述
然后我们来看下面一段代码,也是我们之前写过的例子,一个人的信息,然后点击按钮进行修改
在这里插入图片描述

<template>
  <h2>{{ person }}</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("name1", name1);

    const name2 = toRef(person.name);
    console.log("name2", name2);

    return {
      person,
      name: toRef(person, "name"),
      age: toRef(person, "age"),
      salary: toRef(person.job.j1, "salary"),
    }
  }
}
</script>

之前我们 return 中只返回 person,然后取值时使用 person.name、person.age等,如果我们想返回它的某些字段,就需要使用 toRef,例如返回 name 属性 name:toRef(person, "name")这样才能让数据依然是响应式的,在模板中可以直接使用 {{name}} 就可以取到值。如果在 return 中直接像以下代码这样写是不行的,因为返回的 name 不是响应式的

	错误代码:
	return {
      name: person.name,
      age: person.age,
      salary: person.job.j1.salary,
    }
	错误代码:
	return {
      ...person
    }

上边代码中我们输出了 name1 和 name2,可以看到 name1 仅仅是一个字符串,而 name2 是一个 ObjectRefImpl 。这就解释了为什么直接返回 person.name 不是响应式的了
在这里插入图片描述

toRefs

还是上边的代码,我们使用 toRefs,把 person 的第一层拆出来形成了一个对象,我们打印看看

	const x = toRefs(person);
    console.log(x);

在这里插入图片描述
所以刚才的代码可以改为:

<template>
  <h2>{{ person }}</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
        }
      }
    })

    const x = toRefs(person);
    console.log(x);

    return {
      person,
      ...toRefs(person)
    }
  }
}
</script>

或者

const {name,age,job} =  toRefs(person);
    return {
      person,
      name,
      age,
      job
    }

ref

vue2 中我们可以通过给元素添加ref=‘xxx’,然后在代码中通过refs.xxx的方式来获取元素。在 vue3 中也可以通过 ref 来获取元素,但不是像刚才说的方式,因为在 vue3 中没有$refs这些东西,我们可以通过一个例子来说明下,添加一个 input,让它自动获取焦点功能:

<template>
  <input type="text" ref="inputRef"/>
</template>

<script lang="ts">
import {defineComponent, ref,onMounted} from 'vue';

export default defineComponent({
  setup() {
    const inputRef = ref<HTMLElement|null>(null);
    //页面加载后的生命周期
    onMounted(()=>{
      inputRef.value && inputRef.value.focus()
    })

    return{
      inputRef
    }
  }
});
</script>

在这里插入图片描述


http://www.niftyadmin.cn/n/1816678.html

相关文章

EasyX图形库__C语言__贪吃蛇核心代码

EasyX图形库__C语言__贪吃蛇核心代码 前言&#xff1a;&#xff08;第一次博客啊&#xff0c;格式不太会&#xff09; 简介&#xff1a; 1.虽然用的是EasyX的图形库&#xff0c;但其实EGE应该也可以&#xff0c;函数功能好多都是相通的&#xff1b; 2.去掉注释&#xff0c;代…

ip的正则表达式 完美版

IP地址的长度为32位2进制&#xff0c;分为4段&#xff0c;每段8位&#xff0c;用十进制数字表示&#xff0c;每段数字范围为0~255&#xff0c;段与段之间用英文句点“.”隔开。例如&#xff1a;IP地址为10.0.0.100。 分析IP地址的每组数特点&#xff1a;百位&#xff0c;十位&…

推荐一款2D游戏引擎:HGE

Haafs Game Engine 目前已经是1.81版了。目前已完全遵循zlib/libpng许可开源的&#xff0c;即时您是商业使用&#xff0c;也是免费的哦&#xff01; 官方网站&#xff1a;http://www.relishgames.com/ HGE中文社区&#xff1a;http://www.hgechina.com 引用官方的话&#xff1a…

Vue3 其他Composition API

文章目录shallowReactive 和 shallowRefreadonly 与 shallowReadonlytoRaw 和 markRawCustomRefprovide 和 inject响应式数据的判断Composition API的优势shallowReactive 和 shallowRef 作用 shallowReactive&#xff1a;只处理对象最外层属性的响应式&#xff08;浅响应式) …

DevCpp和VS2019安装armadillo库

DevCpp中 点这里下载armadillo 然后解压出来一个文件夹"armadillo-10.4.0", 找到include 看到这两项&#xff0c;就是我们要copy的 找到你DevCpp安装的位置 这里我装的是MinGW&#xff0c;如果你的是TDM-GCC同理 点开编译器的include文件夹 把我们解压出来…

canvas 绘点图

canvas 绘点图 项目中需要一个记录点实时变动的信息&#xff0c;在此记录一下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><script src"http://cdn.b…

避坑_数组转化为指针的规则

今天有人问我scanf输入字符串为什么不加&&#xff0c;我果断给他解释一波…… 但是自己顺手又加上&试了一波&#xff1a; 我真的是一脸懵逼&#xff0c;原本还以为掌握指针了&#xff0c;结果被这么小的问题卡住&#xff0c;我想不明白&#xff0c;去查书、百度了一波…

jquery插件开发模板

(function($){ $.fn.extend({ //将可选择的变量传递给方法pluginname: function(options) { //设置默认值并用逗号隔开var defaults { padding: 20, mouseOverColor : #000000, mouseOutColor : #ffffff } var options $.extend(defaults, options); return this.…