Vue-ref與props的使用詳解
一、props:父組件向子組件傳遞數(shù)據(jù)
props 是單向數(shù)據(jù)流的核心,用于父組件向子組件傳遞數(shù)據(jù)。
1. 基本用法(Vue 3 +<script setup>)
子組件(ChildComponent.vue)
<script setup>
// 定義接收的 props
defineProps({
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
}
})
</script>
<template>
<div class="child">
<h3>{{ title }}</h3>
<p>當前計數(shù):{{ count }}</p>
</div>
</template>父組件(ParentComponent.vue)
<script setup>
import ChildComponent from './ChildComponent.vue'
const parentTitle = '來自父組件的數(shù)據(jù)'
const parentCount = 5
</script>
<template>
<div>
<h1>父組件</h1>
<ChildComponent
:title="parentTitle"
:count="parentCount"
/>
</div>
</template>? 數(shù)據(jù)從父 → 子,單向流動。
2.props的特點
| 特性 | 說明 |
|---|---|
| ? 響應式 | 父組件數(shù)據(jù)變化,子組件自動更新 |
| ? 不可直接修改 | 子組件不能修改 props(會報警告) |
| ? 類型校驗 | 支持 type、required、default |
| ? 默認值 | 可設置 default 值 |
錯誤示例:子組件修改 props
// ? 錯誤!不要這樣做 props.count++ // 警告:Avoid mutating a prop directly
? 正確做法:通過事件通知父組件修改
<!-- 子組件 -->
<script setup>
const emit = defineEmits(['update-count'])
const increment = () => {
emit('update-count', props.count + 1)
}
</script>
<template>
<button @click="increment">+1</button>
</template><!-- 父組件 --> <ChildComponent :count="count" @update-count="count = $event" />
? 實現(xiàn)“子組件通知父組件更新數(shù)據(jù)”。
二、ref:獲取 DOM 元素或子組件實例
ref 是一個響應式引用,可用于:
- 模板中:獲取 DOM 元素
- 組件中:獲取子組件實例
- 變量:創(chuàng)建響應式數(shù)據(jù)(Vue 3)
1. 獲取 DOM 元素
<script setup>
import { ref, onMounted } from 'vue'
// 創(chuàng)建 ref
const inputRef = ref(null)
onMounted(() => {
// DOM 渲染完成后,inputRef.value 指向真實 DOM
inputRef.value.focus() // 自動聚焦
})
</script>
<template>
<input ref="inputRef" type="text" placeholder="自動聚焦輸入框" />
</template>? ref 在模板中通過字符串名綁定,在 JS 中通過變量訪問。
2. 獲取子組件實例
子組件(Modal.vue)
<script setup>
import { ref } from 'vue'
const isVisible = ref(false)
// 提供方法給父組件調用
function open() {
isVisible.value = true
}
function close() {
isVisible.value = false
}
// 暴露給父組件
defineExpose({
open,
close
})
</script>
<template>
<div v-if="isVisible" class="modal">
<p>這是一個模態(tài)框</p>
<button @click="close">關閉</button>
</div>
</template>父組件(Parent.vue)
<script setup>
import { ref } from 'vue'
import Modal from './Modal.vue'
const modalRef = ref(null)
const openModal = () => {
modalRef.value.open() // 調用子組件方法
}
</script>
<template>
<div>
<button @click="openModal">打開模態(tài)框</button>
<Modal ref="modalRef" />
</div>
</template>? 通過 defineExpose 暴露方法,父組件通過 ref 調用。
3.ref創(chuàng)建響應式數(shù)據(jù)(Vue 3)
<script setup>
import { ref } from 'vue'
const count = ref(0) // ref 包裝基本類型
const increment = () => {
count.value++ // 注意:需要 .value
}
</script>
<template>
<p>計數(shù):{{ count }}</p>
<button @click="increment">+1</button>
</template>? ref 是 Vue 3 響應式系統(tǒng)的基礎之一(與 reactive 并列)。
三、ref與props的對比
| 維度 | props | ref |
|---|---|---|
| 作用 | 父 → 子 傳遞數(shù)據(jù) | 獲取 DOM / 組件實例 / 創(chuàng)建響應式變量 |
| 方向 | 自上而下(單向) | 自下而上(調用子組件)或內部使用 |
| 響應式 | 是(父變子變) | 是(ref 變量本身是響應式) |
| 可修改性 | 子組件不能直接修改 | 可以修改(如 count.value++) |
| 使用場景 | 數(shù)據(jù)傳遞 | DOM 操作、方法調用、響應式變量 |
| Vue 2 寫法 | this.$refs.xxx | this.$refs.xxx |
| Vue 3 寫法 | defineProps() | ref() + 模板綁定 |
一句話總結:
props 用于“傳數(shù)據(jù)”,ref 用于“拿實例”或“做響應式變量”。
四、Vue 2 vs Vue 3 差異
Vue 2 寫法
// 子組件
export default {
props: ['title'],
mounted() {
this.$refs.input.focus()
}
}
// 父組件
export default {
methods: {
callChild() {
this.$refs.childModal.open()
}
}
}Vue 3<script setup>寫法
<script setup> // 使用 defineProps 和 ref const props = defineProps(['title']) const inputRef = ref(null) </script>
? Vue 3 更簡潔,但需注意 ref 在 setup 中的 .value 問題。
五、常見誤區(qū)與最佳實踐
? 誤區(qū) 1:在setup中直接使用ref變量不加.value
// ? 錯誤
const count = ref(0)
console.log(count) // RefImpl { value: 0 }
// ? 正確
console.log(count.value) // 0? 誤區(qū) 2:子組件直接修改props
// ? 錯誤
props.count++
// ? 正確:通過事件通知父組件
emit('update:count', props.count + 1)? 最佳實踐
props只用于傳遞數(shù)據(jù),不用于方法調用ref用于需要直接操作的場景(如聚焦、動畫、第三方庫集成)- 避免過度使用
ref調用子組件方法,優(yōu)先使用emit事件通信 - 復雜狀態(tài)管理使用
Pinia或Vuex,而非層層props傳遞
六、總結
| API | 核心用途 | 是否響應式 | 是否可修改 | 推薦場景 |
|---|---|---|---|---|
| props | 父 → 子 傳數(shù)據(jù) | ? | ?(子不能改) | 配置項、展示數(shù)據(jù) |
| ref | 獲取實例 / 響應式變量 | ? | ? | DOM 操作、方法調用、局部狀態(tài) |
通信原則:
- 數(shù)據(jù)流:
props向下,emit向上 - 實例調用:
ref獲取子組件,謹慎使用 - 響應式:
ref和reactive是 Vue 3 的基石
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vue elementUi+sortable.js實現(xiàn)嵌套表格拖拽問題
這篇文章主要介紹了vue elementUi+sortable.js實現(xiàn)嵌套表格拖拽問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
在導入.vue文件的時候,ts報錯提示:找不到模塊“@/Layout/index.vue”或其相應的類型聲明問題
這篇文章主要介紹了在導入.vue文件的時候,ts報錯提示:找不到模塊“@/Layout/index.vue”或其相應的類型聲明問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08
Vue使用vue-area-linkage實現(xiàn)地址三級聯(lián)動效果的示例
很多時候我們需要使用地址三級聯(lián)動,即省市區(qū)三級聯(lián)動,這篇文章主要介紹了Vue使用vue-area-linkage實現(xiàn)地址三級聯(lián)動效果的示例,感興趣的小伙伴們可以參考一下2018-06-06

