Vue3学习(组合式API——父、子组件间通信详解)

目录

一、组合式API下的父组件传子组件。(自定义属性)

(1)基本思想。

(2)核心注意点。(defineProps)

(3)传递简单类型数据。

(4)传递对象类型数据。(v-bind="对象类型数据")

(5)传递响应式类型数据。(:属性="响应式数据")

(6)defineProps原理简要分析。

二、组合式API下的子组件传父组件。(自定义事件)

(1)基本思想。

(2)核心注意点。

<1>事件驱动通信。

<2>单向数据流原则。

<3>核心实现步骤。

(3)页面渲染时子组件立即向父组件传递数据。

(4)基于子组件的事件函数向父组件传递数据。

三、Vue3组合式API中的父、子组件间通信小结。


一、组合式API下的父组件传子组件。(自定义属性)

(1)基本思想。
  1. 父组件中给子组件绑定属性。(propsXXX)
  2. 子组件内部通过props选项(setup中使用defineProps:“编译器宏”)接收。
(2)核心注意点。(defineProps)
  1. 单向数据流:数据从父组件流向子组件,子组件不直接修改父组件数据。
  2. 声明式接收:子组件通过 defineProps 声明要接收的属性(props),明确数据类型和校验规则。
  3. 响应式绑定:父组件通过 ref 或 reactive 创建响应式数据。用 ":" 动态绑定到子组件属性,数据变化时子组件自动更新
(3)传递简单类型数据。
  • 父组件代码示例。
<script setup>
//局部子组件(导入就能使用)
import Son from "./components/Son.vue";

</script>

<template>
  <div>
    <h2>我是父组件</h2>
    <Son propsCar="宝马5系" />
  </div>
</template>

<style scoped>
</style>
  • 子组件代码示例。
<script setup>
//因为写在setup中,无法直接配置props选项
//借助于“编译器宏"函数接收子组件传递的数据
const props = defineProps({
  propsCar : String
})
console.log('子组件获取:',props)
//脚本中获取属性需要通过props.xxx获取
console.log('子组件获取属性值:',props.propsCar)
</script>

<template>
<!-- 对于模版中,可以直接使用props传递的值 -->
  <div class="son">我是子组件------{{propsCar}}</div>
</template>

<style scoped>
.son{
  border: 1px solid #000;
  padding: 30px;
}
</style>
  • 页面渲染效果。

(4)传递对象类型数据。(v-bind="对象类型数据")
  • 父组件代码示例。
<script setup>
//局部子组件(导入就能使用)
import Son from "./components/Son.vue";
const data = {
  name: "张三",
  age: 18
}
</script>

<template>
  <div>
    <h2>我是父组件</h2>
    <Son v-bind="data" />
<!-- 第2种写法也可以   <Son :="data" />-->
  </div>
</template>

<style scoped>
</style>
  • 子组件代码示例。
<script setup>
//因为写在setup中,无法直接配置props选项
//借助于“编译器宏"函数接收子组件传递的数据
const props = defineProps({
  name: String,
  age : Number
})
console.log('子组件获取:',props)
//脚本中获取属性需要通过props.xxx获取
console.log('子组件获取属性值:',props.name)
console.log('子组件获取属性值:',props.age)
</script>

<template>
<!-- 对于模版中,可以直接使用props传递的值 -->
  <div class="son">我是子组件------{{name}}------{{age}}</div>
</template>

<style scoped>
.son{
  border: 1px solid #000;
  padding: 30px;
}
</style>
  • 页面渲染效果。



(5)传递响应式类型数据。(:属性="响应式数据")
  • 父组件代码示例。
<script setup>
//局部子组件(导入就能使用)
import Son from "./components/Son.vue";
import {ref} from "vue";
const money = ref(100)
const addMoney = () =>{
  money.value++
}
</script>

<template>
  <div>
    <h2>
      我是父组件---当前父组件money:{{money}}
      <button @click="addMoney">money++</button>
    </h2>
    <Son :propsMoney="money" />

  </div>
</template>

<style scoped>
</style>
  • 子组件代码示例。
<script setup>
//因为写在setup中,无法直接配置props选项
//借助于“编译器宏"函数接收子组件传递的数据
import {watch} from "vue";

const props = defineProps(['propsMoney'])
console.log('页面首页渲染子组件获取:',props)
//脚本中获取属性需要通过props.xxx获取
//监听父组件传递的响应式数据是否变化
watch(() => props.propsMoney, (newValue) => {
  //每变化一次就打印一次
  console.log('子组件获取更新的money值:',newValue)
})
</script>

<template>
<!-- 对于模版中,可以直接使用props传递的值 -->
  <div class="son">我是子组件------父组件传递的money:{{propsMoney}}</div>
</template>

<style scoped>
.son{
  border: 1px solid #000;
  padding: 30px;
}
</style>
  • 页面渲染效果。

(6)defineProps原理简要分析。
  • 本质上是编译阶段的一个标识实际当编译器解析时,遇到后会进行编译转换

