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>
相关推荐
GHUIJS5 分钟前
【vue3】vue3.5
前端·javascript·vue.js
计算机学姐1 小时前
基于python+django+vue的家居全屋定制系统
开发语言·vue.js·后端·python·django·numpy·web3.py
Ripple1111 小时前
Vue源码速读 | 第二章:深入理解Vue虚拟DOM:从vnode创建到渲染
vue.js
秋沐1 小时前
vue中的slot插槽,彻底搞懂及使用
前端·javascript·vue.js
QGC二次开发1 小时前
Vue3 : Pinia的性质与作用
前端·javascript·vue.js·typescript·前端框架·vue
想退休的搬砖人3 小时前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js
啥子花道3 小时前
Vue3.4 中 v-model 双向数据绑定新玩法详解
前端·javascript·vue.js
清灵xmf3 小时前
揭开 Vue 3 中大量使用 ref 的隐藏危机
前端·javascript·vue.js·ref
学习路上的小刘4 小时前
vue h5 蓝牙连接 webBluetooth API
前端·javascript·vue.js
&白帝&4 小时前
vue3常用的组件间通信
前端·javascript·vue.js