Vue学习记录之三(ref全家桶)

news2024/9/20 21:16:28

ref、reactive是在 setup() 声明组件内部状态用的, 这些变量通常都要 return 出去,除了供 < template > 或渲染函数渲染视图,也可以作为 props 或 emit 参数 在组件间传递。它们的值变更可触发页面渲染。

ref :是一个函数,用于创建一个响应式的引用,通俗的说就是把一个变量转变成响应式变量。定义基本类型数据(支持所有的类型).能指定基础类型和复杂类型. 也可以读取dom(详见实例1)

isRef: 是判断一个对象是否是Ref 类型。

Ref :是 TypeScript 中的类型,用于描述由 ref 创建的响应式对象的类型。
import type {Ref} from ‘vue’
const count: Ref = ref(0);

reacive:和ref功能相同,但是使用范围不同。只能指定基础类型(引用类型), 定义对象(或数组)类型(引用类型) Array,Object,Map,Set。 其次ref 取值或者修改值需要用到value, 而reactive则不需要。reacive 不能直接赋值,否则就会破坏其响应式, readonly可以将其属性转化为只读。其次shallowReactive也是浅层响应。 详见实例4

shallowRef : 用于浅层响应式的。ref 可以做深层次相应的。但是在同一个方法中,二者不可以同时使用,否则shallowRef 就会失去浅层相应。 二者的底层都是triggerRef,所有被强制执行了。

triggerRef: 强制更新页面DOM,一般情况下不直接使用。

customRef :顾名思义,就是可以自定义ref函数。接受一个工厂函数作为参数,这个工厂函数返回一个对象,该对象需要实现 get 和 set 方法。 一般情况下用不到,属于高级编程。 详见实例2

toRefs: 使从reactive定义的解构数据变成响应式的。用于将整个 reactive 对象中的每个属性转换为 ref,适合解构赋值的场景。

toRef:用于将 reactive 对象中的单个属性转换为 ref,适合只处理某个特定属性的场景。是对传入对象指定属性的响应式绑定,值改变不会更新视图。只能修改响应式对象的值,非响应式视图毫无变化。该函数需要两个参数,第一个是对象,第二个是对象的属性。

它们的主要区别在于作用的范围:toRefs 处理所有属性,而 toRef 仅处理单个属性

toRaw: 用于获取响应式对象的原始数据对象,不受响应式系统的影响。就是解除响应式。
左侧是: man对象,右侧是 toRaw(man)
在这里插入图片描述

我们可以自己编写一下toRefs的功能:

const man = reactive({name:'lvmanba', age:50, like: 'eat'})
const toRefs = <T extends object>(object:T) =>{
    const map:any = {}
    for(let key in object){
      map[key] = toRef(object,key)
    }
    return map
}

const {name,age,like} = toRefs(man)

toRef、toRefs 用于处理 组件/函数 传递的响应式数据,如:在接收父组件 props 时 / 或 composables 组合式函数返回数据时建立起某些属性的响应式引用;
通过 ref 包装的属性在 setup 函数内都需要通过 .value 去访问它值 ( template 模版内不用 )。因此,ref、toRef 创建的变量值都需要用变量 .value 读取。reactive 则不用,因为会自动解包分配给它的 ref。
至于 toRefs,如果是解构赋值,如: const { state1, state2 } = toRefs(props),值需要这样获取:state1.value.count;
若整体赋给一个变量,如:const state = toRefs(props),则是 state.state1.value。
只有 toRefs 可以解构;

实例1

<template>
  <div>{{Man}}</div>
  <div>{{Man2}}</div>
  <button @click="change">修改</button>
