Vue3在script setup标签中进行父子组件的通信

父组件

在父组件中定义添加和删除函数,并且传递给子组件

<div>
     <Input @add="handleAdd" />
     <List :list="state.list" @delete="handleDelete" />
</div>
<script setup>
import Input from './Input.vue';
import List from './List.vue'
import { reactive } from 'vue';

//这里定义响应式数组的时候要注意要定义在reactive内部,不然直接修改list后就会失去响应式
const state = reactive({
    list:[
    {
        id: '1',
        title: '标题1'
    },
    {
        id: '2',
        title: '标题2'
    },
]
});
//通过state.list添加数据
const handleAdd = (title) => {
    state.list.push({
        id: `id-${Date.now()}`,
        title
    })
}

const handleDelete = (id) => {
    state.list = state.list.filter(item => item.id !== id)
}

</script>

子组件

Input.vue

<input type="text" v-model="title" id="input1" @keyup.enter.native = addTitle>
<button class="plus" @click=addTitle>add</button>
<script setup>
import { ref } from 'vue'

const title = ref('')
//通过difineEmits获取add函数,并向父组件传值
const emit = defineEmits(['add'])
const addTitle = () => {
    emit('add', title.value);
    title.value = '';
}

defineExpose({
    title,
    deleteLi
})
</script>

List.vue

<ul>
   <li v-for="item in props.list" :key="item.id">{{ item.title }}
       <button @click="deleteLi(item.id)">delete</button>
   </li>
</ul>
//在script setup标签中props变更为了defineProps
const props = defineProps({
    list: {
        type: Array,
        default() {
            return []
        }
    }
})
const emit = defineEmits(['delete'])
const deleteLi = (id) => {
    emit('delete', id)
}
//将函数暴露出来
defineExpose({
    deleteLi,
})

Vue3父子组件通信有以下三种方式: 1. 父组件给子组件传参: 父组件通过props向子组件传递数据,子组件通过props接收数据。 2. 子组件调用父组件的方法: 父组件通过v-on绑定一个方法,子组件通过$emit触发这个方法,并传递数据。 3. 子组件暴露属性给父组件: 子组件通过defineExpose暴露属性或方法,父组件通过ref获取子组件实例,再调用子组件的属性或方法。 以下是三种方式的代码示例: 1. 父组件给子组件传参: 父组件: ```vue <template> <child-component :message="msg"></child-component> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, data() { return { msg: 'Hello World', }; }, }; </script> ``` 子组件: ```vue <template> <div>{{ message }}</div> </template> <script> export default { props: { message: String, },}; </script> ``` 2. 子组件调用父组件的方法: 父组件: ```vue <template> <child-component @change-visible="handleChangeVisible"></child-component> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, methods: { handleChangeVisible(visible) { console.log(visible); }, }, }; </script> ``` 子组件: ```vue <template> <button @click="handleClick">Change Visible</button> </template> <script> export default { methods: { handleClick() { this.$emit('change-visible', false); }, }, }; </script> ``` 3. 子组件暴露属性给父组件: 子组件: ```vue <template> <div>{{ message }}</div> </template> <script> import { defineExpose } from 'vue'; export default { setup() { const message = 'Hello World'; defineExpose({ message, }); return { message, }; }, }; </script> ``` 父组件: ```vue <template> <child-component ref="child"></child-component> </template> <script> import ChildComponent from './ChildComponent.vue'; export default { components: { ChildComponent, }, mounted() { console.log(this.$refs.child.message); }, }; </script> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值