效果:
父far.vue
<template><div><div>父组件内容<pre>value1:{{ value1 }}</pre><el-button type="primary">flag1:{{ flag1 }}</el-button><pre>obj1:{{ obj1 }}</pre><el-input v-model="obj1.name" placeholder=""></el-input></div><el-button type="primary" @click="getSonData">父组件触发子组件事件</el-button><!-- :value1="value1" 是正常传值 --><!-- v-model="flag1" 是匿名双向绑定 --><!-- v-model:obj2="obj1" 是具名obj2双向绑定 --><son ref="sonRef" :value1="value1" v-model="flag1" v-model:obj2="obj1"></son></div>
</template><script setup>
import { ref } from "vue"
import son from './components/son.vue'
let value1 = ref('123')
let flag1 = ref(false)
let obj1 = ref({name: 'jack',age: 18
})const sonRef = ref(null)
// 父组件触发子组件事件
const getSonData = () => {if (!sonRef.value) returnsonRef.value.sonFun()
}
</script><style lang="scss" scoped></style>
子组件:son.vue
<template><div style="margin-top: 100px;">子组件:{{ value1 }} {{ modelValue }} {{ obj2 }}<br>正常使用:<el-input v-model="value2" placeholder=""></el-input><br><el-button type="primary" @click="changeFlag">双向修改flag1:{{ localValue }}</el-button><br>双向修改:<el-input v-model="obj3.name" placeholder="" @change="changeName"></el-input></div></template><script script setup>
import { ref, defineOptions, defineProps, defineEmits, watch } from 'vue'const emit = defineEmits(['value1', 'update:modelValue', 'update:obj2']);defineOptions({name: " Son"
})
const props = defineProps({value1: {type: [String, Number],default: () => {return undefined}},modelValue: { // 父组件 v-model 时数据没有指定参数名,所以此时属性modelValue会接收到v-model变量 即 flag1type: Boolean,default: () => {return false}},obj2: { // 具名双向绑定type: Object,default: () => {return {}}},
})
let value2 = ref(props.value1)
let localValue = ref(props.modelValue || false)
let obj3 = ref(props.obj2 || {})
const changeFlag = () => {localValue.value = !localValue.valueemit('update:modelValue', localValue.value) // 同步修改父组件的值
}
const changeName = () => {emit('update:obj2', obj3.value) // 同步修改父组件的值
}// 监听属性变化
watch([() => props.modelValue, () => props.obj2], ([modelValue, obj2]) => {console.log(modelValue, obj2);
}, { deep: true, immediate: true })// 子组件暴露给父组件的方法
const sonFun = () => {console.log('子组件暴露给父组件的方法', 1);
}
// 暴露
defineExpose({sonFun
})
</script><style lang="scss" scoped></style>