二、组合式API下的子组件传父组件。(自定义事件)

(1)基本思想。
  1. 父组件中给子组件通过@绑定事件
  2. 子组件内部通过emit方法触发事件
(2)核心注意点。
<1>事件驱动通信。
  • 子组件通过自定义事件向父组件发送数据。父组件监听这些事件并处理数据
  • 子组件使用defineEmits声明可触发的事件通过emit触发事件并传递参数

<2>单向数据流原则。
  • 子组件不直接修改父组件数据,而是通过事件通知父组件自行更新

<3>核心实现步骤。
  1. 子组件步骤。
  • 声明事件:const emit = defineEmits(['事件名',...,])
  • 触发事件:emit ('需触发的事件名',{需携带的参数...})

  1. 父组件步骤。
  • 监听事件:子组件标签<Xxx @子组件触发的事件名="父组件中处理事件的方法">
  • 处理事件:在对应的方法中更新自身状态
(3)页面渲染时子组件立即向父组件传递数据。
  • 父组件页面初始渲染效果。
<script setup>
//局部子组件(导入就能使用)
import Son from "./components/Son.vue";
import {reactive} from "vue";
const data = reactive({
  name:'张三',
  addr:'湖南长沙'
})

</script>

<template>
  <div>
    <h2>
      我是父组件---当前父组件响应式数据:姓名:{{data.name}} 地址:{{data.addr}}
    </h2>
    <Son />
  </div>
</template>

<style scoped>
</style>


  • 子组件自定义事件向父组件传递新值。
<script setup>

//通过defineEmits编译器宏声明事件、emit方法
const emit = defineEmits(['changeValue'])
//页面渲染时直接触发自定义的事件并进行传参
emit('changeValue',{
  name : '李四',
  addr : '湖北武汉'
})
</script>

<template>
  <div class="son">我是子组件</div>
</template>

<style scoped>
.son{
  border: 1px solid #000;
  padding: 30px;
}
</style>

  • 父组件监听子组件(自定义事件)传递的数据。
<script setup>
//局部子组件(导入就能使用)
import Son from "./components/Son.vue";
import {reactive} from "vue";
const data = reactive({
  name:'张三',
  addr:'湖南长沙'
})

const getValue = (res) => {
  console.log('子组件传递的数据:',res);
  data.name = res.name;
  data.addr = res.addr;
};

</script>

<template>
  <div>
    <h2>
      我是父组件---当前父组件响应式数据:姓名:{{data.name}} 地址:{{data.addr}}
    </h2>
<!--  @后面跟的必须和子组件的事件名一致  -->
<!--  getValue:处理子组件传递的数据,更新自身状态  -->
    <Son @change-value="getValue" />
  </div>
</template>

<style scoped>
</style>
  • 页面最终渲染效果。

(4)基于子组件的事件函数向父组件传递数据。
  • 基本实现:当子组件输入框的内容并按钮提交(事件函数触发),通过自定义事件的触发将对应的参数通过子组件传递到父组件。
  • 子组件代码示例。
<script setup>

//通过defineEmits编译器宏声明事件、emit方法
import {ref} from "vue";

const emit = defineEmits(['submitInput'])

const inputValue = ref('')
//在子组件的对应事件函数上触发子组件向父组件传值的自定义事件
const changeInput = () =>{
  emit('submitInput',{
    input: inputValue.value
  })
}
</script>

<template>
  <div class="son">
    <h3>我是子组件</h3>
    <div style="padding: 10px">
      <input type="text" v-model="inputValue">输入框的值:{{inputValue}}
      <button @click="changeInput">提交(子传父)</button>
    </div>
  </div>

</template>

<style scoped>
.son{
  border: 1px solid #000;
  padding: 30px;
}
</style>
  • 父组件代码示例。
<script setup>
//局部子组件(导入就能使用)
import Son from "./components/Son.vue";
import {reactive} from "vue";
const data = reactive({
  value:'哈哈哈哈我是父组件的响应式',
})

const getInputValue = (res) => {
  console.log('子组件传递的数据:',res);
  data.value = res.input;
};

</script>

<template>
  <div>
    <h2>
      我是父组件---当前父组件响应式数据:{{data.value}}
    </h2>
<!--  @后面跟的必须和子组件的事件名一致  -->
<!--  getValue:处理子组件传递的数据,更新自身状态  -->
    <Son @submitInput="getInputValue" />
  </div>
</template>

<style scoped>
</style>
  • 页面渲染效果。



三、Vue3组合式API中的父、子组件间通信小结。

  1. 父传子过程中通过 defineProps({属性名:类型,...}) 方式接收props。
  2. setup语法糖中通过 const props=defineProps({属性名:类型,...})、props.xxx 使用父组件传递的数据。而在模版中可以直接通过属性名使用。
  3. 子传父过程中通过 defineEmits(['事件名',...]) 方式得到emit方法。
  4. 触发事件:emit('事件名',需传递的参数)父组件通过@事件名即可监听
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁岁岁平安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值