1、props/$emit
父传子 使用props
//父组件
<template>
<childrenComp :arr="arr" />
<input type="text" v-model="data" />
<button @click="handleAdd">添加</button>
</template>
<script setup>
import { ref } from 'vue';
import childrenComp from '@/components/children-comp.vue';
const data = ref('');
const arr = ref([]);
const handleAdd = () => {
arr.value.push(data.value);
value.value = '';
};
</script>
<style></style>
//子组件
<template>
<div class="hello">
<ul>
<li v-for="(item, index) in props.arr" :key="index">
{{ item }}
</li>
</ul>
</div>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
arr: {
type: Array,
default: () => [],
},
});
</script>
子传父,使用$emit
//子组件
<template>
<div class="hello">
<input type="text" v-model="data" />
<button @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref, defineEmits } from 'vue';
const data = ref('');
const emits = defineEmits(['add']);
const handleAdd = () => {
emits('add', data.value);
data.value = '';
};
</script>
//父组件
<template>
<ul>
<li v-for="(item, index) in arr" :key="index">
{{ item }}
</li>
</ul>
<childrenComp @add="addItem" />
</template>
<script setup>
import { ref } from 'vue';
import childrenComp from '@/components/children-comp.vue';
const arr = ref([]);
const addItem = (item) => {
arr.value.push(item);
};
</script>
2、ref
子组件
<template>
<div class="hello">
<input type="text" v-model="data" />
<button @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref, defineExpose } from 'vue';
const data = ref('');
const arr = ref([]);
const handleAdd = () => {
arr.value.push(data.value);
data.value = '';
};
defineExpose({ arr }); //通过defineExpose暴露给父组件的数据
</script>
父组件
<template>
<ul>
<li v-for="(item, index) in childrenRef?.arr" :key="index">
{{ item }}
</li>
</ul>
<childrenComp ref="childrenRef" />
</template>
<script setup>
import { ref } from 'vue';
import childrenComp from '@/components/children-comp.vue';
const childrenRef = ref();
</script>
3、v-model
父组件
<template>
<ul>
<li v-for="(item, index) in list" :key="index">
{{ item }}
</li>
</ul>
<childrenComp v-model:list="list" />
// Vue 会自动将其解释为:<childrenComp :list="list" @update:list="list = $event"/>
</template>
<script setup>
import { ref } from 'vue';
import childrenComp from '@/components/children-comp.vue';
const list = ref([1, 2, 3, 4]);
</script>
<style></style>
子组件
<template>
<div class="hello">
<input type="text" v-model="data" />
<button @click="handleAdd">添加</button>
</div>
</template>
<script setup>
import { ref, defineEmits, defineProps } from 'vue';
const props = defineProps({
list: {
type: Array,
default: () => [],
},
});
const emits = defineEmits(['update:list']);
const data = ref('');
const handleAdd = () => {
const arr = [...props.list, data.value];
emits('update:list', arr); // 触发父组件@update:list的事件,$event就是arr
data.value = '';
};
</script>
4、provide/inject,该API可以实现父组件向子组件传递数据,无论层级有多深,都可以通过这对API实现
父组件使用provide提供响应式数据
<template>
<div class="hello">
<input type="text" v-model="data" />
<button @click="handleAdd">添加</button>
</div>
<childrenComp v-model:list="list" />
</template>
<script setup>
import { provide, ref } from 'vue';
import childrenComp from '@/components/children-comp.vue';
const list = ref([]);
provide('list', list);
const data = ref('');
const handleAdd = () => {
list.value.push(data.value);
data.value = '';
};
</script>
子组件使用inject获取数据
<template>
<ul>
<li v-for="(item, index) in list" :key="index">
{{ item }}
</li>
</ul>
</template>
<script setup>
import { inject } from 'vue';
const list = inject('list');
</script>