父子间通信(props/$emit)
1.父组件向子组件传值
父组件通过绑定属性的方式向子组件传值,子组件通过props来接收。
父组件:
<template>
<div id="app">
<Child :msg="msg"/>
</div>
</template>
<script>
import Child from './components/Child.vue'
// 父组件通过绑定自定义属性来给子组件传值
export default {
name: 'App',
components: {
Child
},
data() {
return {
msg: 'hi, my child!'
}
}
}
</script>
子组件:
<template>
<div>
<div>子组件接收到父组件的信息:{{msg}}</div>
</div>
</template>
<script>
export default {
// 子组件通过props来接收父组件传递过来的值,props有以下两种写法:
// props: ['msg'],
props: {
msg: {
type: String,
defalut: ''
}
}
}
</script>
2.子组件向父组件传值
子组件绑定一个事件,通过this.$emit()
来触发;父组件通过v-on
来监听事件
子组件:
<template>
<div>
<button @click="toFather">点击发送信息给父组件</button>
</div>
</template>
<script>
export default {
data() {
return {
sonMsg: 'hello, father!'
}
},
methods: {
// 子组件绑定一个事件,通过this.$emit()来触发
toFather() {
this.$emit('toFather', this.sonMsg)
}
}
}
</script>
父组件:
<template>
<div id="app">
<Child @toFather="fatherHandle"/>
<p>父组件接收到子组件传递过来的信息: {{sonMsg}}</p>
</div>
</template>
<script>
import Child from './components/Child.vue'
// 父组件通过v-on监听事件
export default {
name: 'App',
components: {
Child
},
data() {
return {
sonMsg: ''
}
},
methods: {
fatherHandle(msg) {
// 子组件传递过来的值
this.sonMsg = msg
}
}
}
</script>
兄弟组件间通信
事件总线($emit/$on)
- 创建事件中心管理组件组件的通信EventBus.js:一个空的Vue实例,用来传递和接收事件。
import Vue from 'vue'
export default new Vue()
- 发送的组件
在要传值的组件导入这个事件中心,绑定事件并通EventBus.$emit()
来触发
<template>
<div>
<button @click="add">加1</button>
</div>
</template>
<script>
// 发送组件导入事件中心,绑定事件并通过$emit()来触发事件
import EventBus from './EventBus'
export default {
data() {
return {
count: 0
}
},
methods: {
add() {
this.count++
EventBus.$emit('add', this.count)
}
}
}
</script>
- 接受的组件
在接受的组件中导入这个事件中心,通过EventBus.$on()
来监听回调
<template>
<div>
<div>num: {{num}}</div>
</div>
</template>
<script>
// 在接受组件导入事件中心,通过$on()来监听回调
import EventBus from './EventBus'
export default {
data() {
return {
num: 0
}
},
created() {
EventBus.$on('add', count => {
this.num = count
})
}
}
</script>
跨组件间通信
依赖注入(provide/inject)
Vue的依赖注入可以实现很深层次的通信。provide和inject是Vue提供的两个钩子,和data、methods同级。
provide
钩子用来发送数据或方法;inject
钩子用来接受数据和方法。
注意: 依赖注入所提供的属性是非响应式的
祖先组件:
<template>
<div id="app">
<Child/>
</div>
</template>
<script>
import Child from './components/Child.vue'
export default {
name: 'App',
// provide钩子用来发送数据或方法
provide() {
return {
// Fname: 'father datas'
app: this,
}
},
components: {
Child,
},
data() {
return {
msg: 'hi, my child!',
}
},
}
</script>
后代组件:
<template>
<div>
<!-- <div>Fname:{{Fname}}</div> -->
<div>{{app.msg}}</div>
</div>
</template>
<script>
export default {
// inject钩子用来接收数据或方法
// inject: ['Fname'],
inject: ['app'],
}
</script>
ref/$refs
ref
属性用在子组件上, 它的引用就指向了子组件的实例。可以通过实例来访问组件的数据和方法。
子组件:
<template>
<div></div>
</template>
<script>
export default {
data() {
return {
name: 'ref of children'
}
},
methods: {
sayHi() {
console.log('hi, father!')
}
}
}
</script>
父组件:
<template>
<div id="app">
<div>refName: {{refName}}</div>
<Ref ref="childRef"/>
</div>
</template>
<script>
import Ref from './components/Ref.vue'
export default {
name: 'App',
components: {
Ref,
},
data() {
return {
refName: ''
}
},
mounted() {
// 通过Vue实例来访问组件的数据和方法
this.refName = this.$refs.childRef.name,
this.$refs.childRef.sayHi()
},
}
</script>
$parent/$children
- 使用
$parent
可以让组件访问父级的实例(是上一级的父级),值是一个对象 - 使用
$children
可以让组件拿到所有子组件的实例,它的值是一个无序的数组,且访问的数据也不是响应式的
子组件:
<template>
<div>
</div>
</template>
<script>
export default {
data() {
return {
sonMsg: 'hello, father!'
}
},
mounted() {
// this.$parent可以访问上一级的实例,值为一个对象
console.log(this.$parent.msg); // hi, my child!
},
}
</script>
父组件:
<template>
<div id="app">
<Child/>
</div>
</div>
</template>
<script>
import Child from './components/Child.vue'
export default {
name: 'App',
components: {
Child,
},
data() {
return {
msg: 'hi, my child!',
}
},
mounted() {
// this.$chiildren拿到所有的子组件实例,值为一个无序的数组
console.log(this.$children);
},
}
</script>
$attrs/$listeners
$attrs/$listeners
实现组件的跨代通信
inheritAttrs
,它默认是true,继承所有父组件除了props之外的所有属性值;设置为false,就只继承class属性。$attrs
:包含了父组件除了props绑定之外的属性(calss和style也除外),作用于子组件,通过v-bind="$attrs"
传入组件内;$listeners
: 包含了父组件中的v-on监听器(除了.native修饰的),作用与子组件,通过v-on="$listeners"
传入组件内
祖父组件:
<template>
<div id="app">
<AttrsChild :msg="msg" msg2="grandSon接收的信息" :obj="obj" @parentHadel="grandParentHandel"/>
</div>
</template>
<script>
import AttrsChild from './components/attrsChild.vue'
export default {
name: 'App',
components: {
AttrsChild
},
data() {
return {
msg: 'I am props datas',
obj: {
name: 'limi',
age: 25,
}
}
},
mounted() {
},
methods: {
grandParentHandel() {
console.log('我是祖父事件');
}
}
}
</script>
<style>
</style>
父组件:
<template>
<div>
<Son v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
import Son from './atrrsSon.vue'
// $attrs:包含所有父级除了props绑定的属性,
// $listeners: 包含所有父级除了.native修饰的v-on事件监听
export default {
components: {
Son
},
props: ['msg'],
// inheritAttrs: false, // 只继承class
created() {
this.$emit('parentHadel') // 我是祖父事件
console.log(this.msg, '----msg'); // I am props datas ----msg
console.log(this.$attrs,'----this.$attrs'); // obj: { name: 'limi', age: 25 }
}
}
</script>
<style>
</style>
孙子组件:
<template>
<div>
</div>
</template>
<script>
export default {
props: ['msg2'],
inheritAttrs: false, // 只继承class
created() {
this.$emit('parentHadel') // 我是祖父事件
console.log(this.msg2, '---msg2'); // grandSon接收的信息 ---msg2
console.log(this.$attrs,'----this.$attrs'); // obj: { name: 'limi', age: 25 }
}
}
</script>
<style>
</style>