在vue中 父组件指的就是我们new Vue的这个实例,而子组件通常指的就是我们自己定义的全局或者私有的组件,那么父子组件之间的通信是如何实现的?
父组件向子组件传值
首先我们创建一个Vue实例,在data对象中定义msg属性:
(我们用属性的内容来区分值是属于父组件还是子组件)
data:{
msg:'这是父组件内容 哈哈哈哈'
},
接下来我们创建一个私有子组件,这个私有子组件在页面中进行的调用的时候,
不仅能够显示自身组件的内容,还能显示上述的父组件的内容
首先我们定义这个私有子组件:
components:{
com1:{
template:'<h3>这是子组件</h3>'
}
}
然后在我们在页面中调用:
这时候 我们进行绑定一个属性 parentmsg ,也就是说父组件的msg属性 赋值到我们自己定义的这个属性parentmsg上
<com1 :parentmsg="msg"></com1>
绑定完成之后 我们如何拿到这个值呢?
我们改写com1这个组件内容;
components:{
com1:{
template:'<h3>这是子组件--{{ parentmsg }}</h3>',
props:[
'parentmsg'
],
data(){
return{
}
}
}
}
由于子组件是无法访问到父组件中的data和methods
这个自定义属性parentmsg要在props数组中定义之后 才能使用
props数组中的数据都是父组件传递给自组件的
我们存放到props数组中 然后就可以访问父组件传过来的值了
这边补充一点;
1.data中的数据 是可读可写 props中的数据只能读,也就是子组件无法通过编写方法去改变props中的内容
2.子组件的data数据是组件私有的 不是父组件传递的
父组件向子组件传递方法
先从子组件开始:
创建组件 对应id是tmp1 在data中返回数据传递到父组件中,证明父子之间能够通信,
methods对象中,定义一个点击事件的方法,这个点击事件就是用来触发的时候 能够调用父组件的方法 实现通信
使用$emit()进行激活父组件的方法
var com1 = {
template:'#tmp1',
data(){
//组件的data传递给父组件
return{
sonmsg:{name:'子组件的data',age:6}
}
},
methods:{
myClick(){//点击按钮触发这个方法 进行调用父组件传过来的func ($emit()方法进行触发调用)
//调用父组件的方法 并向父组件传参 data-123
this.$emit('func',this.sonmsg)
}
}
}
子组件html代码:子组件的内容 并定义一个点击事件 用来触发父组件的show方法
<template id="tmp1">
<div>
<h3>这是子组件</h3>
<input type="button " value="子组件的按钮 点击触发父组件传过来的 func 方法"
@click="myClick">
</div>
</template>
接下来是父组件:父组件定义一个方法让子组件进行调用,并将子组件注册到自己的实例内部
var vm = new Vue({
el:'#app',
data:{
msg:'这是父组件内容 哈哈哈哈',
},
methods:{
show(data){
console.log('调用了父组件的show方法'+data)
console.log(data)
}
},
components:{
//引用组件
com1
}
})
父组件的html代码:这边采用自定义事件的方法 将自己内部的show方法存放到func中,func传到子组件中进行激活,
从而实现对父组件方法的调用
<div id="app">
<!-- 父组件向字组件传递方法 使用事件绑定事件 -->
<com1 @func="show"></com1>
</div>
组件的应用示例(评论列表)
代码的讲解都写在注释中!
引入bootstrap.css Vue.js
html代码:
<div id="app">
<!-- 父组件方法传给子组件进行调用 comtbox是父组件对子组件(commentBox)调用的时候的注册名-->
<!-- 定义func方法让子组件能够调用父组件的方法loadComments -->
<cmtbox @func="loadComments"></cmtbox>
<ul class="list-group">
<li class="list-group-item" v-for="item in list " :key="item.id">
<span class="badge">评论人:{{item.user}}</span>
{{item.content}}
</li>
</ul>
</div>
<!-- 子组件的内容 记得用div包裹起来 -->
<template id="tmp1">
<div>
<div class="form-group">
<label>
评论人:
</label>
<!-- v-model数据绑定 -->
<input type="text" class="form-control" v-model="user">
</div>
<div class="form-group">
<label>
评论内容:
</label>
<!-- v-model数据绑定 -->
<textarea class="form-control" v-model="content"></textarea>
</div>
<div class="form-group">
<!-- 定义点击事件 用于提交评论 -->
<input type="button" value="发表" class="btn btn-primary" @click="postComment">
</div>
</div>
</template>
子组件(commentBox)JS代码:
var commentBox = {
template:'#tmp1',
data(){
return{
user:'',
content:''
}
},
methods:{
postComment(){
var comment = {id:Date.now(),user:this.user,content:this.content}
//获取之前所有评论存放到cmts里面 如果取不到 则返回一个空数组 获取的结果转换成json对象
var List = JSON.parse(localStorage.getItem('cmts') || '[]')
//执行插入
List.unshift(comment)
//插入后 刷新保存的评论 序列化List字符串
localStorage.setItem('cmts',JSON.stringify(List))
//插入后 输入框置空
this.user = this.content =''
//触发func方法
this.$emit('func')
}
}
}
父组件(Vue)的JS代码
var vm = new Vue({
el:'#app',
data:{
list:[
{id:Date.now(),user:'关于我们',content:'大速度快安徽'},
{id:Date.now(),user:'客户案例',content:' 的缴纳时抠脚大汉阿鼠'},
{id:Date.now(),user:'合作加盟',content:'打卡机阿鼠和经典款好是的杀毒'},
{id:Date.now(),user:'联系我们',content:'大神带哦啊吗单'}
]
},
beforeCreate() {//这里不能调用loadComments方法,因为此时的data和methods都没被初始化
},
created() {
this.loadComments()
},
methods:{
//从本地的localStorage中加载评论列表
loadComments(){
//获取之前所有评论存放到cmts里面 如果取不到 则返回一个空数组 获取的结果转换成json对象
var List = JSON.parse(localStorage.getItem('cmts') || '[]')
this.list = List
}
},
components:{
cmtbox:commentBox
}
})
最终实现效果
组件间的通信和应用实例就讲到这里!
如果在过程中有任何不清楚或者有错误的,请在评论区进行留言!谢谢