ref用于对元素的标记,通过ref可以获取到对应元素上的属性和方法。
一、访问模板引用
在Vue3中为了通过组合式 API 获得该模板引用,我们需要声明一个同名的 ref。
<template><div><div ref="element">{{ item }}</div></div>
</template><script setup>
import { ref } from 'vue';
const element=ref(null)
console.log(element);
const item = ref("我是一个元素");
</script><style>
</style>
注意,你只可以在组件挂载后才能访问模板引用。如果你想在模板中的表达式上访问 input
,在初次渲染时会是 null
。这是因为在初次渲染前这个元素还不存在呢!
如果你需要侦听一个模板引用 ref 的变化,确保考虑到其值为 null
的情况:
<template><div><div ref="element">{{ item }}</div></div>
</template><script setup>
import { ref , watchEffect} from 'vue';
const element=ref(null)
const item = ref("我是一个元素");
watchEffect(()=>{if(element.value){console.log(element);}else{console.log('未加载');}
})
</script><style>
</style>
二、v-for中的模板引用
当在 v-for
中使用模板引用时,对应的 ref 中包含的值是一个数组,它将在元素被挂载后包含对应整个列表的所有元素,需要注意的是,ref 数组并不保证与源数组相同的顺序。
<template><div><div v-for="(item,index) in 10" :key="index" ref="element">{{ item }}</div></div>
</template><script setup>
import { ref , watchEffect} from 'vue';
const element=ref([])
const item = ref("我是一个元素");
watchEffect(()=>{if(element.value){console.log(element);}else{console.log('未加载');}
})
</script><style>
</style>
三、组件上的ref
如果一个子组件使用的是选项式 API 或没有使用 <script setup>
,被引用的组件实例和该子组件的 this
完全一致,这意味着父组件对子组件的每一个属性和方法都有完全的访问权。这使得在父组件和子组件之间创建紧密耦合的实现细节变得很容易,当然也因此,应该只在绝对需要时才使用组件引用。大多数情况下,你应该首先使用标准的 props 和 emit 接口来实现父子组件交互。
子组件:
<template><div>{{ data }}</div>
</template><script>
export default {
data(){return{data:'我是子元素'}
}
}
</script><style></style>
父组件:
<template><div><Child ref="child"></Child></div>
</template><script setup>
import Child from "@/components/child.vue"
import { ref, watch ,watchEffect} from "vue"
const child=ref(null)
watchEffect(()=>{if(child.value){console.log(child.value.data);}
})</script><style></style>
有一个例外的情况,使用了 <script setup>
的组件是默认私有的:一个父组件无法访问到一个使用了 <script setup>
的子组件中的任何东西,除非子组件在其中通过 defineExpose
宏显式暴露:
子组件:
<template><div>{{ data }}</div>
</template><script setup>
import { ref } from "vue";const data = ref('我是子元素')
defineExpose({data
})
</script><style></style>
父组件:
<template><div><Child ref="child"></Child></div>
</template><script setup>
import Child from "@/components/child.vue"
import { ref, watch ,watchEffect} from "vue"
const child=ref(null)
watchEffect(()=>{if(child.value){console.log(child.value.data);}
})</script><style></style>