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>
相关推荐
Devil枫4 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
毕业设计制作和分享6 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
程序媛小果6 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
从兄6 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
凉辰7 小时前
设计模式 策略模式 场景Vue (技术提升)
vue.js·设计模式·策略模式
薛一半9 小时前
PC端查看历史消息,鼠标向上滚动加载数据时页面停留在上次查看的位置
前端·javascript·vue.js
MarcoPage9 小时前
第十九课 Vue组件中的方法
前端·javascript·vue.js
工业互联网专业9 小时前
Python毕业设计选题:基于Hadoop的租房数据分析系统的设计与实现
vue.js·hadoop·python·flask·毕业设计·源码·课程设计
你好龙卷风!!!9 小时前
vue3 怎么判断数据列是否包某一列名
前端·javascript·vue.js