ホームページ > ウェブフロントエンド > jsチュートリアル > Vue コンポーネントのオプションの小道具

Vue コンポーネントのオプションの小道具

大家讲道理
リリース: 2017-08-19 10:32:07
オリジナル
1820 人が閲覧しました

前に述べたように

コンポーネントで受け入れられるオプションのほとんどは Vue インスタンスと同じであり、オプション props はコンポーネント内で非常に重要なオプションです。 Vue では、親コンポーネントと子コンポーネント間の関係は、プロパティが下、イベントが上として要約できます。親コンポーネントは props を通じて子コンポーネントにデータを渡し、子コンポーネントはイベントを通じて親コンポーネントにメッセージを送信します。この記事ではVueコンポーネントのオプションpropsを詳しく紹介します

static 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: '&lt;p&gt;{{message}}&lt;/p&gt;',
  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

  在模板中,要动态地绑定父组件的数据到子模板的 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验证

  可以为组件的 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会在组件实例创建之前进行校验,所以在 defaultvalidator 函数里,诸如 datacomputedmethods

<p id="example">
  <parent></parent>
</p>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

Static Prop は、親コンポーネント内の子コンポーネントのプレースホルダーに属性を追加することで、値を渡すという目的を達成します

<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>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

🎜🎜dynamic props🎜🎜 テンプレートでは、テンプレートのデータを動的にバインドする必要があります親コンポーネントから子へのテンプレート プロパティは、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()
  }
}
ログイン後にコピー
ログイン後にコピー
🎜🎜🎜🎜🎜 🎜🎜 リテラル prop であるため、その値は数値ではなく文字列 "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>
ログイン後にコピー
ログイン後にコピー
🎜🎜🎜🎜🎜 または、動的プロパティを使用して、データに対応する数値 1🎜 を設定することもできます属性🎜🎜rrreee🎜🎜🎜🎜🎜props検証🎜🎜 コンポーネントのpropsの検証仕様を指定できます。受信データが仕様を満たしていない場合、Vue は警告を発行します。これは、コンポーネントが他の人によって使用されている場合に便利です🎜🎜 検証仕様を指定するには、文字列配列ではなく、オブジェクトの形式を使用する必要があります🎜🎜🎜rrreee🎜🎜🎜 typeは次のとおりですネイティブ コンストラクター コンストラクター 🎜🎜🎜rrreee🎜🎜🎜 type は、instanceof を使用して検出するカスタム コンストラクター関数にすることもできます。 🎜🎜 prop の検証が失敗すると、Vue は警告をスローします (開発バージョンを使用している場合)。小道具はコンポーネント インスタンスが作成されるに検証されるため、default または validator 関数 (data など) で検証されます。 , computedmethods などのインスタンス属性はまだ利用できません🎜🎜 以下は簡単な例です。サブコンポーネントに渡されたメッセージが数値でない場合、警告が表示されます。投げられる🎜🎜🎜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数据

  修改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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート