前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单说一下vue3中的那些晦涩难懂的概念(ref、reactive、unref、isRef、toRef、toRefs、shallowRef、triggerRef、custormRef)

简单说一下vue3中的那些晦涩难懂的概念(ref、reactive、unref、isRef、toRef、toRefs、shallowRef、triggerRef、custormRef)

作者头像
何处锦绣不灰堆
发布2023-12-13 14:48:00
1810
发布2023-12-13 14:48:00
举报
文章被收录于专栏:农历七月廿一农历七月廿一
写在前面

vue3中很多实现响应式的方式,我们比较常用的有一些ref reactive等操作,但是其实文档本身是帮我们实现了不止这些,他有帮我们考虑了很多种不同的业务场景,今天就简单的介绍一下

  • ref
代码语言:javascript
复制
<!--
  * @Description: 测试ref unref isRef toRef toRefs shallowRef triggerRef customRef
  * @author:clearlove
  * @createTime: 2023-12-11 14:02:55
  -->
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
	当前 count	{{count}}
	</div>
</template>

<script setup>
	import {ref} from 'vue'
	const count = ref(0)
	const addCount = ()=>{
		count.value++
	}
</script>
  • unref
代码语言:javascript
复制
他本身是一个语法糖:val = isRef(val) ? val.value : val; 
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
	当前 count	{{unRefCount}}
	</div>
</template>

<script setup>
import {ref,unref} from 'vue'
	const count = ref(0)
	const unRefCount = unref(count)
	const addCount = ()=>{
		count.value++
		console.log(count.value,unRefCount)
	}
</script>

在这里插入图片描述
在这里插入图片描述
  • isRef
代码语言:javascript
复制
    import {ref,unref,isRef} from 'vue'
	const count = ref(0)
	const unRefCount = unref(count)
	const ordinaryCount = 0
	console.log(isRef(count),isRef(unRefCount),isRef(ordinaryCount)) // true  false  false
  • reactive
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
	当前 count	{{countObject.num}}
	</div>
</template>

<script setup>
  import {reactive} from 'vue'
	const countObject = reactive({
		num : 0
	})
	const addCount = ()=>{
		countObject.num++
	}
</script>
  • toRef
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
		当前 count {{toRefCount}}
		<hr />
		原对象的 num {{count.num}}
	</div>
</template>

<script setup>
	import { toRef, ref } from 'vue'
	const count = ref({
		num: 0
	})
	const toRefCount = toRef(count.value, 'num')
	/**
	 toRef可以改变一个原对象中的某一个属性,toRef 接受两个参数,第一个是对象,第二个是属性值,
	 这个属性值就和当前的定义的变量保持同步,当然这里使用 reactive 也是可以的
	 */
	const addCount = () => {
		// 以下两个值,任意改变都会印象另一个对应的属性
		count.value.num++
		// toRefCount.value++
	}
</script>

在这里插入图片描述
在这里插入图片描述
  • toRefs
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
		当前 count {{toRefCount.num}}
		<hr />
		原对象的 num {{count.num}}
	</div>
</template>

<script setup>
	import { toRefs, reactive } from 'vue'
	const count = reactive({
		num: 0,
		age: 0
	})
	const toRefCount = toRefs(count)
	
	/**
	 * toRefs 之后会将count 转为普通对象,toRefCount 具备了 count 对象的属性,
	   且里面的属性均为 ref 响应式对象 
	   toRefCount 的 num / age  和 count
     里面的	num / age 保持同步
		 不管改哪里的数据,两边均保持同步
	 */ 
	const addCount = () => {
		count.num++
		// toRefCount.num.value++
	}
</script>

toRefs应用

代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
		当前 num {{num}}
		<hr />
		原对象的 num {{count.num}}
	</div>
</template>

<script setup>
	import { reactive,toRefs } from 'vue'
	const count = reactive({
		num: 0,
		age: 0
	})
	// const { num, age } = count // 这里解构之后 num 和 age 均失去了响应式
	const toRefCount = toRefs(count)
	const { num } = toRefCount // 这里解构之后 均还存在 ref 的响应式,因为 toRefs 之后给内部的属性均添加了响应式
	const addCount = () => {
		count.num++
	}
</script>
// 当然这里有点冗余了,你可以直接使用对象[key]的方式进行获取数据,也是可以保留响应式进行展示的
  • shallowRef
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
		<el-button @click="addCountValue">改变 value</el-button>
	</div>
	<br />
	<div>
		当前 num {{count.num}}
	</div>
</template>

<script setup>
	import { shallowRef } from 'vue'
	/**
	  shallowRef 仅仅对当前的 value 改变可以进行监听响应式,深层的是不具备响应式的
	 */
	const count = shallowRef({
		num: 0,
	})
	
	// 这里无法实现动态的 num
	const addCount = () => {
		count.value.num++ 
	}
	// 这里可以改变动态 num
	const addCountValue = ()=>{
		let temp = count.value.num
		temp++
		count.value = {
			num : temp
		}
	}
</script>

  • triggerRef
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
		<el-button @click="addCountValue">改变 value</el-button>
	</div>
	<br />
	<div>
		当前 num {{count.num}}
	</div>
</template>

<script setup>
	import { shallowRef,triggerRef } from 'vue'
	/**
	  triggerRef  可以对shallowRef 浅层不具备更新的属性进行强制更新
	 */
	const count = shallowRef({
		num: 0,
	})
	
	// 这里添加shallowRef 之后可以实现动态的 num
	const addCount = () => {
		count.value.num++ 
		triggerRef(count)
	}
</script>
  • custormRef
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
		当前 num {{num}}
	</div>
</template>

<script setup>
	import { customRef } from 'vue'
	/**
	  customRef 可以自定义一个 ref 的功能函数, 它可以实现的自定义一个条件判断进行区分哪里是需要进行响应式的
	 */
	const diyRef = ((value) => {
		return customRef((track, trigger) => {
			return {
				get() {
					track()
					return value
				},
				set(newValue) {
					setTimeout(()=>{
						value = newValue
						trigger()
					},2000)
				}
			}
		})
	})
	const num = diyRef(0)
	const addCount = () => {
		num.value++
	}
</script>
  • shallowReactive
代码语言:javascript
复制
<template>
	<div>
		<el-button @click="addCount">count++</el-button>
	</div>
	<br />
	<div>
		当前 num {{obj.age}} - {{obj.grade.english}}
	</div>
</template>

<script setup>
	import { shallowReactive } from 'vue'
	/**
	  shallowReactive 只有根节点是响应式的,内部深层的是不具备响应式的
	 */
	const obj = shallowReactive({
		age: 0, 
		grade: {
			english: 90
		}
	})

	const addCount = () => {
		// 这里有个很奇怪的点  如果两个同时写上的话,两个都是具备响应式的  如果只有obj.grade.english++ 是不具备的 不晓得是不是一个 bug  按照官方的解释,这里是不会进行响应式进行页面更新的
		obj.grade.english++
		obj.age++
	}
</script>

写在最后

这篇文章也许不会帮你全完全了解这些概念,但是学习的过程就是你要先知道,然后再追求精通,所以我的目的是希望通过这篇文章可以对这些概念有一个简单的认识,具体他是做什么的,哪里可以用到,要看你们实际业务场景是不是需要对应的一些概念,喜欢的可以收藏一下,拜拜

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 写在前面
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档