</template>
<script setup lang='ts'>
import { ref,reactive, shallowRef,triggerRef, customRef } from 'vue'
import type {Ref} from 'vue'
//const Man = {name: "lvmanba"}  //下面将无法修改
type M = {
  name: string
}
//可以使用两种方式,第一种(Ref)如果类型比较复杂,则推荐使用。一般使用第二种。
//第一种:
//const Man:Ref<M> = ref({name:"lvmanba"})
//第二种:
//const Man = ref<M>({name:"lvmanba"})   //ref<泛型类型>({对象})
//第三种:
const Man = ref({name:"lvmanba1"})   //让自己判断类型
const Man2 = shallowRef({name:"lvmanba2"})  //应该是浅层相应,只能到value。
const change = () =>{
  // ref 返回的是ES6的class类,通过它里面的属性value来获取值。 固定语法
  //Man.value.name = "lvmanba1-1"
  //Man2.value.name = "lvmanba2-1"
  //注意,如果同时在一个方法中修改ref和shallowRef两种类型,则shallowRef失效。 修改shallowRef类型的值有两种方法。
  //方法1:
  Man2.value.name = "lvmanba2-1"
  triggerRef(Man2)
  //方法2:
  /*
  Man2.value = {
    name:"我被修改了"
  }
  */
  console.log(Man)
}
</script>
<style scoped>

</style>

实例2: 自定义ref

<template>
  <div>{{Man}}</div>
  <button @click="change">修改</button>
</template>
<script setup lang='ts'>
import { ref,reactive, shallowRef,triggerRef, customRef} from 'vue'
function MyRef<T>(value:T){
  //它是一个回调函数,要求返回一个对象,需要传递2个参数track,trigger
  return customRef((track,trigger)=>{
    return {
      get(){
        //用来收集依赖
        track()
        return value
      },
      set(newVal){
        //触发依赖
        value = newVal
        trigger()
      }
    }
  })
}
const Man = MyRef<string>("你好")
const change = () =>{
  Man.value = "不好"
}
</script>

上述可以实现防抖功能:函数改进如下

function MyRef<T>(value:T){
  //它是一个回调函数,要求返回一个对象,需要传递2个参数track,trigger
  return customRef((track,trigger)=>{
    let timer: any
    return {
      get(){
        //用来收集依赖
        track()
        return value
      },
      set(newVal){
        //触发依赖
        clearTimeout(timer)
        timer = setTimeout(()=>{
          console.log("我被触发了")
          timer = null
          value = newVal
          trigger()
        },500)
        
      }
    }
  })
}

实例3: ref 读取dom

<template>
  <div>{{ name }}</div>
  <div class="container" ref="doms"> 这个是内容的主题</div>
  <button @click="changes">修改值</button>
</template>
<script setup lang='ts'>
import { ref,reactive, shallowRef,triggerRef, customRef} from 'vue'
const name = ref("lvmanba")
const doms = ref<HTMLDivElement>()
//console.log(doms.value?.innerHTML)  //这个阶段,html还没有被渲染,我们可以随便加入一个函数
const changes = () =>{
  name.value = "lvmanba2"
  console.log(doms.value?.innerHTML)
}
</script>

实例4 : reactive 实际应用

<template>
  <form>
    <input v-model="form.name" type="text">
    <br>
    <input v-model="form.age" type="text">
    <br>
    <button @click.prevent="submit">提交</button> <!--.prevent 阻止默认提交-->
  </form>
  <hr>
  <button @click="add">添加数组</button>
  <div>
    <li v-for="item in list">{{ item }}</li>
  </div>
  
</template>
<script setup lang='ts'>
import { ref,reactive, shallowRef,triggerRef, customRef} from 'vue'
//第一种 对象
const form = reactive({
  name: "张三",
  age: 20
})
const submit=()=>{
  console.log(form)
}
//第二种是 数组
let list = reactive<string[]>(['a','b','c'])
const add = () =>{
  //第一种方法,同步
  //list.push("ABC")
  //第二种方法,异步
  setTimeout(()=>{
    let res = ['ABC','EFG','HIG','KLM']
    //list = res   //reacive 不能直接赋值,否则就会破坏其响应式
    list.push(...res)  //... 是扩展运算符,用于将数组或其他可迭代对象展开成单个元素,并作为独立的参数传递给 push,最终将这些元素添加到 list 的末尾
    console.log(list)
  },2000)
}
//第三种方法,将数组转化为对象(添加一个对象,将数组作为属性), 然后就可以将 list_1.arr = res 赋值了。视图中也需要修改为list_1.arr
const list_1 = reactive<{arr:string[]}>({arr:[]})
</script>

