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

Vue3——组件传值

父传子

props ——最推荐的方法(TOP1级别)

父组件文件

<sidebar :text="textname" ></sidebar> //父组件通过 :text 将父组件的数据textname传递给子组件
const textname:Ref<dataFather[]> = ref([{name:'刘亦菲',age:18
},
{name:'迪丽热巴',age:17
}]);

子组件文件

<div v-for="item in formattedText">  //不处理 即为 v-for = item in props.text {{ item }}
</div>
let props = defineProps(['text']) //子组件通过defineprops获取到父组件传过来名为text的数据
const formattedText = computed(() => //将数据通过computed处理一下 不用也可以直接使用props.text.map((item:any) => `我叫${item.name},今年刚满${item.age}`)
);

$attrs ——推荐(TOP2级别)

父组件文件

<Sidebar :childData="childData" :changeData="changeData"></Sidebar>
//父组件给子组件传递一个数据和一个方法 也可以是多个数据和方法 
const childData = ref([{ name: '张三', age: 18 },{ name: '李四', age: 19 },{ name: '王五', age: 20 },
]);//定义给子组件的数据
function changeData() {//定义给子组件的方法childData.value[0] = { name: '张三', age: 20 };
}

子组件文件

let restParams = defineProps(['childData'])//先拿到指定的props 剩余的参数可以用下面的attrs拿到
let _attrs = useAttrs();//获取剩余参数console.log('剩余参数====》',_attrs.changeData,restParams.childData)
//or
let _attrs = useAttrs();//获取剩余参数console.log('剩余参数====》',_attrs.changeData,_attrs.childData) //直接用attrs直接获取到所有的参数 
let data = _attrs.childData
data.map(item=>console.log('剩余参数====》',item.name,item.age))

父传孙——透传
二次封装第三方库的时候可以使用attrs来传递参数
子组件文件

//父组件的改动如下:新加了两个参数 newVersion、placeholder 
<Sidebar :childData="childData" :changeData="changeData" newVersion="new" placeholder="请你不要这样的看着我"></Sidebar>
//子组件
<HyInput v-bind="$attrs"></HyInput> <span v-show="newVersion==='new'">这是一个全新版本</span>
import HyInput from '@/components/hyinput/hyinput.vue';//假设这是一个第三方库
defineProps(['newVersion']);//子组件所需的数据 
//假设newVersion是自己封装的新UI和老UI的切换 Or 其他新的功能对第三方库的一个增强方法、函数等 其余的还是使用第三方库 将剩下的参数传递给第三方库v-bind="$attrs"

孙组件——HyInput.vue

//孙组件获取参数方法
let attrs = useAttrs();//通过v-bind='$attrs'透传过来的数据 
console.log(attrs)//这里也可以直接拿到剩下的参数 // let attrs = useAttrs();
// console.log(attrs);
let {childData,changeData,placeholder} = defineProps(['childData','changeData','placeholder']);//这里的一个newVersion 新版本的参数已经在子组件拿去了 然后将剩下的参数传到这个组件里来 
//两个方式选一个

refs & ref 的方式来修改

父组件代码

