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>