<五>子父组件间的交互
组件(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')
触发这个参数就行了。

浙公网安备 33010602011771号