如果两个组件是父子关系,就可以通过props的方式传值。
父组件通过props向子组件传值,子组件通过事件触发向父组件传值
那么如果两个组件之间不具备父子关系,该如何传值呢?任何一个网页都可以拆分成几个部分,或者是几个组件,like this:1和3,3和3组件传值应该怎么传呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>非父子组件传值问题(Bus/总线/观察者模式)</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<!--父组件通过props向子组件传值,子组件通过事件触发向父组件传值-->
<body>
<div id="app">
<child content="Dell"></child>
<child content="Lee"></child>
</div>
</body>
</html>
<script>
// 每一个由Vue实例创建的组件都有bus
Vue.prototype.bus = new Vue()
// 子组件不能修改父组件的值,所以再定义一个变量承接父组件传来的content
Vue.component('Child', {
data: function () {
return {
selfContent: this.content
}
},
props: {
content: String
},
template: '<div @click="handleClick">{{selfContent}}</div>',
methods: {
handleClick: function () {
alert('click:' + this.selfContent)
this.bus.$emit('change', this.selfContent)
}
},
// 监听bus的改变,组件被挂载时
mounted: function () {
var _this = this;
this.bus.$on('change', function (msg) {
alert('bus:' + msg)
_this.selfContent = msg
})
}
})
var vm = new Vue({
el: '#app'
})
</script>
发布订阅模式【总线机制】
······这个例子是,点击Dell,将Dell传给下面的子组件,点击Lee,将Lee传给上面的子组件,实现非父子组件之间的传值。
······在子组件中定义一个点击事件,在点击事件的方法中用bus发出change事件,并将父组件传来的值传入。此时,通过vue的生命周期钩子mounted来监听change事件并且传值
······我在handle click方法和mounted方法中都写了alert,点击Dell之后,会弹出三个提示框,分别是click:Dell、bus:Dell、bus:Dell,在弹出第三个提示框之后,Lee变成了Dell。这是什么意思呢?首先,点击Dell会触发handle click方法,alert(click:Dell),然后由bus发出change事件,并且携带了content值(也就是Dell)。然后mounted中的bus.$on监听到change事件,会发出alert(bus Dell),因为页面的两个组件都有bus,所以,会发出两次alert,每一次alert之后都有一句_this.selfContent = msg,所以就会把msg携带的Dell覆盖掉原来的self_content。That’s all.
需要回顾的知识就是mounted,mounted只会执行一次,在html已经渲染到页面之后,也就是组件都挂载完成之后,会执行一次mounted中定义的事件,一半执行的是Ajax操作。