效果:
父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) return
sonRef.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变量 即 flag1
type: 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.value
emit('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>