reactive
:
当使用reactive()
处理数据后,数据再次被使用
时,就会进行依赖收集
当数据发生改变
时,所有收集到的依赖
进行对应的响应式操作(如:更新界面),
事实上,我们编写的data选项
也是在内部交给了reactive()
将其变成响应式对象的
ref
:
在template中使用ref的变量
时,vue内部会自动帮我们进行解包(取出其中的.value),
所以并不需要通过变量.value
是方式来使用,
但是,在setup()中
还是需要用变量.value
的方法使用
官方说,template中的解包,是浅层的解包,如果将ref放到reactive中,那么在模板中使用时,它会自动解包
<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对象
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
例子:const nameRef = ref('White')unref(nameRef) = nameRef.valueunref('Black') = 'Black'总结:当你不确定一个变量是不是ref的时候,可以利用`unref()`
使用 ref 获取组件、DOM元素
方法:定义一个Ref对象,将其绑定到组件、DOM元素的ref属性上即可
<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组件
<script setup>function showInfoFn(){clog('我是ShowInfo组件的showInfoFn方法')}# 必须 `defineExpose()` 将函数、变量暴露出去,父组件才能通过`ref.showInfo.value.xxxxxx`调用子组件ShowInfo中的函数、变量defineExpose({showInfoFn})
</script>
<template><h2> showInfo组件 </h2>
</template>
<script setup>import { ref, reactive } from 'vueimport 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组件
<script setup>import { ref, defineProps, defineEmits, defineExpose } from 'vueconst 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>