//template<Sidebar ref="sidebarRef"></Sidebar><div @click="getChildRef($refs)">点我修改子组件的数据</div>
// script
import Sidebar from '@/components/sidebar/sidebar.vue';let childRef = useTemplateRef('sidebarRef');let childRef = useTemplateRef('sidebarRef');function getChildRef(refs) { // 使用refs 可以获取到所有的子组件的refrefs.sidebarRef.dataList = '我先来show一把'; //通过refs修改子组件的数据for (const key in refs) {console.log(refs[key].dataList);//无需.value 打印出来是 我先来show一把}childRef.value.dataList = '爸爸来收你的爱了'; //通过ref来修改子组件的数据}
onMounted(() => {//接收子组件的ref只能在onMounted生命周期函数中获取/*** 执行的顺序 父组件的setup > 父beforeMounted > 子setup > 子beforeMounted > 子mounted > 父mounted* ref的挂载在 子mounted 所以需要在父组件的mounted中才能获取到 如果在setup中获取则获取不到 */console.log(childRef.value.dataList);})

子组件文件

        <div>{{ dataList }}</div>
let dataList = ref('给爸爸的爱');
defineExpose({dataList//必须主动将数据暴露出去 vue2中无需暴露 但是vue3为了保护单项数据流 所以需要做一个主动暴露 
})

如果是异步加载组件

const Sidebar = defineAsyncComponent(() => import('@/components/sidebar/sidebar.vue'));//异步引入侧边栏组件
//则不能在onMounted里面获取/*** 执行的顺序 父组件的setup > 父beforeMounted >父mounted > 子setup > 子beforeMounted > 子mounted * ref的挂载在 子mounted 所以在父组件的mounted中获取不到了 * 如果你想用nextTick 也是不行的 他的执行顺序是 父mounted > 父nextTick > 子mounted > 子nextTick */

通过v-model的相互传递值

父组件

 <hy-input v-model="textSearch"></hy-input>const HyInput = defineAsyncComponent(()=>import('@/components/hyinput/hyinput.vue'));//const textSearch = ref('')//定义搜索框内容

子组件

<template><div class="hy-input"><input type="text"class="hy-input__inner" :value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/></div>
</template><script setup lang="ts" name="hy-input">
defineProps(['modelValue']);//接收父组件传递的modelValue属性
const emit = defineEmits(['update:modelValue']);//将modelValue作为自定义事件update:modelValue的参数传递给父组件
</script><style scoped>.hy-input__inner{border: 1px solid #ccc;border-radius: 2px;color: #ccc;}
</style>

provide 注入

父组件

let fatherData = ref([{name: 'father',age: 18
},
{name: 'mother',age: 20
}
]
);
function changeData(params) {fatherData.value = params;
}
/*** * @description: provide(key, value) 在祖先组件中提供数据,使其所有后代组件可以注入使用。* @param key:标识提供数据的键,可以是字符串或 Symbol。* @param 要提供的数据,可以是任意类型(推荐响应式数据)。*/
provide('fatherDatas', {fatherData,changeData});//父组件向子组件传递数据
//也可以将fatherData changeData 分开注入

子组件 or 孙组件

//template
<button @click="changeData(childNewData)">changeData</button>
//script
let childNewData = [{name:'didi',age:19}
]
let defaultInjectValue = {fatherData:childNewData,changeData:() => {}
}
/*** @description inject(key, [defaultValue]) 在后代组件中注入祖先组件提供的数据。* @param key:与 provide 中相同的键。* @param defaultValue(可选):当未找到匹配的提供者时使用的默认值。*/
let {fatherData,changeData} = inject('fatherDatas',defaultInjectValue);

解决 Prop 钻取问题
共享全局状态:某些数据需要被多个组件共享,但不需要像 Vuex/Pinia 那样复杂的全局状态管理。
提供全局工具或服务:将某些工具函数或服务(如 API 客户端、路由实例)提供给所有组件使用。
跨组件生命周期协作:祖先组件需要控制后代组件的生命周期行为,或后代组件需要通知祖先组件。
组件库设计中的高级用法:组件库中的组件需要与使用者提供的配置或上下文进行交互。

子传父

props

父组件

<sidebar :getChildData="getChildData"></sidebar>
const childData = ref();
function getChildData(childValue:string[]){childData.value = childValue;
}

子组件文件 通过父组件的传递的函数来传递数据

let props = defineProps(['getChildData'])//子组件通过defineprops获取到父组件传过来名为getChildData的接收函数
let sendMyComputed = ()=>{ //将父组件的getChildData函数通过传递参数给父组件接收props.getChildData(formattedText.value)
}

emit——自定义事件 子传父

父组件文件

<sidebar @send-father-data="getChildData"></sidebar> //自定义一个send-father-data的事件 通过getChildData来接收子组件传过来的值const childData = ref();
function getChildData(childValue){childData.value = childValue; //将子组件传过来的childValue赋值给定义的childData
}

子组件

<div @click="sendFatherData">sendFatherData
</div>
let emit = defineEmits(['send-father-data']);//通过defineEmits 来接收自定义事件
let sendFatherData = () => {emit('send-father-data',textname.value) //将textname.value通过emit发送到'send-father-data'
}

$parent

父组件文件

let fatherData = ref('给儿子修改的数据 这都是爱');defineExpose({fatherData,//主动暴露})

父组件文件

//template<div @click="changeFatherData($parent)" >点我修改爸爸</div>
//script
function changeFatherData(parent:any) {parent.fatherData = '爸爸,爸爸 儿子永远爱你';
}

异步(defineAsyncComponent)组件中直接访问 $parent ,父组件未完全初始化,依赖收集失败
能修改 但是响应式数据会出问题

通过provide注入方法 子组件inject接收来修改父组件or祖组件

父组件

let fatherData = ref([{name: 'father',age: 18
},
{name: 'mother',age: 20
}
]
);
function changeData(params) {fatherData.value = params;
}
/*** * @description: provide(key, value) 在祖先组件中提供数据,使其所有后代组件可以注入使用。* @param key:标识提供数据的键,可以是字符串或 Symbol。* @param 要提供的数据,可以是任意类型(推荐响应式数据)。*/
provide('fatherDatas', {fatherData,changeData});//父组件向子组件传递数据
//也可以将fatherData changeData 分开注入

子组件 or 孙组件


//template
<button @click="changeData(childNewData)">changeData</button>
//script
let childNewData = [{name:'didi',age:19}
]
let defaultInjectValue = {fatherData:childNewData,changeData:() => {}
}
/*** @description inject(key, [defaultValue]) 在后代组件中注入祖先组件提供的数据。* @param key:与 provide 中相同的键。* @param defaultValue(可选):当未找到匹配的提供者时使用的默认值。*/
let {fatherData,changeData} = inject('fatherDatas',defaultInjectValue);
http://www.lryc.cn/news/576293.html

相关文章:

  • 【音视频】H.264详细介绍及测试代码
  • Excel限制编辑:保护表格的实用功能
  • 道路交通标志检测数据集-智能地图与导航 交通监控与执法 智慧城市交通管理-2,000 张图像
  • Qt:QCustomPlot库简介
  • HarmonyOS NEXT仓颉开发语言实战案例:图片预览器
  • linux面试常考
  • Go开发工程师-Golang基础知识篇
  • pycharm Windows 版快捷键大全
  • 大数据在UI前端的应用创新研究:用户偏好的动态调整与优化
  • 前端进阶之路-从传统前端到VUE-JS(第一期-VUE-JS环境配置)(Node-JS环境配置)(Node-JS/npm换源)
  • C++ STL深度剖析:Stack、queue、deque容器适配器核心接口
  • PCL 生成任意椭球点云
  • 关于庐山派多视频层(layer)和bind_layer的应用
  • 【SpringSecurity鉴权】
  • ChatboxAI 搭载 GPT 与 DeepSeek,引领科研与知识库管理变革
  • 视觉的基石:卷积神经网络与LeNet的破晓之光
  • 从【人工智能】到【计算机视觉】。深度学习引领的未来科技创新与变革
  • Note2.2 机器学习训练技巧:Batch and Momentum(Machine Learning by Hung-yi Lee)
  • Note2.1 处理critical point(Machine Learning by Hung-yi Lee)
  • 安卓中静态和动态添加子 View 到容器
  • 【C/C++】单元测试实战:Stub与Mock框架解析
  • 【RAG面试题】LLMs已经具备了较强能力,存在哪些不足点?
  • Windows11系统上安装WM虚拟机及Ubuntu 22.04系统
  • clion与keil分别配置项目宏定义
  • Day44 预训练模型
  • FLUX.1 Kontext(Dev 版)训练lora基础教程
  • Python基础知识之文件
  • 什么是故障注入测试
  • SCSAI万物对象模型和五维市场交易平台原型
  • mongodb生产备份工具PBM