面试时,总会提问关于使用 Vue时,组件之间有哪些通信方式
本文是根据面试题,总结出 8 种不同方式,结合代码,都一一验证过了
1. props 父组件向子组件传值 defineProps
//父组件
<view>
<props-child list="list"></props-child>
</view>
const list = reactive(['111', '222', '333'])
// 子组件
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
通过 props.list 即可获取到值
2. emits 子组件向父组件传值 defineEmits
// 子组件
<view class="item">
<input v-model="value" placeholder="子组件按钮"/>
<button @click="toAdd" type="button">添加2</button>
</view>
let emits = defineEmits(['add'])
let value = ref('')
const toAdd = () => {
console.log('点击了添加')
emits('add', value.value)
}
// 父组件
<view>
<props-child @add="handleAdd"></props-child>
</view>
const handleAdd = value => {
// 父组件接收子组件的值
console.log('value==', value);
}
3. v-model 语法糖
// 父组件
<view>
<child v-model:list="list"></child>
</view>
const list = ref(['111', '222', '333'])
// 子组件
<view class="item">
<input v-model="value" placeholder="model输入"/>
<button @click="toAdd" type="button">添加model</button>
</view>
/* 子组件传值 */
let emits = defineEmits(['update:list'])
let value = ref('')
const toAdd = () => {
console.log('点击了添加',value.value)
let arr = props.list
arr.push(value.value)
console.log('新的',arr)
emits('update:list',arr)
value.value=''
}
4. refs
和Vue2不同,vue3中的this是undefined,所以不能通过this.$refs['组件名称']来获取组件内属性和方法。vue3内通过引入 ref 来解决,defineExpose起到了暴露属性的作用。
// 子组件
const list = ref(['1', '6', '9'])
defineExpose({ list })
// 父组件
<ul>
<li v-for="item in childRefs?.list">{{item}}</li>
</ul>
const childRefs = ref(null)
在父组件使用
const childRefs = ref(null)
template 内通过 childRefs?.list 取值
子组件使用 const list = ref(['1', '6', '9']) defineExpose({ list })
5. useAttrs()
// 父组件
<props-child :aaa="11111"></props-child>
// 子组件
const attrs = useAttrs();
console.log('$attrs=',attrs); // Proxy {aaa: 11111}
6. provide、inject
常用来在爷孙组件之间传递数据。
顶级组件通过provide提供数据,子组件通过inject能接收返回的数据
// 父组件
import { provide} from 'vue'
const list = reactive (['1113','2223','3333'])
provide('list',list)
//子组件
import { inject } from 'vue'
const listData = inject('list')
console.log('listData==',listData);