三种简洁易行的方法解决基于Vue.js的组件通信

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

  在总结Vue组件化编程的数据通信方面看了网上的很多资料都是讲父子组件的数据交互也就是参数传递在组件的通信方面分几种情况比如父子组件、非父子的兄弟组件、非父子的其他组件等等这样看来基于Vue.js的组件通讯非常繁琐。

  可是我们在C/S下的组件通信并没有这些麻烦通常情况下我们怎样设计组件通信

  在组件上声明事件可以是截获系统事件的也可以是自定义事件在这个事件中我们就可以对外进行数据通信。

  沿着这个思路就可以解决Vue组件化编程的组件通信很简单了。

  另外在Windows中的消息队列中我们也可以通过捕获事件的方式来得到组件的操作和数据也同样可以实现Vue组件化编程的组件通信。

  最简单的当然是组件中的数据直接对外进行数据绑定这样也就可以实现组件通信了。

  所以总结基于Vue.js的组件通信比较简单易用的三种方式通过数据绑定与数据监听、通过组件的自定义函数事件、通过事件捕获

  下面针对这三种情况分别举例说明。

  用于演示的基本数据结构

personList:[
    {name:'小明',score:97},
    {name:'小丽',score:88},
	{name:'小英',score:95},
]

  假设现在需要计算score的总和并且总分也要随着这些分数值的变化而变化。

  1、通过数据绑定与数据监听

  首先在Vue实例的data中定义用于计算总和的数据项total以及personList再定义组件放置姓名和分数input输入框然后组件的数据项与personList绑定最后监听personList数据变化就可以得到总和并且每个input框的分数变化后总分也随之变化。

  完整网页代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue.js的组件化编程组件通信</title>
		<script src="./js/vue2.js"></script>
	</head>
	<body>
		<div id="app">
			<h2>人员表</h2>
			<my-person v-for="(p,index) in personList" :key="index" :my-person="personList[index]"></my-person>
			<p>总分{{ total }}</p>
		</div>
		<script type="text/javascript">
			Vue.component("myPerson",{
				props:['myPerson'],
				template:`<div>
						姓名{{ myPerson.name }}
						分数<input type="number" v-model="myPerson.score"/>
					</div>`,
			});
			var vm=new Vue({
				el:"#app",
				data:{
					total:0,
					personList:[
						{name:'小明',score:97},
						{name:'小丽',score:88},
						{name:'小英',score:95},
					]
				},
				methods:{
					ScoreChange(){
						this.total = this.personList.reduce((prev, curr) => {
							return parseInt(prev) + parseInt(curr.score)
						}, 0)
					}
				},
				watch:{
					personList:{
						handler:'ScoreChange',
						deep:true,//深度监听
						immediate:true,//有初始值
            		}
				}
			});
		</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">
			<h2>人员表</h2>
			<my-person :my-name="'小明'" :my-score="'99'"  ref="S1"></my-person>
			<my-person :my-name="'小丽'" :my-score="'87'"  ref="S2"></my-person>
			<p>总分{{total}}</p>
		</div>
		<script type="text/javascript">
			Vue.component("myPerson",{
				props:['myName','myScore'],
				data(){
					return {
							person:{
								name:"",
								score:0
							}
					}
				},
				mounted() {
					this.person.name=this.myName;
					this.person.score=this.myScore;
				},
				template:`<div>
						姓名{{ person.name }}
						分数<input type="number" v-model="person.score" @input="dataChange()"/>
					</div>`,
				methods:{
					dataChange(){
						this.$parent.total=parseInt(this.$parent.$refs.S1.person.score) + parseInt(this.$parent.$refs.S2.person.score);
					}
				}
			});
			var vm=new Vue({
				el:"#app",
				data:{
					total:0
				}
			});
		</script>
	</body>
</html>

  输出结果

  说明

  ⑴ 数据绑定可以在created或者mounted中进行

  ⑵ 绑定的时候不能少写this否则会提示找不到数据项

  ⑶ 关键在事件中的处理即this.$parent.$refs包含了组件数据所以在放置组件的时候要写ref属性值不能重复。

  3、通过事件捕获

  直接叙述就是声明另外一Vue实例进行事件挂载与事件捕获就是组件的事件在Vue实例上进行注册在另外组件上需要处理的时候就捕获这个事件即可。

  完整的代码示例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Vue.js的组件化编程组件通信</title>
		<script src="./js/vue2.js"></script>
	</head>
	<body>
		<div id="app">
			<h2>人员表</h2>
			<my-person :my-name="'小明'" :my-score="'99'"  ref="S1"></my-person>
			<my-person :my-name="'小丽'" :my-score="'87'"  ref="S2"></my-person>
			<my-total></my-total>
		</div>
		<script type="text/javascript">
			eventBus=new Vue();
			Vue.component("myPerson",{
				props:['myName','myScore'],
				data(){
					return {
							person:{
								name:"",
								score:0
							}
					}
				},
				mounted() {
					this.person.name=this.myName;
					this.person.score=this.myScore;					
				},
				template:`<div>
						姓名{{ person.name }}
						分数<input type="number" v-model="person.score" @input="myDataChange()"/>
					</div>`,
				methods:{
					myDataChange(){
						eventBus.$emit('DataChange',this.person);						
					}
				}
			});

			Vue.component("myTotal",{
				data(){
					return {
						total:0,
						personList:[]
					}
				},
				mounted() {
					eventBus.$on('DataChange',(p)=>{
						this.total=0;
						if( !this.personList.find(obj=>obj.name==p.name) ){
							this.personList.push(p);
						}
						this.personList.forEach(element => {
							this.total+=parseInt(element.score);
						});							
					})
				},
				template:`<div>总数{{ total }}</div>`
			});
			var vm=new Vue({
				el:"#app"
			});
		</script>
	</body>
</html>

  结果输出

   说明

  ⑴ 需要声明另外一个Vue实例名称可以根据自己需要设定

  ⑵  组件的数据绑定可以在created或者mounted中进行

  ⑶ 组件的事件触发eventBus.$emit('DataChange',this.person)DataChange可以被其他组件进行捕获处理

  ⑷ 其他组件捕获事件

eventBus.$on('DataChange',(p)=>{
    //p是传递过来的参数
    //......
})

  原来Vue组件的数据通信这么简单

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: vue