vue3组件之间通信(二)——子传父属性和方法

文章目录

      • 1:setup函数传递属性和方法
        • (1)子组件传值和方法给父组件
        • (2)使用ref的方式来在父组件中获取子组件的数据和方法
      • 2:script setup 语法糖传递属性和方法
        • (1)子组件传值和方法给父组件
        • (2)使用ref的方式来在父组件中获取子组件的数据和方法


前言:理论上来讲,子组件修改父组件的值是可以的,但是由于父组件的可以引用多个子组件,其中一个子组件改了父组件的值后,其他的子组件的数据可能会有问题,所以不推荐使用子组件修改父组件的值,而是在父组件中定义属性和方法,在子组件中修改。

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>

③:效果
vue3组件之间通信(二)——子传父属性和方法_第1张图片

④:代码步骤说明
大致思路就是父组件传一个方法给子组件,然后子组件要传值给父组件的时候,通过点击事件触发父组件的方法,将子组件要传的值当成参数传给父组件的方法,然后就可以在父组件定义一个值用来接收这个参数了
vue3组件之间通信(二)——子传父属性和方法_第2张图片
⑤:子组件传方法给父组件并触发,和上面步骤一样

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>

③:效果
vue3组件之间通信(二)——子传父属性和方法_第3张图片
④:代码步骤说明
vue3组件之间通信(二)——子传父属性和方法_第4张图片

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>

③效果
vue3组件之间通信(二)——子传父属性和方法_第5张图片

④代码说明:大致逻辑和setup思路是一样的
vue3组件之间通信(二)——子传父属性和方法_第6张图片

(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>

③效果
vue3组件之间通信(二)——子传父属性和方法_第7张图片

④代码说明(重点就是要使用子组件的ref需要defineExpose
vue3组件之间通信(二)——子传父属性和方法_第8张图片

你可能感兴趣的:(vue3,javascript,vue.js,前端)