平行组件、父子、子父之间的值传递都可以使用中间对象来传递值,有些地方成为公交车对象,其原理就是将要传递的值放在一个单独的对象上,要接受的地方从这个单独的对象上去接受。其中主要用到一个独立的Vue
对象、$emit
和$on
方法
-
vm.$emit( eventName, […args] )
-
参数:
{string} eventName
[...args]
触发当前实例上的事件。附加参数都会传给监听器回调。
-
-
vm.$on( event, callback )
-
参数:
-
{string | Array<string>} event
(数组只在 2.2.0+ 中支持) {Function} callback
-
-
用法:
监听当前实例上的自定义事件。事件可以由
vm.$emit
触发。回调函数会接收所有传入事件触发函数的额外参数。
详情参见……
-
代码案例如下:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-10 col-lg-offset-1">
<div class="panel panel-default" id="app">
<div class="panel-heading">
<div class="panel-title">APP父组件</div>
</div>
<div class="panel-body">
<blockquote>
<p>接收其他组件传来的值</p>
<!--其他组件传来的值-->
<footer>值为:<cite title="Source Title">{{other_info}}</cite></footer>
</blockquote>
<div class="row">
<div class="col-lg-4">
<Com1></Com1>
</div>
<div class="col-lg-4">
<Com2></Com2>
</div>
<div class="col-lg-4">
<Gcom></Gcom>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 声明一个公共vue对象(公交车),用来作为传递的中介
let bus = new Vue();
// 定义一个全局子组件
Vue.component('Gcom', {
data:function () {
return {
gcom_info:'Gcom组件中的信息',
// 用来接收其他组件传来的值
other_info:''
}
},
template:`
<div class="panel panel-danger">
<div class="panel-heading">
<div class="panel-title">Gcom全局子组件</div>
</div>
<div class="panel-body">
<blockquote>
<p>接收其他组件传来的值</p>
<footer>值为:<cite title="Source Title">{{other_info}}</cite></footer>
</blockquote>
{{gcom_info}}<br>
<button class="btn btn-danger" v-on:click="Pass">Gcom向其他组件传值</button>
</div>
</div>
`,
methods:{
Pass:function () {
// 向bus对象pass_value事件传值
bus.$emit('pass_value', this.gcom_info)
}
},
created:function () {
//监听bus对象pass_value事件,并接受传来的值
bus.$on('pass_value', (val)=> {
this.other_info = val
})
}
})
//定义一个局部组件com1
let Com1={
data:function () {
return {
com1_info:'Com1组件信息',
// 用来接收其他组件传来的值
other_info:''
}
},
template:`
<div class="panel panel-primary">
<div class="panel-heading">
<div class="panel-title">Com1子组件</div>
</div>
<div class="panel-body">
<blockquote>
<p>接收其他组件传来的值</p>
<footer>值为:<cite title="Source Title">{{other_info}}</cite></footer>
</blockquote>
{{com1_info}}<br>
<button class="btn btn-primary" v-on:click="Pass">Com1向其他组件传值</button>
</div>
</div>
`,
methods:{
Pass:function () {
// 向bus对象pass_value事件传值
bus.$emit('pass_value', this.com1_info)
}
},
created:function(){
//监听bus对象pass_value事件,并接受传来的值
bus.$on('pass_value', (val)=> {
this.other_info = val
})
}
}
//定义一个局部组件com2
let Com2={
data:function () {
return {
com2_info:'Com2组件信息',
// 用来接收其他组件传来的值
other_info:''
}
},
template:`
<div class="panel panel-warning">
<div class="panel-heading">
<div class="panel-title">Com2子组件</div>
</div>
<div class="panel-body">
<blockquote>
<p>接收其他组件传来的值</p>
<footer>值为:<cite title="Source Title">{{other_info}}</cite></footer>
</blockquote>
{{com2_info}}<br>
<button class="btn btn-warning" v-on:click="Pass">Com2向其他组件传值</button>
</div>
</div>
`,
methods:{
Pass:function () {
// 向bus对象pass_value事件传值
bus.$emit('pass_value', this.com2_info)
}
},
created:function () {
//监听bus对象pass_value事件,并接受传来的值
bus.$on('pass_value', (val)=>{
this.other_info = val
})
}
}
// 父组件app
new Vue({
el:'#app',
data:function () {
return {
app_user:{
name:'孙悟空',
age:529
},
// 用来接收子组件传来的值
other_info:''
}
},
// 挂载子组件、全局组件不用挂载
components:{
Com1,
Com2
},
created:function () {
//监听bus对象pass_value事件,并接受传来的值
bus.$on('pass_value', (val)=>{
this.other_info = val;
})
}
});
</script>
</body>
</html>
效果图如下: