文章目录
前言:理论上来讲,子组件修改父组件的值是可以的,但是由于父组件的可以引用多个子组件,其中一个子组件改了父组件的值后,其他的子组件的数据可能会有问题,所以不推荐使用子组件修改父组件的值,而是在父组件中定义属性和方法,在子组件中修改。
1:setup函数传递属性和方法
(1)子组件传值和方法给父组件
①:父组件
<template>
<div class="father">
<h1>父组件:{{ fatherMsg }}</h1>
<button @click="clickFather">点我(调用子组件的方法)</button>
<son @getMsessage="getMsessage" />
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
import son from "./son.vue";
export default defineComponent({
components: {
son,
},
setup(prop, ctx) {
const fatherMsg = ref("");
function getMsessage(params) {
fatherMsg.value = params;
console.log("父组件的方法被触发了one", params);
}
return {
fatherMsg,
getMsessage,
};
},
});
</script>
<style scoped>
.father {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style>
②:子组件
<template>
<div class="son">
<h2>子组件</h2>
<button @click="getMsessage">点我传值给父组件</button>
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
setup(prop, ctx) {
const message = ref("子组件的值--张三");
function getMsessage() {
console.log("进来了");
ctx.emit("getMsessage", message);
}
return {
message,
getMsessage,
};
},
});
</script>
<style scoped>
.son {
width: 200px;
height: 100px;
border: 1px solid green;
}
</style>
③:效果
④:代码步骤说明
大致思路就是父组件传一个方法给子组件,然后子组件要传值给父组件的时候,通过点击事件触发父组件的方法,将子组件要传的值当成参数传给父组件的方法,然后就可以在父组件定义一个值用来接收这个参数了
⑤:子组件传方法给父组件并触发,和上面步骤一样
function getMsessage(params) {
fatherMsg.value = params;
console.log("父组件的方法被触发了one", params());
}
(2)使用ref的方式来在父组件中获取子组件的数据和方法
①:父组件
<template>
<div class="father">
<h1>父组件:{{ fatherMsg }}</h1>
<button @click="clickFather">点我(调用子组件的方法)</button>
<son ref="sonRef" />
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
import son from "./son.vue";
export default defineComponent({
components: {
son,
},
setup(prop, ctx) {
const fatherMsg = ref("");
const sonRef = ref(null);
function clickFather() {
console.log("父组件", sonRef.value.message);
fatherMsg.value = sonRef.value.message;
sonRef.value.clickSon();
}
return {
fatherMsg,
clickFather,
sonRef,
};
},
});
</script>
<style scoped>
.father {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style>
②:子组件
<template>
<div class="son">
<h2>子组件</h2>
</div>
</template>
<script>
import { defineComponent, ref } from "vue";
export default defineComponent({
setup(prop, ctx) {
// 子组件的值
const message = ref("子组件的值--张三");
// 子组件的方法
function clickSon() {
console.log("son的log");
}
return {
message,
clickSon,
};
},
});
</script>
<style scoped>
.son {
width: 200px;
height: 100px;
border: 1px solid green;
}
</style>
③:效果
④:代码步骤说明
2:script setup 语法糖传递属性和方法
(1)子组件传值和方法给父组件
①:父组件
<template>
<div class="father">
<h1>父组件: {{ fatherMsg }}</h1>
<son @clickFather="clickFather" />
</div>
</template>
<script setup>
import { ref } from "vue";
import son from "./son.vue";
const fatherMsg = ref("");
function clickFather(params) {
fatherMsg.value = params;
console.log("父组件的方法被触发了", params);
}
</script>
<style scoped>
.father {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style>
②:子组件
<template>
<div class="son">
<h2>子组件</h2>
<button @click="clickSon">点我</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits, ref } from "vue";
const emits = defineEmits(["clickFather"]);
// 子组件的值
const message = ref("父组件的值---李四");
// 子组件的方法
function clickSon() {
emits("clickFather", "子组件的值4");
}
</script>
<style scoped>
.son {
width: 200px;
height: 150px;
border: 1px solid green;
}
</style>
③效果
④代码说明:大致逻辑和setup思路是一样的
(2)使用ref的方式来在父组件中获取子组件的数据和方法
①:父组件
<template>
<div class="father">
<h1>父组件: {{ fatherMsg }}</h1>
<button @click="clickFather">点我触发自组件的值和方法</button>
<son ref="sonRef" />
</div>
</template>
<script setup>
import { ref } from "vue";
import son from "./son.vue";
const sonRef = ref(null); // 子组件的ref
const fatherMsg = ref("");
function clickFather() {
fatherMsg.value = sonRef.value.message;
sonRef.value.clickSon();
}
</script>
<style scoped>
.father {
width: 200px;
height: 200px;
border: 1px solid red;
}
</style>
②:子组件
<template>
<div class="son">
<h2>子组件</h2>
</div>
</template>
<script setup>
import { ref } from "vue";
// 子组件的值
const message = ref("父组件的值---李四");
// 子组件的方法
function clickSon() {
console.log("son的log");
}
defineExpose({
message,
clickSon,
});
</script>
<style scoped>
.son {
width: 200px;
height: 150px;
border: 1px solid green;
}
</style>
③效果
④代码说明(重点就是要使用子组件的ref需要defineExpose)