Props聲明
一個(gè)組件需要顯示聲明它所接受的props,這樣vue才能知道外部傳入的哪些是props,哪些是透?jìng)鱝ttribute
在使script setup的單文件中,props可以使用 ==defineProps()==宏來聲明:
<script setup>
const props= defineProps(['foo'])
console.log(props.foo)
<script>
在沒有使用script setup的組件中,prop可以使用props選項(xiàng)來聲明:
export default{
props:['foo'],
setup(props){
//接收props作為第一個(gè)參數(shù)
console.log(props.foo)
}
}
注意傳遞給defineProps的參數(shù)和提供給props選項(xiàng)的值是相同的,兩種聲明方式背后其實(shí)使用的都是prop選項(xiàng)。
除了使用字符串?dāng)?shù)組來聲明prop外,還可以使用對(duì)象的形式:
//使用<script setup>
defineProps({
title:String,
likes:Number
}
}
//使用非<script setup>
export default{
props:{
title:String,
likes:Nunber
}
}
對(duì)于以對(duì)象形式聲明中的每個(gè)屬性,key是prop的名稱,而值則是該prop預(yù)期類型的構(gòu)造函數(shù)。比如,如果要求一個(gè)prop的值是number類型,則可以使用Number構(gòu)造函數(shù)作為其聲明的值。
對(duì)象形式的props聲明不僅可以一定程度上作為組件的文檔,而且如果其他開發(fā)者在使用你的組件時(shí),傳遞錯(cuò)誤的類型,也會(huì)在瀏覽器控制臺(tái)中拋出警告。我們將在本章節(jié)稍后進(jìn)一步討論有關(guān) prop 校驗(yàn)的更多細(xì)節(jié)。
如果你正在搭配 TypeScript 使用
<script setup lang='ts'>
defineProps<{
title?:string
likes?:number
}>()
</script>
傳遞prop的細(xì)節(jié)
Prop名字格式
如果一個(gè)prop的名字很長,應(yīng)使用camelCase形式,因?yàn)樗鼈兪呛戏ǖ腏avascript 標(biāo)識(shí)符,可以直接在模板的表達(dá)式中使用,也可以避免在作為屬性key名時(shí)必須加上引號(hào)
defineProps({
greetingMessage: String
})
<span>{{ greetingMessage }}</span>
雖然理論上你也可以在向子組件傳遞props時(shí)使用camelCase形式(使用Dom 內(nèi)模板是例外),但實(shí)際上為了和HTML attribute 對(duì)齊,我們通常會(huì)為其寫為 kebab-case形式:
<MyComponent greeting-message='hello'/>
對(duì)于組件名我們推薦使用 PascalCase ,因?yàn)檫@提高了模板的可讀性,能幫助我們區(qū)分vue組件和原生Html元素。對(duì)于傳遞props來說,使用camelCase并沒有太多優(yōu)勢(shì),因此我們推薦更貼切html的書寫風(fēng)格。
靜態(tài)vs動(dòng)態(tài) prop
至此,你已經(jīng)見過了很多像這樣的靜態(tài)值形式的props:
<BlogPost title='My journey whit vue'/>
相應(yīng)地,還有使用v-bind 或 縮寫 :來動(dòng)態(tài)綁定的props:
<BlogPost :title='post.title' />
<BlogPost :title="post.title+ 'by'+post.author.name"/>
傳遞不同的值類型
在上述的兩個(gè)例子中,我們只傳入了字符串值,但實(shí)際上任何類型的值都可以作為props的值被傳遞。
Number
<!-- 雖然 `42` 是個(gè)常量,我們還是需要使用 v-bind -->
<!-- 因?yàn)檫@是一個(gè) JavaScript 表達(dá)式而不是一個(gè)字符串 -->
<BlogPost :likes="42" />
<!-- 根據(jù)一個(gè)變量的值動(dòng)態(tài)傳入 -->
<BlogPost :likes="post.likes" />
Boolean
<!-- 僅寫上 prop 但不傳值,會(huì)隱式轉(zhuǎn)換為 `true` -->
<BlogPost is-published />
<!-- 雖然 `false` 是靜態(tài)的值,我們還是需要使用 v-bind -->
<!-- 因?yàn)檫@是一個(gè) JavaScript 表達(dá)式而不是一個(gè)字符串 -->
<BlogPost :is-published="false" />
<!-- 根據(jù)一個(gè)變量的值動(dòng)態(tài)傳入 -->
<BlogPost :is-published="post.isPublished" />
Array
<!-- 雖然這個(gè)數(shù)組是個(gè)常量,我們還是需要使用 v-bind -->
<!-- 因?yàn)檫@是一個(gè) JavaScript 表達(dá)式而不是一個(gè)字符串 -->
<BlogPost :comment-ids="[234, 266, 273]" />
<!-- 根據(jù)一個(gè)變量的值動(dòng)態(tài)傳入 -->
<BlogPost :comment-ids="post.commentIds" />
Object
<!-- 雖然這個(gè)對(duì)象字面量是個(gè)常量,我們還是需要使用 v-bind -->
<!-- 因?yàn)檫@是一個(gè) JavaScript 表達(dá)式而不是一個(gè)字符串 -->
<BlogPost
:author="{
name: 'Veronica',
company: 'Veridian Dynamics'
}"
/>
<!-- 根據(jù)一個(gè)變量的值動(dòng)態(tài)傳入 -->
<BlogPost :author="post.author" />
使用一個(gè)對(duì)象綁定多個(gè)prop
如果你想要將一個(gè)對(duì)象的所有屬性都當(dāng)作props傳入,你可以使用沒有參數(shù)的v-bind,即只使用 v-bind 而非屬性
const post = {
id: 1,
title: 'My Journey with Vue'
}
以及下面的模板:
<BlogPost v-bind="post" />
而這實(shí)際上等價(jià)于:
<BlogPost :id="post.id" :title="post.title" />
單向數(shù)據(jù)流
所有的props都遵循著單向綁定原則,props因父組件的更新而變化,自然地將新狀態(tài)向下流往子組件,而不會(huì)逆向傳遞。這避免了子組件意外修改父組件的狀態(tài)的情況,不然應(yīng)用的數(shù)據(jù)流將會(huì)很容易變得混亂而難以理解。
另外,每次父組件更新完后,所有的子組件中的props都會(huì)被更新到最新值,這意味著你不應(yīng)該在子組件中去修改一個(gè)prop。否則會(huì)拋出警告:
const props = defineProps(['foo'])
// ? 警告!prop 是只讀的!
props.foo = 'bar'
導(dǎo)致你想要更改一個(gè)prop的需求通常來之以下兩種場(chǎng)景:
1.prop被用于傳入初始值,而子組件想在之后將其作為一個(gè)局部數(shù)據(jù)屬性。愛這種情況下,最好是新定義一個(gè)局部數(shù)據(jù)屬性,從props上獲取初始值即可:
const props =defineProps(['initialCounter'])
// 計(jì)數(shù)器只是將 props.initialCounter 作為初始值
// 像下面這樣做就使 prop 和后續(xù)更新無關(guān)了
const counter = ref(props.initialCounter)
2.需要對(duì)傳入的prop值做進(jìn)一步的轉(zhuǎn)換,在這種情況下,最好是基于該prop值定義一個(gè)計(jì)算屬性:
const props = defineProps(['size'])
// 該 prop 變更時(shí)計(jì)算屬性也會(huì)自動(dòng)更新
const normalizedSize = computed(() => props.size.trim().toLowerCase())
更改對(duì)象 / 數(shù)組類型的 props
當(dāng)對(duì)象或數(shù)組作為 props 被傳入時(shí),雖然子組件無法更改 props 綁定,但仍然可以更改對(duì)象或數(shù)組內(nèi)部的值。這是因?yàn)?JavaScript 的對(duì)象和數(shù)組是按引用傳遞,而對(duì) Vue 來說,禁止這樣的改動(dòng),雖然可能生效,但有很大的性能損耗,比較得不償失。文章來源:http://www.zghlxwxcb.cn/news/detail-716999.html
這種更改的主要缺陷是它允許了子組件以某種不明顯的方式影響父組件的狀態(tài),可能會(huì)使數(shù)據(jù)流在將來變得更難以理解。在最佳實(shí)踐中,你應(yīng)該盡可能避免這樣的更改,除非父子組件在設(shè)計(jì)上本來就需要緊密耦合。在大多數(shù)場(chǎng)景下,子組件應(yīng)該拋出一個(gè)事件來通知父組件做出改變。文章來源地址http://www.zghlxwxcb.cn/news/detail-716999.html
到了這里,關(guān)于vue3中的Props的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!