前言
在上个文章中介绍了组件的注册,包括局部注册和全局注册。这里将介绍父子组件以及父子组件之间的通信方式。
父子组件
父子组件,顾名思义就是在组件中套用组件形成父子关系,一个简单的实例如下:
<body>
<div id="app">
<father> </father>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
components:{
father:{
template:`
<div>
<h1>父组件</h1>
<child></child>
</div>`,
components: {
child:{
template:`<h1>子组件</h1>`
}
}
}
}
})
</script>
</body>
如上就是定义了一个最简单的父子组件,之前说到实例就是组件,所以组件中也可以声明实例中有的对象属性。定义父子对象比较简单,接下来就说一下父子组件怎么传递数据。
父子组件传递数据
首先介绍一个属性props
,它是一个数组,作用就是接收传进来的值:
<body>
<div id="app">
<father title="这里是标签"> </father>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
components:{
father:{
props:["title"],
template:`
<div>
<h1>父组件</h1>
<h1>{{title}}</h1>
<child></child>
</div>`
}
}
}
})
</script>
</body>
<!--
渲染效果:
父组件
这里是标签
-->
我们直接在组件标签中中声明了一个变量用来接收值,同时用props进行接收,最后可以直接应用在Vue支持的语法上。虽然只是传递了字符串,事实上它可以传递JavaScript所以类型。和组件的命名格式一样,在JavaScript中可以使用“驼峰命名”,但是在html中需要使用短横线命名,模板字符串除外。
像这样,我们已经知道了可以像这样给 prop 传入一个静态的值:
<father title="这里是标签"> </father>
prop 也可以通过 v-bind 动态赋值,例如:
<!-- 动态赋予一个变量的值 -->
<blog-post v-bind:title="post.title"></blog-post>
<!-- 动态赋予一个复杂表达式的值 -->
<blog-post
v-bind:title="post.title + ' by ' + post.author.name"
></blog-post>
我们知道了动态传值后,剩下的就好办了,因为父子组件传值依赖 v-bind 动态赋值:
new Vue({
el: '#app',
components:{
father:{
data(){
return{
msg:"白月光与朱砂痣"
}
}
template:`
<div>
<h1>父组件</h1>
<child :msg="msg"></child>
</div>`,
components: {
child:{
props:["msg"],
template:`<h1>子组件{{msg}}</h1>`
}
}
}
}
})
如上所示,首先在father组件中定义了msg数据,之后用动态传值的方式绑定到子组件,接着用 props 接收这个传过来了参数,最后在插值语法中渲染。
父子组件传递方法
new Vue({
el: '#app',
components:{
father:{
data(){
return {
msg:""
}
},
methods:{
fatherFunction(value) {
this.msg=value
alert("白月光与朱砂痣"+value)
}
},
template:`
<div>
<h1>父组件 {{msg}}</h1>
<child @father-function="fatherFunction"></child>
</div>`,
components: {
child:{
template:`<h1 @click="childFunction">子组件</h1>`,
methods:{
childFunction(){
this.$emit("father-function",",你想起她的好")
}
}
}
}
}
}
})
在上面中主要实现了两个功能,一个是把父组件的方法传递给子组件,另一个就是把子组件的数据传递给父组件。
在传递方法的时候,对属性需要使用v-on
进行指定,不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或 property 名,所以就没有理由使用“驼峰命名”了。并且 v-on
事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent
将会变成 v-on:myevent
——导致 myEvent 不可能被监听到,所以记性传递的时候推荐使用短横线命名,“驼峰命名”不会起到作用的。
传递给子组件之后,需要子组件另定义一个方式,在子组件中的方法通过this.$emit("事件名")"
进行调用。第一个参数是方法名,往后的参数是方法的属性了,这里传递了一个字符串,通过子组件调用父组件的方法把数据传递父组件data中的数据。