コンポーネントで受け入れられるオプションのほとんどは Vue インスタンスと同じであり、オプション props はコンポーネント内で非常に重要なオプションです。 Vue では、親コンポーネントと子コンポーネント間の関係は、プロパティが下、イベントが上として要約できます。親コンポーネントは props を通じて子コンポーネントにデータを渡し、子コンポーネントはイベントを通じて親コンポーネントにメッセージを送信します。この記事ではVueコンポーネントのオプションpropsを詳しく紹介します
コンポーネントインスタンスのスコープは分離されています。これは、子コンポーネントのテンプレート内で親コンポーネントのデータを直接参照できない (また、参照すべきではない) ことを意味します。子コンポーネントに親コンポーネントのデータを使用させるには、子コンポーネントの props オプションを使用する必要があります
。Prop を使用してデータを渡すには、まず静的 props を導入します
。 use props オプションは、取得するデータを宣言します<code>props
选项声明它期待获得的数据
var childNode = { template: '<p>{{message}}</p>', props:['message'] }
静态Prop通过为子组件在父组件中的占位符添加特性的方式来达到传值的目的
<p id="example"> <parent></parent></p>
<script>var childNode = { template: '<p>{{message}}</p>', props:['message'] }var parentNode = { template: ` <p class="parent"> <child message="aaa"></child> <child message="bbb"></child> </p>`, components: { 'child': childNode } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
对于props声明的属性来说,在父级HTML模板中,属性名需要使用中划线写法
var parentNode = { template: ` <p class="parent"> <child my-message="aaa"></child> <child my-message="bbb"></child> </p>`, components: { 'child': childNode } };
子级props属性声明时,使用小驼峰或者中划线写法都可以;而子级模板使用从父级传来的变量时,需要使用对应的小驼峰写法
var childNode = { template: '<p>{{myMessage}}</p>', props:['myMessage'] }
var childNode = { template: '<p>{{myMessage}}</p>', props:['my-message'] }
在模板中,要动态地绑定父组件的数据到子模板的 props,与绑定到任何普通的HTML特性相类似,就是用 v-bind
。每当父组件的数据变化时,该变化也会传导给子组件
var childNode = { template: '<p>{{myMessage}}</p>', props:['myMessage'] }
var parentNode = { template: ` <p class="parent"> <child :my-message="data1"></child> <child :my-message="data2"></child> </p>`, components: { 'child': childNode }, data(){ return { 'data1':'aaa', 'data2':'bbb' } } };
初学者常犯的一个错误是使用字面量语法传递数值
<!-- 传递了一个字符串 "1" --><comp some-prop="1"></comp>
<p id="example"> <my-parent></my-parent></p>
<script>var childNode = { template: '<p>{{myMessage}}的类型是{{type}}</p>', props:['myMessage'], computed:{ type(){ return typeof this.myMessage } } }var parentNode = { template: ` <p class="parent"> <my-child my-message="1"></my-child> </p>`, components: { 'myChild': childNode } };// 创建根实例new Vue({ el: '#example', components: { 'MyParent': parentNode } })</script>
因为它是一个字面 prop,它的值是字符串 "1"
而不是 number。如果想传递一个实际的 number,需要使用 v-bind
,从而让它的值被当作JS表达式计算
<!-- 传递实际的 number --><comp v-bind:some-prop="1"></comp>
var parentNode = { template: ` <p class="parent"> <my-child :my-message="1"></my-child> </p>`, components: { 'myChild': childNode } };
或者可以使用动态props,在data属性中设置对应的数字1
var parentNode = { template: ` <p class="parent"> <my-child :my-message="data"></my-child> </p>`, components: { 'myChild': childNode }, data(){ return { 'data': 1 } } };
可以为组件的 props 指定验证规格。如果传入的数据不符合规格,Vue会发出警告。当组件给其他人使用时,这很有用
要指定验证规格,需要用对象的形式,而不能用字符串数组
Vue.component('example', { props: { // 基础类型检测 (`null` 意思是任何类型都可以) propA: Number, // 多种类型 propB: [String, Number], // 必传且是字符串 propC: { type: String, required: true }, // 数字,有默认值 propD: { type: Number, default: 100 }, // 数组/对象的默认值应当由一个工厂函数返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, // 自定义验证函数 propF: { validator: function (value) { return value > 10 } } } })
type
可以是下面原生构造器
String Number Boolean Function Object Array Symbol
type
也可以是一个自定义构造器函数,使用 instanceof
检测。
当 prop 验证失败,Vue 会在抛出警告 (如果使用的是开发版本)。props会在组件实例创建之前进行校验,所以在 default
或 validator
函数里,诸如 data
、computed
或 methods
<p id="example"> <parent></parent> </p>
<script> var childNode = { template: '<p>{{message}}</p>', props:{ 'message':Number } } var parentNode = { template: ` <p class="parent"> <child :message="msg"></child> </p>`, components: { 'child': childNode }, data(){ return{ msg: '123' } } }; // 创建根实例 new Vue({ el: '#example', components: { 'parent': parentNode } }) </script>
りー
ネーミング規約
props 宣言された属性の場合、親 HTML テンプレートでは属性名をアンダースコアで記述する必要があります
var childNode = { template: '<p>{{message}}</p>', props:{ 'message':{ validator: function (value) { return value > 10 } } } }
子 props 属性を宣言する場合は、キャメルケースまたはアンダースコアで記述することができます。子テンプレート 親から渡された変数を使用する場合は、対応するキャメルケースを使用する必要があります
var parentNode = { template: ` <p class="parent"> <child :message="msg"></child> </p>`, components: { 'child': childNode }, data(){ return{ msg:1 } } };
<p id="example"> <parent></parent> </p>
v-bind
を使用して通常の HTML 機能にバインドされます。親コンポーネントのデータが変更されると、その変更は子コンポーネントにも送信されます🎜🎜🎜<script> var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="childMsg"> </p> <p>{{childMsg}}</p> </p> `, props:['childMsg'] } var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } }; // 创建根实例 new Vue({ el: '#example', components: { 'parent': parentNode } }) </script>
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
<p id="example"> <parent></parent></p><script>var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="temp"> </p> <p>{{temp}}</p> </p> `, props:['childMsg'], data(){ return{ temp:this.childMsg } }, };var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
"1"
になります。実際の数値を渡したい場合は、その値が JS 式として評価されるように v-bind
を使用する必要があります 🎜🎜🎜<script src="https://unpkg.com/vue"></script><script>var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="temp"> </p> <p>{{temp}}</p> </p> `, props:['childMsg'], computed:{ temp(){ return this.childMsg } }, };var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
<p id="example"> <parent></parent></p><script>var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="temp"> </p> <p>{{temp}}</p> </p> `, props:['childMsg'], data(){ return{ temp:this.childMsg } }, watch:{ childMsg(){ this.temp = this.childMsg } } };var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
type
は次のとおりですネイティブ コンストラクター コンストラクター 🎜🎜🎜rrreee🎜🎜🎜 type
は、instanceof
を使用して検出するカスタム コンストラクター関数にすることもできます。 🎜🎜 prop の検証が失敗すると、Vue は警告をスローします (開発バージョンを使用している場合)。小道具はコンポーネント インスタンスが作成される前に検証されるため、default
または validator
関数 (data
など) で検証されます。 , computed
や methods
などのインスタンス属性はまだ利用できません🎜🎜 以下は簡単な例です。サブコンポーネントに渡されたメッセージが数値でない場合、警告が表示されます。投げられる🎜🎜🎜rrreee🎜 🎜🎜🎜rrreee🎜🎜🎜 数字123が渡されたとき、警告はありません。文字列「123」が渡されると、結果は次のようになります 🎜🎜🎜🎜🎜 上記のコードのサブコンポーネントの内容を次のように変更します。 関数が false を返す場合、警告プロンプトが表示されるようにカスタマイズできます。出力🎜🎜🎜 rrreee🎜🎜🎜 親コンポーネントの受信msg値は1です。10未満なので警告プロンプトが出力されます🎜🎜🎜rrreee🎜🎜🎜🎜🎜🎜🎜🎜一方向のデータフロー🎜🎜 prop は一方向バインドです: when 親コンポーネントのプロパティが変更されると、それらは子コンポーネントに伝播されますが、その逆は伝播されません。これは、子コンポーネントが親コンポーネントの状態を誤って変更することを防ぐためです。これにより、アプリケーションのデータ フローが理解しにくくなります🎜另外,每次父组件更新时,子组件的所有 prop 都会更新为最新值。这意味着不应该在子组件内部改变 prop。如果这么做了,Vue 会在控制台给出警告
下面是一个典型例子
<p id="example"> <parent></parent> </p>
<script> var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="childMsg"> </p> <p>{{childMsg}}</p> </p> `, props:['childMsg'] } var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } }; // 创建根实例 new Vue({ el: '#example', components: { 'parent': parentNode } }) </script>
父组件数据变化时,子组件数据会相应变化;而子组件数据变化时,父组件数据不变,并在控制台显示警告
修改子组件数据时,打开浏览器控制台会出现下图所示警告提示
修改prop中的数据,通常有以下两种原因
1、prop 作为初始值传入后,子组件想把它当作局部数据来用
2、prop 作为初始值传入,由子组件处理成其它数据输出
[注意]JS中对象和数组是引用类型,指向同一个内存空间,如果 prop 是一个对象或数组,在子组件内部改变它会影响父组件的状态
对于这两种情况,正确的应对方式是
1、定义一个局部变量,并用 prop 的值初始化它
props: ['initialCounter'], data: function () { return { counter: this.initialCounter } }
但是,定义的局部变量counter只能接受initialCounter的初始值,当父组件要传递的值发生变化时,counter无法接收到最新值
<p id="example"> <parent></parent></p><script>var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="temp"> </p> <p>{{temp}}</p> </p> `, props:['childMsg'], data(){ return{ temp:this.childMsg } }, };var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
下面示例中,除初始值外,父组件的值无法更新到子组件中
2、定义一个计算属性,处理 prop 的值并返回
props: ['size'], computed: { normalizedSize: function () { return this.size.trim().toLowerCase() } }
但是,由于是计算属性,则只能显示值,而不能设置值
<script src="https://unpkg.com/vue"></script><script>var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="temp"> </p> <p>{{temp}}</p> </p> `, props:['childMsg'], computed:{ temp(){ return this.childMsg } }, };var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
下面示例中,由于子组件使用的是计算属性,所以,子组件的数据无法手动修改
3、更加妥帖的方案是,使用变量储存prop的初始值,并使用watch来观察prop的值的变化。发生变化时,更新变量的值
<p id="example"> <parent></parent></p><script>var childNode = { template: ` <p class="child"> <p> <span>子组件数据</span> <input v-model="temp"> </p> <p>{{temp}}</p> </p> `, props:['childMsg'], data(){ return{ temp:this.childMsg } }, watch:{ childMsg(){ this.temp = this.childMsg } } };var parentNode = { template: ` <p class="parent"> <p> <span>父组件数据</span> <input v-model="msg"> </p> <p>{{msg}}</p> <child :child-msg="msg"></child> </p> `, components: { 'child': childNode }, data(){ return { 'msg':'match' } } };// 创建根实例new Vue({ el: '#example', components: { 'parent': parentNode } })</script>
以上がVue コンポーネントのオプションの小道具の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。