首頁 > web前端 > js教程 > Vue組件選項props

Vue組件選項props

大家讲道理
發布: 2017-08-19 10:32:07
原創
1825 人瀏覽過

 前面的話

  元件接受的選項大多與Vue實例一樣,而選項props是元件中非常重要的選項。在 Vue 中,父子元件的關係可以總結為 props down, events up。父元件透過 props 向下傳遞資料給子元件,子元件透過 events 給父元件發送訊息。本文將詳細介紹Vue元件選項props

 

#靜態props

  元件實例的作用域是孤立的。這表示不能 (也不應該) 在子元件的範本內直接引用父元件的資料。要讓子元件使用父元件的數據,需要透過子元件的 props 選項

  使用Prop傳遞資料包含靜態和動態兩種形式,以下先介紹靜態props

#  子元件要顯式地用 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>
登入後複製

#

var parentNode = {
  template: `  <p class="parent">
    <child my-message="aaa"></child>
    <child my-message="bbb"></child>
  </p>`,
  components: {
    'child': childNode
  }
};
登入後複製

# # 

命名約定

  對於props宣告的屬性來說,在父級HTML範本中,屬性名稱需要使用中劃線寫法

#

var childNode = {
  template: '<p>{{myMessage}}</p>',
  props:['myMessage']
}
登入後複製
登入後複製

  子級props屬性宣告時,使用小駝峰或中劃線寫法都可以;而子級模板使用從父級傳來的變數時,需要使用對應的小駝峰寫法

var childNode = {
  template: '<p>{{myMessage}}</p>',
  props:['my-message']
}
登入後複製

var childNode = {
  template: '<p>{{myMessage}}</p>',
  props:['myMessage']
}
登入後複製
登入後複製

動態props

  在範本中,要動態地綁定父元件的資料到子模板的props,與綁定到任何普通的HTML特性相類似,就是用 

v-bind

。每當父元件的資料變更時,此變更也會傳導給子元件

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>
登入後複製

<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">&lt;!-- 传递实际的 number --&gt;&lt;comp v-bind:some-prop=&quot;1&quot;&gt;&lt;/comp&gt;</pre><div class="contentsignin">登入後複製</div></div>

#  因為它是一個字面上prop,它的值是字串

"1"

而不是number。如果想要傳遞一個實際的number,就需要使用

v-bind

,從而讓它的值被當作JS表達式計算 

var parentNode = {
  template: `  <p class="parent">
    <my-child :my-message="1"></my-child>
  </p>`,
  components: {
    'myChild': childNode
  }
};
登入後複製

var parentNode = {
  template: `  <p class="parent">
    <my-child :my-message="data"></my-child>
  </p>`,
  components: {
    'myChild': childNode
  },
  data(){
    return {
      'data': 1
    }
  }
};
登入後複製

  或可以使用動態props,在data屬性中設定對應的數字1

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
      }
    }
  }
})
登入後複製

 

props驗證

  可以為元件的props 指定驗證規格。如果傳入的資料不符合規格,Vue會發出警告。當元件給其他人使用時,這很有用

  要指定驗證規格,需要用物件的形式,而不能用字串陣列

String
Number
Boolean
Function
Object
Array
Symbol
登入後複製

#  type 可以是下面原生建構器

<p id="example">
  <parent></parent>
</p>
登入後複製
登入後複製
登入後複製
  type 也可以是自訂建構器函數,使用instanceof 檢測。   當 prop 驗證失敗,Vue 會在拋出警告 (如果使用的是開發版本)。 props會在元件實例創建之前進行校驗,所以在default 或

validator

函數裡,諸如

data

computed

methods

等實例屬性還無法使用

  下面是一個簡單例子,如果傳入子元件的message不是數字,則拋出警告

#

<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>
登入後複製

var childNode = {
  template: '<p>{{message}}</p>',
  props:{
    'message':{
      validator: function (value) {
        return value > 10
      }
    }
  }
}
登入後複製

  傳入數字123時,則無警告提示。當傳入字串'123'時,結果如下所示

  將上面程式碼中,子元件的內容修改如下,可自訂驗證函數,當函數傳回為false時,則輸出警告提示

var parentNode = {
  template: `
  <p class="parent">
    <child :message="msg"></child>
  </p>`,
  components: {
    'child': childNode
  },
  data(){
    return{
      msg:1
    }
  }
};
登入後複製

  在父元件中傳入msg值為1,由於小於10,則輸出警告提示

<p id="example">
  <parent></parent>
</p>
登入後複製
登入後複製
登入後複製

############ #######單向資料流######  prop 是單向綁定的:當父元件的屬性變化時,將傳導給子元件,但是不會反過來。這是為了防止子元件無意修改了父元件的狀態-這會讓應用程式的資料流難以理解###

  另外,每次父组件更新时,子组件的所有 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組件選項props的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板