在 Vue 中,ref 是一个非常重要的 API,用于获取 DOM 元素或组件实例的引用,并在 Vue 3 中引申为响应式数据的创建方式。
🔰Vue 中 ref 的基础用法
✅ 用于 DOM 引用(Vue 2 & 3 都支持)
<template>
<input ref="myInput" />
</template>
<script>
export default {
mounted() {
this.$refs.myInput.focus();
}
}
</script>
- 在 Vue 2 和 Vue 3 中都可以通过 this.$refs.myInput 访问对应 DOM 元素或组件实例。
✅ 在 Vue 3 中用于响应式数据(Composition API)
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
- ref(0) 创建一个响应式的变量。
- 使用 .value 访问或修改其值。
- Vue 会自动跟踪 .value 的变化并响应更新视图。
🎯 Vue 3 中响应式的两种方式对比
import { ref, reactive } from 'vue'
const count = ref(0)
const state = reactive({
name: 'Alice',
age: 25
})
场景 推荐 |
API |
基础类型数字、字符串等) |
ref() |
对象、数组、嵌套结构 |
reactive() |
⚙️ 使用 ref 的常见场景(Vue 3)
- 操作 DOM(如 focus、scroll)
- 获取组件实例的方法(如手动触发方法)
- 创建响应式的局部状态(尤其在组合式函数中)
- 与 watch 或 watchEffect 配合使用
vue2 和vue3的对比
🧩 创建和使用 ref
✅ Vue 2 - 仅用于 DOM/组件引用
<template>
<input ref="myInput" />
</template>
<script>
export default {
mounted() {
this.$refs.myInput.focus()
}
}
</script>
- ❌ 没有 ref() 响应式 API
- this.$refs.myInput 获取 DOM 或子组件实例
✅ Vue 3 - DOM + 响应式变量(Composition API)
<template>
<input ref="myInput" />
</template>
<script setup>
import { ref, onMounted } from 'vue'
const myInput = ref(null)
onMounted(() => {
myInput.value.focus()
})
</script>
- ref(null) 可用于 DOM,也可用于响应式数据
- .value 是关键:访问响应式内容或 DOM 节点
📦 响应式数据对比
✅ Vue 2 - 使用 data(Options API)
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
- 响应式由 Vue 自动处理,不能在 data 外创建变量响应式化
✅ Vue 3 - 使用 ref()(Composition API)
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
- 可在任意作用域中定义响应式变量(组合式函数)
- value 访问响应式数据
🧩 组件引用对比
✅ Vue 2
<child-component ref="child" />
this.$refs.child.someMethod()
✅ Vue 3
<child-component ref="childRef" />
const childRef = ref(null)
onMounted(() => {
childRef.value.someMethod()
})
📌 生命周期中访问 ref
生命周期 |
Vue 2 |
Vue 3 |
访问时机 |
mounted() |
onMounted() |
DOM 可用 |
this.$refs.xxx |
ref.value |
使用方式 |
Options API |
推荐使用 |
✅ 完整对照示例
🔹Vue 2 示例(Options API)
<template>
<div>
<input ref="inputEl" />
<p>{{ count }}</p>
<button @click="increment">+</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
mounted() {
this.$refs.inputEl.focus()
},
methods: {
increment() {
this.count++
}
}
}
</script>
🔹Vue 3 示例(Composition API)
<template>
<div>
<input ref="inputEl" />
<p>{{ count }}</p>
<button @click="increment">+</button>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const count = ref(0)
const inputEl = ref(null)
const increment = () => count.value++
onMounted(() => {
inputEl.value.focus()
})
</script>
✅ 总结对比表
功能 |
Vue 2 |
Vue 3 |
DOM/组件引用 |
ref=“xxx” + $refs.xxx |
ref() + .value |
响应式数据 |
data() 返回对象 |
ref() / reactive() |
生命周期访问 |
mounted() |
onMounted() |
类型支持 |
弱,难配合 TS |
强,适合 TS/组合式函数 |
编程风格 |
Options API |
Composition API(推荐) |