<五>子父元件間的互動
阿新 • • 發佈:2021-12-11
元件(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')
觸發這個引數就行了。