vue3.0 之父子组件传值

父子组件传值

父传子 props

方式 1:原始的 props 传值

父组件
<template>
  <div>
    父组件 -- {{ num }}
    <RegChild :num="num" />
  </div>
</template>

<script>
import RegChild from "./childCom/RegChild";
import { defineComponent, ref } from "vue";
export default defineComponent({
  name: "Reg",
  components: {
    RegChild,
  },
  setup() {
    let num = ref(0);
    return {
      num,
    };
  },
});
</script>
子组件
<template>
  <div>
    <div>子组件 -- {{ num }}</div>
  </div>
</template>

<script>
import { defineComponent, reactive, toRefs } from "vue";
export default defineComponent({
  name: "RegChild",
  components: {},
  // props: ["num"],
  props: {
    num: {
      type: Number,
      default: 0,
    },
  },
  setup(proos) {
    let state = reactive({
      num: proos.num,
    });
    return {
      ...state,
    };
  },
});
</script>

方式 2:使用 provide && inject

  • 父组件
<template>
  <div>
    <Son />
  </div>
</template>

<script>
import Son from "./childCom/Son";
import { defineComponent, onMounted, ref, provide } from "vue";
export default defineComponent({
  name: "About",
  components: {
    Son,
  },
  provide: {
    name: "张三",
    age: 20,
  },
  setup() {
    provide("num", 88);
    return {};
  },
});
</script>
  • 子组件
<template>
  <div>
    <div>子组件num -- {{ num }}</div>
    <div>子组件name -- {{ name }}</div>
    <div>子组件age -- {{ age }}</div>
  </div>
</template>

<script>
import { defineComponent, reactive, toRefs, inject } from "vue";
export default defineComponent({
  name: "Son",
  components: {},
  props: ["num", "name"],
  inject: ["age"],
  setup() {
    let state = reactive({
      num: inject("num"),
      name: inject("name"),
    });
    return {
      ...state,
    };
  },
});
</script>

父组件

  • 父组件修改 count 的值,然后传值给子组件
  • 父组件修改 userInfo 之中的 username 的值,传递给子组件
  • 注意点:就是在子组件之中,使用 v-model的时候,子组件可以修改父组件的值
<template>
  <div>
    <div>
      父组件count的值 -- {{ count }} 父组件username的值 -- {{ username }}
    </div>
    <div>
      修改count
      <button @click="addCount">修改count</button>
    </div>
    <div>
      修改username
      <button @click="setUsername">修改username</button>
    </div>
    <RegChild />
  </div>
</template>

<script>
import RegChild from "./childCom/RegChild";
import { defineComponent, provide, ref, reactive, toRefs } from "vue";
export default defineComponent({
  name: "Reg",
  components: {
    RegChild,
  },
  setup() {
    let count = ref(0);
    const addCount = () => {
      count.value = count.value + 1;
    };
    let userInfo = reactive({
      username: "张三",
    });
    const setUsername = () => {
      userInfo.username = "李四";
    };
    provide("count", count);
    provide("userInfo", userInfo);
    return {
      count,
      addCount,
      ...toRefs(userInfo),
      setUsername,
    };
  },
});
</script>
<style lang="scss" scoped></style>

子组件

<template>
  <div>
    <div>子组件count --- {{ count }}</div>
    <div>子组件username --- {{ userInfo.username }}</div>
    <div>
      子组件的input修改 父组件的数据
      <input type="text" v-model="userInfo.username" />
    </div>
  </div>
</template>

<script>
import { defineComponent, inject, reactive, watchEffect } from "vue";
export default defineComponent({
  name: "RegChild",
  components: {},
  setup() {
    let count = inject("count");
    let userInfo = inject("userInfo");
    return {
      count,
      userInfo,
    };
  },
});
</script>
<style lang="scss" scoped></style>

provide 与 inject 的获取 setup 中的数据 ,传递到子组件

+父组件

<template>
  <div>
    <Son />
  </div>
</template>

<script>
import Son from "./childCom/Son";
import { defineComponent, provide, reactive, ref } from "vue";
export default defineComponent({
  name: "About",
  components: {
    Son,
  },
  provide() {
    return {
      // 使用 this 是拿到 setup之中的 return的数据
      obj: this.obj,
      num: this.num,
      // 不使用 this 直接赋值,这是直接传递数据过去
      name: "张三",
      age: 20,
    };
  },
  setup() {
    let num = ref(99);
    let obj = reactive({
      color: "yellow",
    });
    return {
      num,
      obj,
    };
  },
});
</script>
  • 子组件
<template>
  <div>
    <div>子组件num -- {{ num }}</div>
    <div>子组件name -- {{ name }}</div>
    <div>子组件age -- {{ age }}</div>
    <div>子组件obj -- {{ obj }}</div>
  </div>
</template>

<script>
import { defineComponent, reactive, toRefs, inject } from "vue";
export default defineComponent({
  name: "Son",
  components: {},
  props: ["num", "name", "obj"],
  inject: ["age"],
  setup() {
    let state = reactive({
      num: inject("num", 0), //接受 父组件的值 , 定义默认值 0
      name: inject("name", "默认值"),
      obj: inject("obj"),
    });
    return {
      ...state,
    };
  },
});
</script>

父子通讯 案例

  • 需求:就是父组件一个数组,里面有着两个对象,在子组件之中,点击删除父组件的数据
  • 方式:使用 props + emit 的方式更为靠谱 与 习惯

父组件

<template>
  <div>
    <div>我是data --- {{ data }}</div>
    <Test v-for="item in data" :key="item.id" :item="item" @remove="remove" />
  </div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
import Test from "./childCom/Test.vue";
export default defineComponent({
  name: "Home",
  components: {
    Test,
  },
  setup() {
    let data = ref([
      {
        id: 1,
        age: 20,
        title: "第一",
      },
      {
        id: 2,
        age: 30,
        title: "第二",
      },
    ]);
    const remove = (id: any) => {
      data.value = data.value.filter((item) => item.id !== id);
    };
    return {
      data,
      remove,
    };
  },
});
</script>

子组件

  • 子组件向父组件传值,还是使用 emit 发射事件的方式
    • 首先的是子组件自定义事件 @click="remove(item.id) 并且传递值
    • 需要在emits: ["remove"], 注册该自定义事件
    • 在 setup 组件 api 之中,使用该自定义事件,并且需要向父组件发送事件ctx.emit("remove", id);
    • 最后的时候,需要把当前的事件在return 之中返回出去,给当前子组件使用
<template>
  <div>
    <div>我是title{{ item.title }}</div>
    <button @click="remove(item.id)">删除</button>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "Test",
  components: {},
  props: {
    item: Object,
  },
  // 注册自定义事件
  emits: ["remove"],
  // props 从父组件 传递的值 , ctx为上下文对象 this
  setup(props, ctx) {
    const remove = (id: any) => {
      ctx.emit("remove", id);
    };
    return {
      remove,
    };
  },
});
</script>
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值