一、组件间通信的分类
- 父子组件之间的通信
- 兄弟组件之间的通信
- 祖孙与后代组件之间的通信
- 非关系组件间之间的通信
二、组件间通信的方案
- 通过 props 传递
- 通过 $emit 触发自定义事件
- 使用 ref
- EventBus
- $parent 或$root
- attrs 与 listeners
- Provide 与 Inject
- Vuex
1、props传递数据
适用场景:父组件向子组件传值
Child.vue:
props:{
// 字符串形式
name:String // 接收的类型参数
// 对象形式
age:{
type:Number, // 接收的类型为数值
defaule:18, // 默认值为18
require:true // age属性必须传递
}
}
Father.vue
<Child name="jack" age=18 />
2、$emit触发自定义事件
适用场景:子组件传递数据给父组件。
在子组件中使用this.$emit(),第一个参数为自定义事件名,第二个参数为传递的数据。
<template>
<div class="home">
<h1>我是子组件</h1>
<h2 @click="change('武汉')">测试其emit组件</h2>
</div>
</template>
<script>
// @ is an alias to /src
export default {
methods: {
change(val) {
let data = {
msg: val,
};
this.$emit("showCityName", data);
},
},
};
</script>
在父组件中,在子组件的标签上绑定method,接收传递过来的参数。
<template>
<div class="hello">
<h2>我是父组件,我需要建立一些参数</h2>
<h3>我所在地的名称是:{{ msg }}</h3>
<span><mHome @showCityName="updateCityName" /></span>
</div>
</template>
<script>
import mHome from "@/views/Home.vue";
export default {
components: {
mHome,
},
data() {
return {
msg: "北京",
};
},
methods: {
updateCityName(data) {
this.msg = data.msg;
},
},
};
</script>
ref
在子组件的标签上加上ref,就可以通过$ref获取子组件。
<Children ref="foo" />
this.$refs.foo.xxx // 获取子组件实例,通过子组件实例我们就能拿到对应的数据,xxx为子组件中的data
此外,ref还可以用来获取页面的dom元素和调用子组件中的方法。
EventBus
- 使用场景:兄弟组件传值
- 创建一个中央时间总线EventBus
- 兄弟组件通过$emit触发自定义事件,$emit第二个参数为传递的数值
- 另一个兄弟组件通过$on监听自定义事件
初始化
//main.js
//方式一
Vue.prototype.$eventBus = new Vue();
//方式二
window.eventBus = new Vue();
触发事件
//使用方式一定义时
this.$eventBus.$emit('eventName', param1,param2,...)
//使用方式二定义时
eventBus.$emit('eventName', param1,param2,...)
监听事件
//使用方式一定义时
this.$eventBus.$on('eventName', (param1,param2,...)=>{
//需要执行的代码
})
//使用方式二定义时
eventBus.$on('eventName', (param1,param2,...)=>{
//需要执行的代码
})
移除事件
//使用方式一定义时
this.$eventBus.$off('eventName');
//使用方式二定义时
eventBus.$off('eventName');
$parent 或$ children
$parent可以获取父组件中的元素。
父组件
<template>
<div>
<h1>父组件</h1>
<h-child></h-child>
</div>
</template>
<script>
// 引入子组件
import HChild from './Child'
export default {
name: 'Parent',
components: {
HChild
},
data () {
return {
msg: 'data from parent'
}
},
methods: {
fun () {
console.log('parent fun')
}
}
}
</script>
子组件
<template>
<div>
<h1>子组件</h1>
<button @click="showParent">调用父组件的数据和方法</button>
</div>
</template>
<script>
export default {
name: 'Child',
methods: {
showParent () {
// 获取到所有的子组件
console.log(this.$parent)
// 获取指定子组件中的指定数据
console.log(this.$parent.msg)
// 调用子组件的方法
this.$parent.fun()
}
}
}
</script>
此外,通过共同父辈$parent可以建立兄弟组件之间的通信。(类似eventBus)
兄弟组件A:
this.$parent.on('add',this.add)
兄弟组件B:
this.$parent.emit('add')
$children可以获取子组件的数组,再获取其中的元素。
子组件
<template>
<div>
<h1>子组件</h1>
</div>
</template>
<script>
export default {
name: 'Child',
data () {
return {
msg: 'msg from child'
}
},
methods: {
fun () {
console.log('child fun')
}
}
}
</script>
父组件
<template>
<div>
<h1>父组件</h1>
<h-child></h-child>
</div>
</template>
<script>
// 引入子组件
import HChild from './Child'
export default {
name: 'Parent',
components: {
HChild
},
mounted () {
// 获取到所有的子组件,结果是一个数组
console.log(this.$children)
// 获取指定子组件中的指定数据
console.log(this.$children[0].msg)
// 调用子组件的方法
this.$children[0].fun()
}
}
</script>
$attrs 与$listeners
- 适用场景:祖先传递数据给子孙
- 设置批量向下传属性
$attrs
和$listeners
- 包含了父级作用域中不作为
prop
被识别 (且获取) 的特性绑定 ( class 和 style 除外)。 - 可以通过
v-bind="$attrs"
传⼊内部组件
$attrs包含了父组件传入的且没有在props中传入的数据,如果某一属性存在于props中,则会在$attrs中被移除。
// 父组件
<child-com class="com" name="attr" :foo="foo" :boo="boo" :coo="coo" :doo="doo" @click="test"></child-com>
...
data() {
return {
foo: 'Hello World!',
boo: 'Hello Javascript!',
coo: 'Hello Vue',
doo: 'Last'
}
},
...
// child-com.vue
export default {
name: 'childCom',
components: {
childCom2
},
created() {
console.log(this.$attrs) // {name: "attr", foo: "Hello World!", boo: "Hello Javascript!", coo: "Hello Vue", doo: "Last"}
}
}
provide 与 inject
- 在祖先组件定义
provide
属性,返回传递的值 - 在后代组件通过
inject
接收组件传递过来的值
祖先组件
provide(){
return {
foo:'foo'
}
}
后代组件
inject:['foo'] // 获取到祖先组件传递过来的值
vuex
适用于复杂关系的组件数据传递,类似于redux。
-
state
用来存放共享变量的地方 -
getter
,可以增加一个getter
派生状态,(相当于store
中的计算属性),用来获得共享变量的值 -
mutations
用来存放修改state
的方法。 -
actions
也是用来存放修改state的方法,不过action
是在mutations
的基础上进行。常用来做一些异步操作