Vue.js
小道具
サーチ…
備考
camelCase <=>ケバブケース
あなたのprops
の名前を定義するとき、HTML属性名は大文字小文字を区別しないことに常に注意してください。それは、あなたがコンポーネント定義でラクダのケースでprop
を定義するならば...
Vue.component('child', {
props: ['myProp'],
...
});
... HTMLコンポーネントでmy-propとして呼び出す必要があります。
小道具を使って親から子へデータを渡す
Vue.jsでは、すべてのコンポーネントインスタンスには独立したスコープがあります。つまり、親コンポーネントに子コンポーネントがある場合、子コンポーネントは独自の分離スコープを持ち、親コンポーネントは独自の分離スコープを持ちます。
中規模から大規模までのアプリケーションでは、ベストプラクティス規約に従えば、開発フェーズ中およびその後のメンテナンス中に多くの頭痛を防ぎます。従うべきことの1つは、子コンポーネントから親データを直接参照/変更することを避けることです 。それでは、子コンポーネント内から親データをどのように参照するのですか?
子コンポーネントに必要な親データは、親からのprops
として子に渡す必要があります。
ユースケース :次のフィールドを持つ2つのテーブルのusers
とaddresses
を持つユーザーデータベースがあるとします。
users
テーブル
名 | 電話 | Eメール |
---|---|---|
ジョン・マクレーン | (1)234 5678 9012 | [email protected] |
ジェームズ・ボンド | (44)777 0007 0077 | [email protected] |
addresses
表
ブロック | 通り | シティ |
---|---|---|
中富タワーズ | ブロードウェイ | ニューヨーク |
Mi6ハウス | バッキンガムロード | ロンドン |
私たちはアプリ内のどこにでも対応するユーザー情報を表示するために3つのコンポーネントを用意したいと考えています
user-component.js
export default{
template:`<div class="user-component">
<label for="name" class="form-control">Name: </label>
<input class="form-control input-sm" name="name" v-model="name">
<contact-details :phone="phone" :email="email"></contact-details>
</div>`,
data(){
return{
name:'',
phone:'',
email:''
}
},
}
連絡先詳細.js
import Address from './address';
export default{
template:`<div class="contact-details-component>
<h4>Contact Details:</h4>
<label for="phone" class="form-control">Phone: </label>
<input class="form-control input-sm" name="phone" v-model="phone">
<label for="email" class="form-control">Email: </label>
<input class="form-control input-sm" name="email" v-model="email">
<h4>Address:</h4>
<address :address-type="addressType"></address>
//see camelCase vs kebab-case explanation below
</div>`,
props:['phone', 'email'],
data:(){
return:{
addressType:'Office'
}
},
components:{Address}
}
address.js
export default{
template:`<div class="address-component">
<h6>{{addressType}}</h6>
<label for="block" class="form-control">Block: </label>
<input class="form-control input-sm" name="block" v-model="block">
<label for="street" class="form-control">Street: </label>
<input class="form-control input-sm" name="street" v-model="street">
<label for="city" class="form-control">City: </label>
<input class="form-control input-sm" name="city" v-model="city">
</div>`,
props:{
addressType:{
required:true,
type:String,
default:'Office'
},
data(){
return{
block:'',
street:'',
city:''
}
}
}
main.js
import Vue from 'vue';
Vue.component('user-component', require'./user-component');
Vue.component('contact-details', require'./contact-details');
new Vue({
el:'body'
});
index.html
...
<body>
<user-component></user-component>
...
</body>
私たちはphone
やemail
データを表示しています。これは、 phone
やemail
データを持たないcontact-details
にuser-component
プロパティです。
データを小道具として渡す
したがって、 <contact-details>
コンポーネントを含むテンプレートプロパティのuser-component.js
内では、 <user-component>
(親コンポーネント)から<contact-details>
電話と電子メールデータを渡しています動的小道具にそれを結合することにより、子コンポーネント) - :phone="phone"
と:email="email
と同じであるv-bind:phone="phone"
とv-bind:email="email"
小道具 - 動的バインディング
親コンポーネント内の電話や電子メールの変更は、親コンポーネント内で動的にバインドされているため、 <user-component>
は直ちに子コンポーネント<contact-details>
反映されます。
小道具 - リテラルとして
しかし、 phone="(44) 777 0007 0077" email="[email protected]"
ような文字列リテラル値として電話と電子メールの値を渡すと、親に起こったデータの変更は反映されません成分。
一方向バインディング
デフォルトでは、変更の方向は上から下になります。つまり、親コンポーネント内の動的にバインドされた小道への変更は子コンポーネントに伝播しますが、子コンポーネント内の小道具値の変更は親に伝播しません。
例えばの場合:内からならば<contact-details>
私たちは、電子メールからの変更[email protected]
する[email protected]
、親データつまり電話データプロパティ<user-component>
まだの値が含まれます[email protected]
。
しかし、電子メールの値を親コンポーネント(このユースケースの<user-component>
)の[email protected]
から[email protected]
に変更すると、子コンポーネントの電子メールの値( <contact-details>
ユースケースの場合)は自動的に[email protected]
に変更されます。親の変更はすぐに子に伝播されます。
双方向バインディング
我々は2-wayが結合したい場合、我々は、明示的として、双方向バインディングを指定する必要が:email.sync="email"
代わりに:email="email"
。子コンポーネントのpropの値を変更すると、変更も親コンポーネントに反映されます。
中規模から大規模のアプリケーションでは、親状態を子状態から変化させることは、デバッグ中に特に検出して追跡するのが非常に難しくなります - 慎重にしてください 。
Vue.js 2.0では.syncオプションは使用できません。 Vue.js 2.0では、小道具の双方向バインドが非推奨になりました 。
ワンタイムバインディング
明示的なワンタイムバインディングを定義することもできます:email.once="email
、リテラルを渡すのとほぼ同じです。これは、親プロパティ値のその後の変更が子に伝播しないためです。
警告
オブジェクトまたは配列が小道具として渡されるときは、 :email.sync="email"
参照渡しとなります。これは、明示的に定義されたバインディングタイプに関係なく、 :email.sync="email"
または:email="email"
または:email.once="email"
電子メールが親のObjectまたはArrayである場合、バインディングタイプに関係なく、子コンポーネント内のprop値の変更は、親の値にも影響します。
配列としての小道具
contact-details.js
ファイルではprops:['phone', 'email']
というprops:['phone', 'email']
配列として定義しました。これは小道具で細かい制御をしたくない場合は問題ありません。
オブジェクトとしての小道具
私たちが小道具をより細かく制御したいなら、
- どのタイプの値が小道具として受け入れられるかを定義したい場合
- 小道具のデフォルト値
- 値が必須かどうかが小道具に渡されるかどうか、またはオプションであるかどうか
address.js
行ったように、オブジェクトの表記法を使用して小道具を定義する必要があります。
チームの他の開発者が使用する再利用可能なコンポーネントをオーサリングしている場合は、コンポーネントを使用するすべての人がどのようなタイプのデータであるべきかを明確に理解できるように、小道具をオブジェクトとして定義することをお勧めしますそれは強制的またはオプションです。
これは、 小道具の検証とも呼ばれます。 typeには、次のネイティブコンストラクタのいずれかを指定できます。
- 文字列
- 数
- ブール
- アレイ
- オブジェクト
- 関数
- またはカスタムコンストラクタ
http://vuejs.org/guide/components.html#Propsから取得した小道具検証の例
Vue.component('example', {
props: {
// basic type check (`null` means accept any type)
propA: Number,
// multiple possible types (1.0.21+)
propM: [String, Number],
// a required string
propB: {
type: String,
required: true
},
// a number with default value
propC: {
type: Number,
default: 100
},
// object/array defaults should be returned from a
// factory function
propD: {
type: Object,
default: function () {
return { msg: 'hello' }
}
},
// indicate this prop expects a two-way binding. will
// raise a warning if binding type does not match.
propE: {
twoWay: true
},
// custom validator function
propF: {
validator: function (value) {
return value > 10
}
},
// coerce function (new in 1.0.12)
// cast the value before setting it on the component
propG: {
coerce: function (val) {
return val + '' // cast the value to string
}
},
propH: {
coerce: function (val) {
return JSON.parse(val) // cast the value to Object
}
}
}
});
キャメルケースとケバブケース
HTML属性は大文字と小文字を区別しません。 addressType
、 addresstype
とaddressType
区別できないため、camelCaseの小道具名を属性として使用するときは、 addressType
(ハイフンで区切ったもの)を使用する必要があります。
addressType
は、HTML属性のaddress-type
としてaddressType
必要があります。
ダイナミックな小道具
ビューからモデルにデータをバインドできるのと同じように、同じv-bindディレクティブを使用して親コンポーネントから子コンポーネントに情報を渡すこともできます。
JS
new Vue({
el: '#example',
data: {
msg: 'hello world'
}
});
Vue.component('child', {
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>
});
HTML
<div id="example">
<input v-model="msg" />
<child v-bind:my-message="msg"></child>
<!-- Shorthand ... <child :my-message="msg"></child> -->
</div>
結果
hello world
Vue JSXの使用中にPropsを渡す
私たちは親コンポーネントを持っています:子コンポーネントをインポートして、属性を介して小道具を渡します。ここで属性は 'src'であり、 'src'も渡しています。
ParentComponent.js
import ChildComponent from './ChildComponent';
export default {
render(h, {props}) {
const src = 'https://cdn-images-1.medium.com/max/800/1*AxRXW2j8qmGJixIYg7n6uw.jpeg';
return (
<ChildComponent src={src} />
);
}
};
子コンポーネント、ここでは小道具を渡す必要があります。私たちは、通過している小道具を指定する必要があります。
ChildComponent.js:
export default {
props: ['src'],
render(h, {props}) {
return (
<a href = {props.src} download = "myimage" >
Click this link
</a>
);
}
};