<template> <div> <p>我是子组件:一个按钮</p> <button @click="clickCallback"> 修改父组件的名称为:彭湖湾的组件 </button> </div> </template> <script> export default { data: function () { return { fatherComponentName: '彭湖湾的组件' } }, methods: { clickCallback: function () { this.$emit('changeComponentName', this.fatherComponentName) } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
demo:
点击前:
点击后:
图解:
通过$emit(event, [...参数]),所有的参数将被传递给监听器回调,也就是我们在父组件中定义的changeComponentName方法,从而实现从子组件中给父组件传参
兄弟组件间的数据交流(有共同父组件的兄弟组件)
父组件:
<template> <div> <div> {{ '我是父组件:father' }} <eldest-son :text = "text"></eldest-son> <youngest-son :changeText="changeText"></youngest-son> </div> </div> </template> <script> import eldestSon from './eldestSon.vue' import youngestSon from './youngestSon.vue' export default { data: function () { return { text: '我是一行文本' } }, methods: { changeText: function () { this.text = '我是经过改动的一行文本' } }, components: { eldestSon: eldestSon, youngestSon: youngestSon } } </script> <style> #father div{ border: 1px solid grey; padding: 10px; margin: 10px; } </style>
兄弟组件1:
<template> <div> <p>我是兄弟组件:eldestSon</p> <p>我有一个可变数据text:{{ text }}</p> </div> </template> <script> export default { props: { text: { type: String, default: '' } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
兄弟组件2:
<template> <div> <p>我是兄弟组件:youngestSon</p> <button @click="changeText">更改eldestSon兄弟组件中的文本</button> </div> </template> <script> export default { props: { changeText: { type: Function, default: () => {} } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> </style>
点击前:
点击后:
图解:
如果两个兄弟组件间存在这种数据关系的话,我们可以尝试寻找其共同的父组件,使数据和相关方法“提升”到父组件内部,并向下传给两个子组件
这样,其中一个子组件取得了数据,另外一个子组件取得了改变数据的方法,便可以实现上述的数据沟通
【注意】这种场景存在局限性,它要求两个组件有共同父组件。对于这种场景之外的处理方法,请看下文
全局组件间的数据交流——Vuex
我上述的许多场景里面,都运用到了props或者函数传参的方式去处理组件间的数据沟通。然而在稍大型的应用里面,它们都不约而同地给我们带来了很大的麻烦
例如:
1.通过props从父组件向子组件传递数据
对于直接的父子关系的组件,数据流显得很简洁明确,但在大型应用里面,我们上下嵌套许多个组件的时候,这就会导致我们的代码非常地繁琐,并难以维护
2.对于没有共同的父组件的兄弟组件,函数传参的数据传递方式也无能为力了,Vue文档里介绍到,你可以通过以$emit和$on函数为基础的“事件总线”沟通数据,但它无法应对更加大型的应用
这个时候Vuex就成为了实现全局组件间数据交流的最佳方案了
Vuex拥有一个包含全部顶层状态的单一数据源(state)
1.所有的组件都可以使用这个单一数据源里面的数据
2.所有的组件都可以通过派发 动作(actions)修改这个单一数据源里的数据
原本要“走很多弯路”才能实现沟通的数据流,一下子就找到了最短的捷径
实现View层的数据和model层的解耦