Vue3中的父子传值方法合集

452 阅读1分钟

1. setup 语法糖(reactive)传递方法defineProps 父 -> 子

1.1. 父组件

<template>
  <div>
    <Child :title="state"></Child>
  </div>
</template>


<script setup>
import Child from './components/Child.vue';
import { reactive } from 'vue';
const state = reactive({
  title:'你好'
})
</script>


<style lang="scss" scoped>


</style>

1.2. 子组件

<template>
  <div>
    {{ title }}
  </div>
</template>


<script setup>
// 以下两种方法都可以
defineProps(['title'])
// defineProps({
//   title: {
//     type: String,
//     default: "",
//   },
// });
</script>


<style lang="scss" scoped></style>

2. setup 语法糖(ref)传递方法defineProps 父 -> 子

2.1. 父组件

<template>
  <div>
    <!-- 往子组件传递state的数据 -->
    <Child :newArr="state"></Child>
  </div>
</template>


<script setup>
import Child from "./components/Child.vue";
import { ref } from "vue";
const state = ref({
  title: "好程序员",
});
</script>


<style lang="scss" scoped></style>

2.2. 子组件

<template>
  <div>
    子组件收到父组件传来的{{ newArr }}
  </div>
</template>


<script setup>
// 接收父组件穿过来的 state数据,由于父组件传递的名字叫做 `newArr` ,所以我们这边也采用的是newArr进行接收
defineProps({
  newArr: {
    type: String,
  },
});
</script>
<style lang="scss" scoped></style>

3. 使用provide和inject 进行父子传递 父 -> 子

3.1. 父组件

<template>
  <Child></Child>
</template>


<script setup>
import Child from "./components/Child.vue";
import { reactive, provide } from "vue";


const state = reactive({
  title: "好程序员",
});
provide("provideToChild", {
  // state指的是名字
  state,
  // 传入的东西 ====>   {"title":"好程序员"}
  changeTitle: (FromChildParams) => {
    state.title = FromChildParams;
  },
});
</script>


<style lang="scss" scoped></style>

3.2. 子组件

<template>
  <div>
    我是子组件{{ injectFromParent }}
  </div>
</template>


<script setup>
import { inject } from 'vue';
// 注入依赖,也就是父组件传过来的元素
const injectFromParent = inject('provideToChild')
// 子组件调用父组件传递过来的函数同时携带参数给父组件
// injectFromParent.changeTitle('MontherFucker')
</script>


<style lang="scss" scoped>


</style>

4. setup 语法糖中的defineEmits进行 子 -> 父

4.1. 子元素

<template>
  <div>
    我是子组件
    <button @click="changeFaterTitle">触发子组件传递数据</button>
  </div>
</template>


<script setup>
// 抛发出子元素传出的参数
const fromFather = defineEmits(["toSonEvent"]);
const changeFaterTitle = () => {
  // montherFucker 是子元素传给父元素的值
  fromFather("toSonEvent", "montherFucker");
};
</script>


<style lang="scss" scoped></style>

4.2. 父元素

<template>
  <div>
    <!-- 接收子元素传递过来的数据 -->
    <Child @toSonEvent="changeTitle"></Child>
    <div>{{ state }}</div>
  </div>
</template>


<script setup>
import Child from "./components/Child.vue";
import { reactive, provide } from "vue";
const state = reactive({
  title: "你好",
});
const changeTitle = (fromSonParams) => {
  // 显示传递过来的数据    fromSonParams可以是任意字符,两者相同即可
  state.title = fromSonParams;
};
</script>


<style lang="scss" scoped></style>

5. 通过v-model进行父子传递

5.1. 父组件

<template>
  <div>
    <Child v-model:title="state.title" v-model:name="state.name"></Child>
    <div>父组件中的:{{ state.title }}</div>
    <div>父组件中的:{{ state.name }}</div>
  </div>
</template>


<script setup>
import { reactive } from 'vue';
import Child from './components/Child.vue';


const state=reactive({
  title:'好程序员',
  name:'大前端智慧数字AI'
})
</script>


<style lang="scss" scoped>


</style>

5.2. 子组件

<template>
  <div>
    <button @click="changeInfo">触发子组件传递数据给父组件</button>
  </div>
</template>


<script setup>
// 接收父组件传过来的数据
defineProps(["title", "name"]);
// defineEmits抛发回去
const $emit = defineEmits(["update:title", "update:name"]);
const changeInfo = () => {
  $emit("update:title", "monthreFcker");
  $emit("update:name", "张三");
};
</script>


<style lang="scss" scoped></style>

6. 使用 defineExpose 暴露属性和方法

6.1. 表格的修改弹框实战

6.2. 小案例演示

  • 子组件
<script>
import { defineExpose } from 'vue'

export default {
  setup() {
    const title = 'Hello, world!'

    const setTitle = (newTitle) => {
      title.value = newTitle
    }

    defineExpose({ setTitle })

    return {
      title
    }
  }
}
</script>
  • 父组件
<template>
  <div>
    <ChildComponent ref="child" />
    <button @click="setTitle('New Title')">Change Title</button>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue'

export default {
  components: {
    ChildComponent
  },

  setup() {
    const child = ref(null)

    const setTitle = (newTitle) => {
      child.value.setTitle(newTitle)
    }

    return {
      child,
      setTitle
    }
  }
}
</script>

7. 注意事项:

attrsattrs和listeners主要用来父孙组件之间传值,有的同学说也可以用provide和inject来实现父孙组件之间传值,但需要注意的是provide和inject只能从父组件向孙组件传值,不能从孙组件向父组件传值,这种情况就需要使用attrsattrs和listeners来实现了。