vue3 中的ref、reactive的介绍

reactive

当使用reactive()处理数据后,数据再次被使用时,就会进行依赖收集
当数据发生改变时,所有收集到的依赖进行对应的响应式操作(如:更新界面),

事实上,我们编写的data选项也是在内部交给了reactive()将其变成响应式对象的


ref

在template中使用ref的变量时,vue内部会自动帮我们进行解包(取出其中的.value),

所以并不需要通过变量.value是方式来使用,

但是,在setup()中还是需要用变量.value的方法使用


官方说,template中的解包,是浅层的解包,如果将ref放到reactive中,那么在模板中使用时,它会自动解包
javascript 复制代码
<script setup>
	let count = ref(0)

	let info = reactive({
		count
	})
</script>

<template>
	<!-- 使用时,不需要写`.value` -->
	<h2>{{ info.count }}</h2>

	<!-- 这样是不行的!!! -->
	<btn @click="info.count++"> +1 </btn>


	<!-- 修改的时候,要加上`.value` -->
	<btn @click="info.count.value++"> +1 </btn>
</template>



其他的ref

isRef()

判断是否是一个ref对象


shallowRef()

创建一个浅层(也就是一层)的ref对象

javascript 复制代码
const info = ref({ name: 'White' })
info.value = { age: 18 } // 直接修改了这个对象,info还是响应式的
info.value.name = 'Black' // 修改了对象的name属性,info还是响应式的

const info = shallowRef({ name: 'White' })
info.value = { age: 18 } // 直接修改的`info.value`,info还是响应式的
info.value.name = 'Black' // 这里不是直接修改的`info.value`,而是修改的`info.value.name`,info就不是响应式了

	那么,如果还想把info变成响应式的怎么办呢???
	用`triggerRef(变量名)`,这样`triggerRef(info)`后,info就又变成响应式的了

那么,如果还想把info变成响应式的怎么办呢???

triggerRef(变量名),这样triggerRef(info)后,info就又变成响应式的了


unref()

如果我们想要获取一个ref引用中的value,那么就可以通过unref()实现

复制代码
实质:如果`变量target`是一个ref,则返回`target.value`,否则返回`变量target本身`
	  即:target = isRef(target) ? target.value : target
javascript 复制代码
例子:
	const nameRef = ref('White')
	unref(nameRef) = nameRef.value
	unref('Black') = 'Black'
	总结:当你不确定一个变量是不是ref的时候,可以利用`unref()`



使用 ref 获取组件、DOM元素

方法:定义一个Ref对象,将其绑定到组件、DOM元素的ref属性上即可

javascript 复制代码
<script setup>
	import { ref, onMounted }   from 'vue'
	import ShowInfo from './ShowInfo.vue'

	const titleRef = ref()
	const showInfoRef = ref()

	// 在 onMounted() 中获取Ref元素
	onMounted(){
		clog('titleRef=', titleRef)
		clog('showInfoRef=', showInfoRef)
		showInfoRef.value.showInfoFn() // 调用 ShowInfo组件中的方法
	}
</script>

<template>
	<h2 ref="titleRef"> 标题 </h2>
	<show-info ref="showInfoRef"> ShowInfo组件 </show-info>
</template>

ShowInfo组件

javascript 复制代码
<script setup>
	function showInfoFn(){
		clog('我是ShowInfo组件的showInfoFn方法')
	}
	
	# 必须 `defineExpose()` 将函数、变量暴露出去,父组件才能通过`ref.showInfo.value.xxxxxx`调用子组件ShowInfo中的函数、变量
	defineExpose({
		showInfoFn
	})
</script>
<template>
	<h2> showInfo组件 </h2>
</template>



javascript 复制代码
<script setup>
	import { ref, reactive  } from 'vue
	import ShowInfo from './showInfo.vue'

	let name = ref('赵思')
	let age = ref(12)
	let info = reactive({
		address: '苏州', type: '伊人'
	})

	// 接受 ShowInfo 组件 发射过来的事件
	function infoBtnClick(payload){
		clog("监听到,showInfo组件发射过来的事件", payload)
	}
</script>

<template>
	<h2> 标题 </h2>
	<show-info :name="name" :age="age" :info="info" @infoBtnClick="infoBtnClick"> ShowInfo组件 </show-info>
</template>

ShowInfo组件

javascript 复制代码
<script setup>
	import { ref, defineProps, defineEmits, defineExpose } from 'vue
	const props = defineProps({
		name: {
			type: String, default: '默认值'
		},
		age: {
			type: Number, default: 123
		},
		info: {
			type: Object, defautl: ()=>{}
		}
	})

	// 向 父组件 发射事件
	const emit = defineEmits(["infoBtnClick"])
	function btnClick(){
		emit("infoBtnClick", "showInfo内部发生了点击")
	}

	function showInfoFn(){
		clog("我是 ShowInfo组件 中的方法")
	}

	defineExpose({
		showInfoFn
	})
</script>

<template>
	<h2> {{ name }} - {{ age }} </h2>
	<button @click="btnClick"></button>
</template>
相关推荐
猩兵哥哥2 小时前
前端面向对象设计原则运用 - 策略模式
前端·javascript·vue.js
EMT3 小时前
在 Vue 项目中使用 URL Query 保存和恢复搜索条件
javascript·vue.js
我是日安3 小时前
从零到一打造 Vue3 响应式系统 Day 9 - Effect:调度器实现与应用
前端·vue.js
鹏多多4 小时前
深入解析vue的keep-alive缓存机制
前端·javascript·vue.js
用户516816614584120 小时前
Vue Router 路由懒加载引发的生产页面白屏问题
vue.js·vue-router
前端缘梦20 小时前
Vue Keep-Alive 组件详解:优化性能与保留组件状态的终极指南
前端·vue.js·面试
Simon_He20 小时前
这次来点狠的:用 Vue 3 把 AI 的“碎片 Markdown”渲染得又快又稳(Monaco 实时更新 + Mermaid 渐进绘图)
前端·vue.js·markdown
王同学QaQ1 天前
Vue3对接UE,通过MQTT完成通讯
javascript·vue.js
华仔啊1 天前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端
艾小码1 天前
告别Vue混入的坑!Composition API让我效率翻倍的3个秘密
前端·javascript·vue.js