父子通信
父组件主动向子组件传递数据
defineProps
父组件使用v-bind
绑定需要传递的数据,子组件从vue
中使用defineProps
,实例化对象进行接受
父组件
<template>
<Child :msg="parentMsg" />
</template>
<script setup>
import Child from './child.vue';
import { ref } from 'vue';
const parentMsg = ref('im parent')
</script>
<style lang="css" scoped></style>
子组件
<template>
<div>
{{ props.msg }}
</div>
</template>
<script setup>
const props = defineProps({
msg: {
type: String
}
})
</script>
<style lang="scss" scoped></style>
子父通信
子组件主动向父组件传递数据
发布订阅方式
采用了发布订阅的方式实现
首先子组件定义好一个事件
const emit = defineEmits(['addChild'])
定义好后,将该事件发布出去,我在这采用了一个点击事件触发发布时间的行为
const add = () => {
emit('addChild', childMsg.value)
}
最后在父组件对该事件进行订阅,订阅的事件名一定要和子组件发布的事件名一致,里面会传递一个参数,该参数就是子组件传递的数据。
<Child @addChild="handle" />
具体代码如下
child
<template>
<div>
<button @click="add">发送给父组件</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const childMsg = ref('im child')
const emit = defineEmits(['addChild'])
const add = () => {
emit('addChild', childMsg.value)
}
</script>
<style lang="scss" scoped></style>
parent
<template>
<Child @addChild="handle" />
{{ msg }}
</template>
<script setup>
import Child from './child.vue';
import { ref } from 'vue';
const msg = ref('')
const handle = (e) => {
msg.value = e
}
</script>
<style lang="css" scoped></style>
defineExpose+ref
使用了defineExpose
主动对外暴露,想要暴露的数据
defineExpose({
msg
})
父组件通过ref
定义子组件的dom
元素,从而从dom
元素中拿到挂载在该对象上的属性。注意由于这个过程是异步的第一次访问时这个值是不存在,所以需要在访问之前判断存不存否则会执行会出错。
<Child ref="refChild" />
{{ refChild?.msg }}
全部代码如下
child
<template>
<div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const msg = ref('im child')
defineExpose({
msg
})
</script>
<style lang="scss" scoped></style>
parent
<template>
<Child ref="refChild" />
{{ refChild?.msg }}
</template>
<script setup>
import Child from './child.vue';
import { ref } from 'vue';
const refChild = ref(null)
</script>
<style lang="css" scoped></style>
子父组件的双向数据绑定
双向数据绑定,实现vue3
数据不再是单向流通的
v-model
双向数据绑定主要使用了v-model
首先在父组件上选择好绑定的数据。
<Child v-model:msg="msg" />
对于子组件来说分两步走
第一点,子组件得到来自父组件传递的数据,使用defineProps
第二点,子组件使用defineEmits
,发布事件
const props = defineProps({
msg: {
type: String,
required: true
}
})
const emits = defineEmits(['update:msg'])
具体代码如下
parent
<template>
{{ msg }}
<Child v-model:msg="msg" />
</template>
<script setup>
import Child from './child.vue';
import { ref } from 'vue';
const msg = ref('im parent')
</script>
<style lang="css" scoped></style>
child
<template>
<div>
<input type="text" :value="props.msg" @input="changeMsg">
</div>
</template>
<script setup>
const props = defineProps({
msg: {
type: String,
required: true
}
})
const emits = defineEmits(['update:msg'])
const changeMsg = (e) => {
emits('update:msg', e.target.value)
}
</script>
<style lang="scss" scoped></style>
子孙通信
主要设计目的是用于祖先组件向后代组件单向传递数据,但如果有需求让后代组件向祖先组件传递数据
provide/inject
首先在父组件中使用provide
抛出想要传递的数据
provide('parentMsg', msg)
在孙组件中使用inject
接受即可
const msg = inject('parentMsg')
具体代码 parent
<template>
<Child />
</template>
<script setup>
import Child from './child.vue';
import { provide, ref } from 'vue';
const msg = ref('im parent')
provide('parentMsg', msg)
</script>
<style lang="css" scoped></style>
grandson
<template>
<div>
{{ msg }}
</div>
</template>
<script setup>
import { inject } from 'vue';
const msg = inject('parentMsg')
</script>
<style lang="scss" scoped></style>