vue中props值的傳遞詳解
前言
如果我們正在構(gòu)建一個博客,我們可能需要一個表示博客文章的組件。我們希望所有的博客文章分享相同的視覺布局,但有不同的內(nèi)容。要實現(xiàn)這樣的效果自然必須向組件中傳遞數(shù)據(jù),例如每篇文章標題和內(nèi)容,這就會使用到 props。
prop值的傳遞
Props 是一種特別的 attributes,你可以在組件上聲明注冊。要傳遞給博客文章組件一個標題,我們必須在組件的 props 列表上聲明它。這里要用到defineProps宏:
<!-- BlogPost.vue -->
<script setup>
defineProps(['title'])
</script>
<template>
<h4>{{ title }}</h4>
</template>defineProps是一個僅<script setup>中可用的編譯宏命令,并不需要顯式地導(dǎo)入。聲明的 props 會自動暴露給模板。defineProps會返回一個對象,其中包含了可以傳遞給組件的所有 props:
const props = defineProps(['title']) console.log(props.title)
如果你沒有使用<script setup>,props 必須以props選項的方式聲明,props 對象會作為setup()函數(shù)的第一個參數(shù)被傳入:
export default {
props: ['title'],
setup(props) {
console.log(props.title)
}
}一個組件可以有任意多的 props,默認情況下,所有 prop 都接受任意類型的值。
當(dāng)一個 prop 被注冊后,可以像這樣以自定義 attribute 的形式傳遞數(shù)據(jù)給它:
<BlogPost title="My journey with Vue" /> <BlogPost title="Blogging with Vue" /> <BlogPost title="Why Vue is so fun" />
在實際應(yīng)用中,我們可能在父組件中會有如下的一個博客文章數(shù)組:
const posts = ref([
{ id: 1, title: 'My journey with Vue' },
{ id: 2, title: 'Blogging with Vue' },
{ id: 3, title: 'Why Vue is so fun' }
])這種情況下,我們可以使用v-for來渲染它們:
<BlogPost v-for="post in posts" :key="post.id" :title="post.title" />
留意我們是如何使用v-bind來傳遞動態(tài) prop 值的。當(dāng)事先不知道要渲染的確切內(nèi)容時,這一點特別有用。
監(jiān)聽事件?
讓我們繼續(xù)關(guān)注我們的<BlogPost>組件。我們會發(fā)現(xiàn)有時候它需要與父組件進行交互。例如,要在此處實現(xiàn)無障礙訪問的需求,將博客文章的文字能夠放大,而頁面的其余部分仍使用默認字號。
在父組件中,我們可以添加一個postFontSizeref來實現(xiàn)這個效果:
const posts = ref([ /* ... */ ]) const postFontSize = ref(1)
在模板中用它來控制所有博客文章的字體大?。?/p>
<div :style="{ fontSize: postFontSize + 'em' }">
<BlogPost
v-for="post in posts"
:key="post.id"
:title="post.title"
/>
</div>然后,給<BlogPost>組件添加一個按鈕:
<!-- BlogPost.vue, 省略了 <script> -->
<template>
<div class="blog-post">
<h4>{{ title }}</h4>
<button>Enlarge text</button>
</div>
</template>這個按鈕目前還沒有做任何事情,我們想要點擊這個按鈕來告訴父組件它應(yīng)該放大所有博客文章的文字。要解決這個問題,組件實例提供了一個自定義事件系統(tǒng)。父組件可以通過v-on或@來選擇性地監(jiān)聽子組件上拋的事件,就像監(jiān)聽原生 DOM 事件那樣:
<BlogPost ... @enlarge-text="postFontSize += 0.1" />
子組件可以通過調(diào)用內(nèi)置的$emit方法,通過傳入事件名稱來拋出一個事件
<!-- BlogPost.vue, 省略了 <script> -->
<template>
<div class="blog-post">
<h4>{{ title }}</h4>
<button @click="$emit('enlarge-text')">Enlarge text</button>
</div>
</template>因為有了@enlarge-text="postFontSize += 0.1"的監(jiān)聽,父組件會接收這一事件,從而更新postFontSize的值。
我們可以通過defineEmits宏來聲明需要拋出的事件:
<!-- BlogPost.vue --> <script setup> defineProps(['title']) defineEmits(['enlarge-text']) </script>
這聲明了一個組件可能觸發(fā)的所有事件,還可以對事件的參數(shù)進行驗證。同時,這還可以讓 Vue 避免將它們作為原生事件監(jiān)聽器隱式地應(yīng)用于子組件的根元素。
和defineProps類似,defineEmits僅可用于<script setup>之中,并且不需要導(dǎo)入,它返回一個等同于$emit方法的emit函數(shù)。它可以被用于在組件的<script setup>中拋出事件,因為此處無法直接訪問$emit:
<script setup>
const emit = defineEmits(['enlarge-text'])
emit('enlarge-text')
</script>如果你沒有在使用<script setup>,你可以通過emits選項定義組件會拋出的事件。你可以從setup()函數(shù)的第二個參數(shù),即 setup 上下文對象上訪問到emit函數(shù):
export default {
emits: ['enlarge-text'],
setup(props, ctx) {
ctx.emit('enlarge-text')
}
}以上就是vue中prop值的傳遞詳解的詳細內(nèi)容,更多關(guān)于vue傳遞props的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
安裝@vue/cli 報錯npm WARN deprecated request
這篇文章主要介紹了安裝@vue/cli 報錯npm WARN deprecated request@2.88.2問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

