1. 程式人生 > 其它 ><五>子父元件間的互動

<五>子父元件間的互動

元件(Component)是 Vue.js 最強大的功能之一,元件可以擴充套件 HTML 元素,封裝可重用的程式碼。

1、基本定義和使用

    <body>
      <div id="app">
        <child></child>
        <child1></child1>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全域性註冊
      Vue.component('
child', { template: '<h1>自定義元件!</h1>' }) var ChildTemplate = { template: '<h1>自定義元件!</h1>' } var app = new Vue({ el: '#app' , components: { // <child1> 將只在父模板可用,區域性註冊
'child1': ChildTemplate } }); </script>

2、父元件向子元件互動,props 單向傳遞

  <body>
      <div id="app">
        <div>
          <input v-model="parentMsg">
          <br>
          <child v-bind:message="
parentMsg"></child> </div> </div> <script src="vue.js"></script> <script> // 全域性註冊 Vue.component('child', { props:['message'], template: '<h1>{{message}}</h1>' }) var app = new Vue({ el: '#app', data:{ parentMsg:'' } }); </script>

3、props驗證,如上面例子,如果message只接收數值型用於計算,但是該值是使用者輸入,這時候使用者可以隨便輸入,但是字元型資料並不是我們想要的。

因此傳入的引數可能會在開發子元件的人的意料之外,程式就會發生錯誤,在函式呼叫之前先檢查一下函式一樣,props可以進行一個預先檢查。

 <body>
      <div id="app">
        <div>
          <input v-model="parentMsg">
          <br>
          <child v-bind:message="parentMsg"></child>
        </div>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全域性註冊
      Vue.component('child', {
        props:{
          message:Number        //只能傳入數值型
        },
        template: '<h1>{{message}}</h1>'
      })

      var app = new Vue({
                          el: '#app', 
                          data:{
                            parentMsg:0
                          }                               
                    });
   </script>

結果:當沒有對輸入框的輸入值限定為數值型時,看結果

vue會自動給出一個warn提示,只是個警告,沒有強制報錯。這個警告不知道怎麼捕捉(噗)

給輸入框輸入一個限定型別,

 <input v-model.Number="parentMsg">

這樣就可以自動將輸入值過濾字元並將輸入值自動轉換成數字型,這樣就不會出現這個警告了。

props驗證有多種型別。

當允許多種型別時,比如允許輸入string和number型別時props的定義

 props:{
          message:[Number,String]        //只能傳入數值型
        },

所有的驗證如下:

 props: {
    // 基礎型別檢測 (`null` 意思是任何型別都可以)
    A: Number,
    // 多種型別
    B: [String, Number],
    // 必傳且是字串
    C: {
      type: String,
      required: true
    },
    // 數字,有預設值
    D: {
      type: Number,
      default: 100
    },
    // 陣列/物件的預設值應當由一個工廠函式返回
    E: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定義驗證函式
    F: {
      validator: function (value) {
        return value > 10
      }
    }
  }

4、上面是父元件向子元件傳遞資料,那如果子元件向父元件傳遞資料呢?

  • 使用 $on(eventName) 監聽事件
  • 使用 $emit(eventName) 觸發事件

父元件可以在使用子元件的地方直接用 v-on 來監聽子元件觸發的事件。

 <body>
      <div id="app">
        <p>{{ total }}</p>
      <child v-on:increment="incrementTotal"></child>
    </div>
    
    <script src="vue.js"></script>
    <script>
      // 全域性註冊
      Vue.component('child', {
        template: '<button v-on:click="changeName">{{ counter }}</button>',
        data:function () {
            return {
              counter: 0
            }
          },
        methods: {
          changeName: function () {
            this.counter += 1
            this.$emit('increment')
          }
  },
      })

      var app = new Vue({
                          el: '#app', 
                          data:{
                            total: 0
                          } , 
                          methods: {
                            incrementTotal: function () {
                            this.total += 1
                            }
                          }                              
                    });
   </script>

如程式碼所示,將一個方法繫結一個別名傳遞給子元件,然後子元件使用

this.$emit('increment')

觸發這個引數就行了。