1.父组件传子组件
1.1 父组件
<!-- list为父组件数据 -->
<child-components :list="list"></child-components>
1.2 子组件
<template>
<ul>
<li v-for="i in props.list" :key="i">{{ i }}</li>
</ul>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
list: {
type: Array,
default: () => [],
},
})
</script>
2.子组件传父组件
2.1 子组件
const emits = defineEmits(['add'])
emits('add', 1)
2.2 父组件
<!-- add是子组件要传递的动作,handleAdd是监听到之后执行的事件 -->
<child-components @add="handleAdd"></child-components>
<script>
const list = ref([1,2,3])
const handleAdd = value => {
list.value.push(value)
}
</script>
3. V-model双向绑定
3.1 父组件
<ChildComponent v-model:state="list" />
// 等价于
<ChildComponent :state="pageTitle" @update:list="list = $event" />
3.2 子组件
1.子组件需要emit
一个叫update:xxx
的事件,再把需要更新的响应式数据传给emit方法的第二个参数
const emits = defineEmits(['update:list'])
emits('update:list', arr)
2.利用 computed
简化父子组件双向数据绑定
// 接收父组件传的数据
const props = defineProps({
state: Object,
})
const emits = defineEmits(['update:state'])
const stateNew = computed({
get() {
return props.state
},
set(val) {
emits('update:state', val)
},
})
4. 通过refs获取组件属性和方法
Vue3不同于Vue2,在 Vue3的setup
中我们是无法访问到this
,所以我们需要借助一个方法,那就是getCurrentInstance
,该方法返回了当前的实例对象
4.1 父组件
<template>
<div>
<Child ref="child"></Child>
<button @click="show">Show Child Message</button>
</div>
</template>
<script setup>
import { getCurrentInstance } from '@vue/runtime-core';
import Child from './Child.vue';
const currentInstance = getCurrentInstance()
function show() {
currentInstance.refs.child.alertMessage()
}
</script>
4.2 子组件
注意⚠️,通过
<script setup>
语法糖的写法,其组件是默认关闭的,也就是说如果是通过refs
或者parents
来访问子组件中定义的值是拿不到的,必须通过defineExpose
向外暴露你想获取的值才行。
<template>
<div>
<h1>{{ message }}</h1>
</div>
</template>
<script setup>
import { ref } from '@vue/reactivity';
let message = ref('我是子元素').value
const alertMessage = function () {
alert(message)
}
defineExpose({
message,
alertMessage
})
</script>
5. provide/inject
// 父组件中
provide('list', list.value)
// 子组件中
const list = inject('list')
版权声明:《 Vue3父子组件通信【补充】 》为胡光喆原创文章,转载请注明出处!
最后编辑:2022-10-18 06:10:17