当前位置: 首页 > news >正文

vue3 - 组件间的传值

组件间传参

父传子v-on/props

父组件使用v-on:绑定要传的参数:parentData="parentData"

<template><div><Child1 :parentData="parentData"></Child1></div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { ref } from 'vue';const parentData = ref('父级组件参数:parentData');onMounted(() => {
});
</script>

子组件使用props接收

<template>
<div>父级组件参数:<p>{{ modelValue }}</p><p>{{ parentData }}</p>
</div>
</template>
<script setup lang="ts">
const props = defineProps({modelValue: {type: String,required: false},parentData: {type: String,default: '父级组件参数:default'}
});
</script>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

子传父emit

父组件自定义事件changeData传递给子组件

<template><div><h2>父级组件</h2><Child1 :parentData="parentData" v-model="defaultData" @changeData="changeData"></Child1></div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { onMounted, reactive, ref, watch } from 'vue';const defaultData = ref('v-model绑定参数:defaultData');
const parentData = ref('父级组件参数:parentData');const changeData = (data: string) => {console.log('子组件传给父组件参数:', data);parentData.value = data;
};
</script>

子组件触发事件将需要传递给父组件的参数给事件,使用defineEmits接收事件,emit触发事件。

<template><div><!-- 父组件参数 --><div>父级组件参数:<p>{{ modelValue }}</p><p>{{ parentData }}</p><button @click="emit('changeData', '子组件传给父组件参数')">子组件传给父组件参数</button></div></div>
</template>
<script setup lang="ts">
import { onMounted, reactive, ref, watch } from 'vue';
const props = defineProps({modelValue: {type: String,required: false},parentData: {type: String,default: '父级组件参数:default'}
});/*** 子组件传给父组件参数*  1. 定义事件*  2. 通过emit触发事件*  3. 父组件通过@changeData="changeData"接收事件*/
const emit = defineEmits(['changeData'])
</script>

父传子:依赖/注入:provide/inject

父组件使用provide定义要传递给后代组件的方法、参数。(当需要给深层的某个子组件传递参数时,使用props传参需要一层一层的传递,不好维护代码,可使用provide/inject来实现)

<template><div><h2>父级组件</h2><button @click="provideData = '更新后的父级组件provide参数:provideData'">更新provideData</button><Child1></Child1></div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { ref, provide  } from 'vue';const provideData = ref('父级组件provide参数:provideData');
provide('provideData1', provideData); // 传递响应式参数,父组件更新值,子组件跟着更新数据
provide('provideData2', provideData.value); // 直接传递值,父组件更新后子组件不会更新
</script>

子组件通过inject

<template><div class="child1"><div>父级组件参数:<p>inject:provideData1: {{ provideData1 }}</p><p>inject:provideData2: {{ provideData2 }}</p></div></div>
</template>
<script setup lang="ts">
import { inject, ref } from 'vue';const provideData1 = inject('provideData1');
const provideData2 = inject('provideData2');</script>
<style scoped lang='scss'>
.child1{border: 1px solid #ccc;
}
</style>

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

状态管理pinia

1.安装:

npm install pinia

2.main.ts

创建一个 pinia 实例 (根 store) 并将其传递给应用

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const pinia = createPinia()
const app = createApp(App)app.use(pinia)
app.mount('#app')

使用pinia参考地址:https://pinia.vuejs.org/zh/core-concepts/

3.定义store

/src/stores/counter.ts

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', () => {const count = ref(0)const name = ref('Eduardo')const doubleCount = computed(() => count.value * 2)function increment() {count.value++}return { count, doubleCount, increment }
})

4.使用

<script setup>
import { useCounterStore } from '@/stores/counter'
// 在组件内部的任何地方均可以访问变量 `store` ✨
const store = useCounterStore()// ❌ 下面这部分代码不会生效,因为它的响应式被破坏了
// 与 reactive 相同: https://vuejs.org/guide/essentials/reactivity-fundamentals.html#limitations-of-reactive
const { name, doubleCount } = store
name // 将会一直是 "Eduardo" //
doubleCount // 将会一直是 0 //
setTimeout(() => {store.increment()
}, 1000)// 这一部分代码就会维持响应式
// 💡 在这里可以直接使用 `store.doubleCount`
const doubleValue = computed(() => store.doubleCount)
</script>

父传子:插槽 Slots

父组件使用slots传递html代码给子组件显示

