vuejs官網之prop
prop的大小寫
html中的特性名是大小寫不敏感的,所以瀏覽器會把所有大寫字元解釋為小寫字元。這意味著當你使用dom中的模板時,camelcase(駝峰命名法)的prop名需要使用其等價的kebab-case(短橫線分隔命名)
vue.component('blog-post',{
props:['postTitle'],
template:'<h3>{{postTitle}}</h3>'})
<blog-post post-title="hello"></blog-post>
重申一次,如果你使用字串模板,那麼這個限制就不存在了
prop型別
到這裡,我們只看到了以字串陣列形式列出的prop:
props:['title','likes','ispublished','commentids','authoirt']
但是,通常你希望每個prop都有指定的值型別。這是,你可以以物件形式列出prop,這些屬性的名稱和值分別是prop各自的名稱和型別
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object
}
這不久為你的元件提供了文件,還會在他們遇到錯誤的型別時從瀏覽器的javascript控制檯提示使用者。你會在這個也沒你那接下來的部分看到型別檢查和其他prop驗證
傳遞靜態和動態prop
像這樣,你已經知道了可以像這樣給prop傳入一個靜態的值
<blog-post title="my journey with vue"></blog-post>
你也知道prop可以通過v-bind動態賦值,例如
動態賦予了一個變數的值
<blog-post v-bind:title="post.title"></blog-post>
動態賦予了一個複雜表示式的值
<blog-post v-bind:title="post.title+'by'post.author.name"></blog-post>
在上述兩個例項中,我們傳入的值都是字串型別的,但實際上任何型別的值都可以傳給一個prop。
傳入一個數字
即便42是靜態的,我們任然需要v-bind來告訴vue
這是一個javascript表示式而不是一個字串
<blog-post v-bind:likes="42"></blog-post>
用一個變數進行動態賦值
<blog-post v-bind:likes="post.likes"></blog-post>
傳入一個布林值
包含該prop沒有值的情況在內,都意味著true
<blog-post is-published></blog-post>
即便false是靜態的,我們仍然需要v-bind來告訴vue
這是一個javascript表示式而不是一個字串
<blog-post v-bind:is-published="false"></blog-post>
用一個變數進行動態賦值
<blog-post v-bind:is-published="post.ispublished"></blog-post>
傳入一個數組
即便陣列是靜態的,我們仍然需要v-bind來告訴vue
這是一個javascript表示式而不是一個字串
<blog-post v-bind:comment-ids="[234,123,456]"></blog-post>
用一個變數進行動態賦值
<blog-post v-bind:comment-ids="post.commentids"></blog-post>
傳入一個物件
即便物件是靜態的,我們仍然需要v-bind來告訴vue
這是一個javascript表示式而不是一個字串
<blog-post v-bind:author="{name:'ddff',company:'fasdfasdf'}"></blog-post>
用一個變數進行動態賦值
<blog-post v-bind:author="post.author"></blog-post>
傳入一個物件的所有屬性
如果你想要將一個物件的所有屬性都作為prop傳入,你可以使用不帶引數的v-bind(取代v-bind:prop-name)。例如,對於一個給定的物件post、
post:{
id:1,
title:'fasdfasdf'
}
下面的模板
<blog-post v-bind="post"></blog-post>
等價於
<blog-post
v-bind:id="post.id"
v-bind:title="post.title">
</blog-post>
單項資料流
所有prop都使得其父子prop之間形成了一個單向下行繫結:腹肌prop的更新會向下流動到子元件中,但是反過來則不行。這樣會防止子元件意外改變服及元件的狀態,從而導致你的應用資料流向難以理解
額外,每次腹肌元件發生更新,子元件中所有的prop都將會重新整理為最新的值,這意味著你不應該在一個子元件內部改變prop,如果你這樣做了,vue會在瀏覽器的控制檯中發出警告。
這裡有兩種常見的檢視改變一個prop的情形
1這是prop用來傳遞一個初始值,這個子元件接下來希望將其作為一個本地的prop資料來使用。在這種情況下,最好定義一個本地的data屬性並將這個prop用作其初始值
props:['ffff'],
data:function(){
return{
counter:this.fffff
}
}
2這個prop以一種原始的值傳入且需要進行轉換。在這種情況下,最好使用prop的值來定義一個計算屬性
props:['size'],
computed:{
normalizedsize:function(){
return this.size.trim().tolowercase()
}}
注意在javascript中物件和陣列是通過引用傳入的,所以對於一個數組或物件型別的prop來說,在子元件中改變這個物件或陣列本身將會影響父元件的狀態
prop驗證
我們可以為元件的prop指定驗證要求,例如你知道的這些型別,如果有一個需求沒有被滿足,則vue會在瀏覽器控制檯中警告你。這在開發一個會被別人用到的元件時尤其幫助
為了定製prop的驗證方式,你可以為props中的值提供一個帶有驗證需求的物件,而不是也一個字串陣列。
vue.component('mycom',{
props:{
基礎的型別檢查
propa:bumber,
多個可能的型別
propb:[string,number],
必填的字串
propc:{
type:string,
required:true}
帶有預設值的數字
propd:{
type:number,
default:100}
},
帶有預設值的物件
prope:{
type:object,
default:function(){
return{
message:'fff'}}}
})
當prop驗證失敗的時候,(開發環境構建版本的)vue將會產生一個控制檯的警告
注意哪些prop會在一個元件例項建立之前進行驗證,所以例項的屬性(如data、computed等)在default或validator函式中是不可用的
型別檢查
type可以是下列原生建構函式中的一個
string
number
boolean
array
object
date
function
symbol
額外的,type還可以是一個自定義的建構函式,並且通過instanceof來進行檢查確認,例如,給定下列執行緒的建構函式。
function person(firstname,lastname){
this.firstname=firstname
this.lastname=lastname
}
你可以使用
vue.component('blog-post',{
props:{
author:person
}})
來驗證authorprop的值是否通過new person建立的
非prop的特性
一個非prop特性是指傳向一個子元件,但是該元件並沒有相應prop定義的特性。
因為顯示定義的prop適用於向一個子元件傳入資訊,然而元件庫的作者並不總能遇見元件會被用於怎麼的場景,這也就是為什麼接受任意的特性,而這些特性會被新增到這個元件的根元素
例如,想象以下你通過bs外掛使用了一個第三方的<bootstrap-date-input>元件,這個外掛需要在其<input>上用到一個data-date-picker特性。我們可以將這個特性新增到你的元件例項上,
<boostrap-data-input data-date-picker="activated"></bootstrap-date-input>
然後這個data-date-picker="activated"特性就會自動新增到<boostrap-data-input>的根元素上
替換/合併已有的特性
想象以下,bootstrap-date-input的模板是這樣的
<input type="date" class="form-control">
為了給我們的日期選擇器外掛定製一個主題,我們可能需要向這樣新增一個特別的類名。
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
></bootstrap-date-input>
在這種情況下,我們定義了兩個不同的class的值,
1form-control這是在元件的模板內設定好的
2date-picker-theme-dark這是從元件的父級傳入的
對於絕大多數特性來說,從外部提供給元件的值會替換掉元件內部設定好的值。
所以如果傳入type=“text”就會替換掉type=“date”並把它破壞,慶幸的是,class和style特性會稍微智慧一些,即兩邊的值會被合併起來,從而得到最終的
form-control date-picker-theme-dark
禁用特性繼承
如果你不希望元件的根元素繼承特性,你可以設定在元件的選項中設定
inheritAttrs:false
Vue.component('mycomponent',{
inheritAttrs:false
})
這尤其適合配合例項的sattrs屬性使用。該屬性包含了傳遞給一個元件的特殊名和特性值。
{class:‘uuuu’,
placeholder:'fasdfd'}
有了inheritAttrs:false和$attrs.你就可以手動決定這些特性會被賦予哪些元素。
在撰寫基礎元件的時候常會用到
vue.component('base-input',{
inheritAttrs:false,
props:['label','value'],
template:
<label>
{{ label }}
<input
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
</label>
})
這個模式允許你在使用基礎元件的時候更像是使用原始的html元素。而不會擔心那個元素是真正的根元素
<base-input
v-model="username"
class="username-input"
placeholder="Enter your username"
></base-input>