Vue组件化编程的组件通信
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
对于组件化编程组件之间的通信技术无疑是非常重要的内容需要将细节牢牢把握。
组件通信就是子组件放置在父组件内之后父组件如何向子组件传递参数以及子组件如何与外部组件进行互动。
这部分的知识很重要需要展开一一掌握分下面的三种情况进行逐一说明。当然考虑到组件通信的复杂后面我写一篇很简单的组件通信不必考虑父子组件的区别。
1、父组件向子组件的多种传值方式
演示代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue.js的组件化编程组件通信</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<h1>父组件向子组件传值</h1>
<div id="app">
<my-componect my-title="组件标题1" my-content="组件内容1"></my-componect>
<my-componect v-bind:my-title="'组件标题2'" :my-content="'组件内容2'"></my-componect>
<my-componect v-bind:my-title="item.title" :my-content="item.content"></my-componect>
</div>
<script type="text/javascript">
Vue.component("myComponect",{
props:['myTitle','myContent'],
template:`<div>
<h3>{{myTitle}}</h3>
<h6>{{myContent}}</h6>
</div>`
});
var vm=new Vue({
el:"#app",
data:{
item:{
title:'组件标题',
content:'组件内容'
}
}
});
</script>
</body>
</html>
显示结果
父组件可以有3种方法向子组件传递数据子组件的props接收的是数组可以接收多个参数。
⑴ 直接传字符串是静态文本
⑵ 传JavaScript表达式
⑶ 传对象属性值
⑷ 传对象。
注意点
⑴ props与父组件的data命名最好不要相同。
⑵ v-bind: title可以简写为:title。
传JavaScript表达式或者对象可以看下面的例子。
网页代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue.js的组件化编程组件通信</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<h1>父组件向子组件传值</h1>
<div id="app">
<my-componect :my-data=" { title:'这是组件标题',content:'这是组件内容'}"></my-componect>
<my-componect :my-data="item"></my-componect>
<my-componect :my-data="item"></my-componect>
</div>
<script type="text/javascript">
Vue.component("myComponect",{
props:['myData'],
template:`<div>
<h3>{{myData.title}}</h3>
<input type="text" v-model="myData.content" />
</div>`
});
var vm=new Vue({
el:"#app",
data:{
item:{
title:'组件标题',
content:'组件内容'
}
}
});
</script>
</body>
</html>
显示结果
可以看出如果是以对象的方式进行传值那么当对象的属性改变时子组件的内容也会发生改变其实这也可以作为子组件向外传值的一种方式就是引用方式传值。
2、子组件向父组件传值以及子组件调用父组件的方法函数
结合上面父组件向子组件传递对象练习下面的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue.js的组件化编程组件通信</title>
<script src="./js/vue2.js"></script>
</head>
<body>
<div id="app">
<my-score-sheet v-for="cla in classList" :my-class="cla" :key="cla.id" @data-change="averageFunc"></my-score-sheet>
<p align="center"><b>学校数学总平均分{{averageMaths}}学校语文总平均分{{averageChinese}}</b></p>
</div>
<script type="text/javascript">
Vue.component("myScoreSheet",{
props:['myClass'],
data(){
return {
classSign:{
id:0,
name:'',
students:[],
},
averageMaths:0.0,
averageChinese:0.0
}
},
created() {
this.classSign = this.myClass;
},
template:`<div>
<h1 align="center">{{classSign.name}}</h1>
<table align="center">
<tr align="center">
<td>学号</td>
<td>姓名</td>
<td>语文</td>
<td>数学</td>
</tr>
<tr v-for="student in classSign.students" :key="student.id">
<td>{{student.id}}</td>
<td>{{student.name}}</td>
<td ><input type="number" v-model="student.maths" @input="dataChange()"/></td>
<td ><input type="number" v-model="student.chinese" @input="dataChange()"/></td>
</tr>
</table>
<p align="center">班级数学平均分{{averageMaths}}班级语文平均分{{averageChinese}}</p>
</div>`,
methods:{
dataChange(){
let sumMaths=0.0;
let sumChinese=0.0
this.classSign.students.forEach(element=>{
sumMaths+=parseFloat(element.maths);
sumChinese+=parseFloat(element.chinese);
});
this.averageMaths=sumMaths/Object.keys(this.classSign.students).length;
this.averageChinese=sumChinese/Object.keys(this.classSign.students).length;
this.averageMaths=Math.round(this.averageMaths*100)/100;//保留两位小数
this.averageChinese=Math.round(this.averageChinese*100)/100;//保留两位小数
// this.$emit('data-change',this.classSign);
this.$emit('data-change');//调用父组件的方法函数
}
}
});
var vm=new Vue({
el:"#app",
data:{
classList:[
{ id:1,name:'学霸班',students:[{id:1001,name:'小明',maths:97,chinese:89},{id:1002,name:'小华',maths:83,chinese:91},{id:1003,name:'小黄',maths:75,chinese:86}] },
{ id:2,name:'青云班',students:[{id:2001,name:'小宋',maths:87,chinese:82},{id:2002,name:'小丽',maths:81,chinese:84},{id:2003,name:'小云',maths:82,chinese:89}] }
],
averageMaths:0.0,
averageChinese:0.0
},
methods:{
averageFunc(){
let studentCount=0;
let sumMaths=0.0;
let sumChinese=0.0
this.classList.forEach(element => {
element.students.forEach(student => {
sumMaths+=parseFloat(student.maths);
sumChinese+=parseFloat(student.chinese);
studentCount+=1;
});
});
this.averageMaths=sumMaths/studentCount;
this.averageChinese=sumChinese/studentCount;
this.averageMaths=this.averageMaths.toFixed(2);
this.averageChinese=this.averageChinese.toFixed(2);
}
}
});
</script>
</body>
</html>
输出结果
说明
⑴ 子组件调用父组件通过this.$emit('data-change')来完成当然也可以传递参数给父组件比如
this.$emit('data-change',this.classSign)
那么父组件的函数就应该定义为
dataChange(cla){}
其中的cla就表示this.classSign。
⑵ 子组件在准备了props和data后在created中进行对象的绑定
this.classSign = this.myClass;
因为是引用传值那么在子组件中的数据改变也同步到了父组件的classList中。
⑶ 子组件的数据定义classSign内部的学生数据定义为students:[]在进行数据绑定的时候就接收了父组件传来的学生列表。
⑷ 保留两位小数的函数
Math.round(this.averageMaths*100)/100
或者
this.averageMaths.toFixed(2)
⑸ 数组的统计长度Object.keys(this.classSign.students).lengththis.classSign.students是数组名称。
3、平行组件之间的通讯通过emit结合$refs进行。
具体的内容在《Vue组件化编程的基础知识要点》中有详细记录。
通过上面的总结可能会觉得Vue.js中组件化编程比较麻烦这么多内容其实如果深入思考完全不是这么一回事情可以简单明了地抛开上面的技术细节。
说到底就是自定义事件和事件队列这个思想与传统的C/S下的组件化编程几乎是相同的想明白了这一点组件通信就比较容易了。
后面会进行总结。