<template><div><h2>父级组件</h2><Child1><div><p>父组件代码片段1</p></div><p>父组件代码片段2</p><template #header><p>父组件代码片段3</p></template></Child1></div>
</template>
<script setup lang="ts">
import { te } from 'element-plus/es/locales.mjs';
import Child1 from './components/Child1.vue';
import { ref, provide  } from 'vue';
</script>
<template><div class="child1"><slot name="header">子组件头部插槽(具名插槽)</slot><div>子组件内容1</div><slot>子组件默认插槽</slot><div>子组件内容2</div></div>
</template>
<script setup lang="ts">
import { ref } from 'vue'</script>
<style scoped lang='scss'>
.child1 {border: 1px solid #ccc;
}
</style>

父组件中具名插使用<template #插槽名>,子组件定义<slot name="header"></slot>,当父组件为给插槽传递内容时,会显示<slot></slot>标签之间的插槽默认内容,没有则不显示。

子传父:插槽 Slots

子组件定义传递的参数

<template><slot name="header" :count ="1" :text='text1'></slot><slot :count ="2" :text='text2'></slot>
</template>

父组件接收子组件的参数

<template #header="headerProps">{{ headerProps.count }} {{ headerProps.text }}
</template><template #header="{count,text}">{{ count }}{{text}}
</template><!-- 默认插槽 -->
<template v-slot="defaultProps">{{ defaultProps.count }} {{ defaultProps.text }}
</template><template v-slot="{count,text}">{{ count }}{{text}}
</template><template #default="defaultProps">{{ defaultProps.count }} {{ defaultProps.text }}
</template><template #default="{count,text}">{{ count }}{{text}}
</template>

注:这个传参方式主要在封装组件时使用,例如element plus组件中table

父传子

父组件使用子组件暴露的方法,执行方法,将参数传递给方法中

<template><div><Child1 ref='child'></Child1></div>
</template>
<script setup lang="ts">
import Child1 from './components/Child1.vue';
import { ref } from 'vue';const params = ref({name:'',type:''
})
const child = ref(null);onMounted(() => {child.value.open(params.value)
});
</script>
<script setup lang="ts">
const open = (params)=>{console.log('父组件传递的参数:',params)
}// 暴露方法给父组件
defineExpose({open
});
</script>
http://www.dtcms.com/a/347156.html

相关文章:

  • nodejs和vue安装步骤记录
  • 【Golang】有关任务窃取调度器和抢占式调度器的笔记
  • 机器人 - 无人机基础(5) - 飞控中的传感器(ing)
  • 【大语言模型 16】Transformer三种架构深度对比:选择最适合你的模型架构
  • 云原生俱乐部-k8s知识点归纳(8)
  • 资深产品经理个人能力提升方向:如何系统化进阶并考取高价值证书?
  • 资深产品经理个人能力提升方向:如何系统化进阶与考证规划
  • 可视化-模块1-HTML-02
  • Node.js特训专栏-实战进阶:23. CI/CD流程搭建
  • 国产轻量级桌面GIS软件Snaplayers从入门到精通(21)
  • 复杂街景误检率↓79%!陌讯动态融合算法在街道垃圾识别的边缘计算优化​​
  • Text2SQL、ChatBI简介
  • AI agent开发与大模型工程师面试复习纲要与高频面试题答案(4)-- AI agent系统设计与项目实践
  • Rust系统编程实战:驾驭内存安全、无畏并发与WASM跨平台开发
  • Go语言实战案例-Redis连接与字符串操作
  • python 字典有序性的实现和OrderedDict
  • 字节跳动开源Seed-OSS:36B参数模型以512K上下文与可控思考预算重新定义AI实用主义
  • Linux:进程间通信(IPC)-SystemV
  • MiMo-VL 技术报告
  • 文献阅读笔记【物理信息机器学习】:Physics-informed machine learning
  • AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年8月23日第168弹
  • Java 泛型 T、E、K、V、?、S、U、V
  • 脑洞补给站—金湾读书会—第二期—课题分离——20250823
  • GitHub 热榜项目 - 日榜(2025-08-23)
  • 小白成长之路-k8s原理(一)
  • 新能源电池深孔检测:新启航方案以激光频率梳技术打破光学遮挡,达 2μm 级
  • imx6ull-驱动开发篇36——Linux 自带的 LED 灯驱动实验
  • 使用Ollama部署自己的本地模型
  • LeetCode第1019题 - 链表中的下一个更大节点
  • IntelliJ IDEA 集成 ApiFox 操作与注解规范指南