Visual Studio Code小技巧, 输入vue3回车自动会出现下面的模版。
在这里插入图片描述
在这里插入图片描述
打开文件以后,输入下面内容。

{
	"Print to console": {
	 	"prefix": "vue3",
	 	"body": [
	 		"<template>",
			"    <div></div>",
			"</template>",
			"<script setup lang='ts'>",
			"import { ref,reactive } from 'vue'",
			"",
			"</script>",

			"<style scoped>",
			"",
			"</style>",
	 	],
	 	"description": "Log output to console"
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2142701.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Get包中的根组件

文章目录 1. 知识回顾2. 使用方法2.1 源码分析2.2 常用属性 3. 示例代码4. 内容总结 我们在上一章回中介绍了"Get包简介"相关的内容&#xff0c;本章回中将介绍GetMaterialApp组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 知识回顾 我们在上一章回中已经…

Unity webgl跨域问题 unity使用nginx设置跨域 ,修改请求头

跨域 什么是跨域 跨域是指浏览器因安全策略限制&#xff0c;阻止一个域下的网页访问另一个域下的资源。 一些常见的跨域情况&#xff1a; 协议不同 从 http://example.com 请求 https://example.com。域名不同 从 http://example.com 请求 http://anotherdomain.com。端口不…

Village Exteriors Kit 中世纪乡村房屋场景模型

此模块化工具包就是你一直在寻找的适合建造所有中世纪幻想村庄和城市建筑所需要的工具包。 皇家园区 - 村庄外饰套件的模型和纹理插件资源包 酒馆和客栈、魔法商店、市政大厅、公会大厅、布莱克史密斯锻造厂、百货商店、珠宝商店、药店、草药师、银行、铠甲、弗莱切、马厩、桌…

list从0到1的突破

目录 前言 1.list的介绍 2.list的常见接口 2.1 构造函数&#xff08; (constructor)&#xff09; 接口说明 2.2 list iterator 的使用 2.3 list capacity 2.4 list element access 2.5 list modifiers 3.list的迭代器失效 附整套练习源码 结束语 前言 前面我们学习…

Defining Constraints with ObjectProperties

步骤4&#xff1a;使用对象定义约束 物业 您可以创建时间和放置约束&#xff0c;如本教程所示。你也可以 更改单元格的属性以控制Vivado实现如何处理它们。许多 物理约束被定义为单元对象的属性。 例如&#xff0c;如果您在设计中发现RAM存在时序问题&#xff0c;为了避免重新合…

C语言代码练习(第二十六天)

今日练习&#xff1a; 数据的交换输出输入 n 个数&#xff0c;找出其中最小的数&#xff0c;将它与最前面的数交换后输出这些数 输入一个英文句子&#xff0c;将每个单词的第一个字母改成大写字母 输入一个十进制数 N &#xff0c;将它转换成 R 进制数输出 数据的交换输出输入 …

阿里OSS对象存储服务,实现图片上传回显

阿里OSS对象存储服务 OSS服务1. 创建buckte2. 获取accesskey3. 参照官方SDK编写程序安装SDK 4. 程序编写5. 封装6. 在spring中调用 OSS服务 阿里云对象存储 OSS&#xff08;Object Storage Service&#xff09;是一款海量、安全、低成本、高可靠的云存储服务&#xff0c;提供最…

利用JS数组根据数据生成柱形图

要求 <html> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document…

精准识别,高效管理:工服识别AI检测算法在多场景中的应用优势

随着人工智能技术的快速发展&#xff0c;其在各个行业的应用也日益广泛。特别是在工业生产和安全监管领域&#xff0c;工服识别AI检测算法凭借其高效、精准的特点&#xff0c;成为提升生产效率、保障工作人员安全的重要手段。本文将详细介绍TSINGSEE青犀AI智能分析网关V4工服识…

Hibernate基础

Hibernate基础总结 有利的条件和主动的恢复产生于再坚持一下的努力之中&#xff01; 好久没更新了&#xff0c;今天入门了Hibernate&#xff0c;由于之前学习了MyBatis&#xff0c;初步感觉二者的底层实现思想有很多相似之处&#xff0c;下面让我们以一个入门Demo的形式感受一…

3.Java高级编程实用类介绍(一)

三、Java高级编程实用类介绍(一) 文章目录 三、Java高级编程实用类介绍(一)一、枚举类型二、包装类三、Math 一、枚举类型 使用enum进行定义 public enum 枚举名字{值1,值2.... }二、包装类 每个基本类型在java.lang包中都有一个相应的包装类 /** new包装类&#xff08;字符…

【C++笔记】类和对象的深入理解(三)

【C笔记】类和对象的深入理解(三) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】类和对象的深入理解(三)前言一.日期类的实现1.1声明和定义分离1.2日期类整数1.3日期类整数1.4日期类-整数1.5日期类-日期1.6复用对…

并发安全与锁

总述 这篇文章&#xff0c;我想谈一谈自己对于并发变成的理解与学习。主要涉及以下三个部分&#xff1a;goroutine&#xff0c;channel以及lock 临界区 首先&#xff0c;要明确下面两组概念 并发和并行 并行&#xff1a;指几个程序每时每刻都同时进行 并发&#xff1a;指…

lnmp - 登录技术方案设计与实现

概述 登录功能是对于每个动态系统来说都是非常基础的功能&#xff0c;用以区别用户身份、和对应的权限和信息&#xff0c;设计出一套安全的登录方案尤为重要&#xff0c;接下来我介绍一下常见的认证机制的登录设计方案。 方案设计 HTTP 是一种无状态的协议&#xff0c;客户端…

iOS - TestFlight使用

做的项目需要给外部人员演示&#xff0c;但是不方便获取对方设备的UDID&#xff0c;于是采用TestFlight 的方式邀请外部测试人员的方式给对方安装测试App&#xff0c;如果方便获取对方设备的UDID&#xff0c;可以使用蒲公英 1.在Xcode中Archive完成后上传App Store Connect之前…

浙大上交联合阿里腾讯,共同构建医学AI领域的顶尖科研+商业团队|个人观点·24-09-17

小罗碎碎念 昨晚锻炼时&#xff0c;我想着是时候对推文的内容做一些改进了——既能通过写推文来锻炼自己写paper的能力&#xff0c;也希望凭借自己一点微弱的影响力&#xff0c;去带动更多的人加入医学AI的队伍中。 这一期推文系统且深度的分析一下&#xff0c;国内哪些学者在医…

Linux基础开发环境(git的使用)

1.账号注册 git 只是一个工具&#xff0c;要想实现便捷的代码管理&#xff0c;就需要借助第三方平台进行操作&#xff0c;当然第三平台也是基于git 开发的 github 与 gitee 代码托管平台有很多&#xff0c;这里我们首选 Github &#xff0c;理由很简单&#xff0c;全球开发者…

算法题之回文子串

回文子串 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 示例 1&#xff1a; 输入&#xff1a;s "abc" 输出&#xff1a;3 解释…

C++ 带约束的Ceres形状拟合

C 带约束的Ceres形状拟合 一、Ceres Solver1.定义问题2. 添加残差AddResidualBlockAutoDiffCostFunction 3. 配置求解器4. 求解5. 检查结果 二、基于Ceres的最佳拟合残差结构体拟合主函数 三、带约束的Ceres拟合残差设计拟合区间限定 四、拟合结果bestminmax 五、完整代码 对Ce…

RocksDB系列一:基本概念

0 引言 RocksDB 是 Facebook 基于 Google 的 LevelDB 代码库于 2012 年创建的高性能持久化键值存储引擎。它针对 SSD 的特定特性进行了优化&#xff0c;目标是大规模&#xff08;分布式&#xff09;应用&#xff0c;并被设计为嵌入在更高层次应用中的库组件。RocksDB应用范围很…