Vue3中如何获取动态生成的子组件的输入数据?
解决方案
1. 修正父组件的列表渲染逻辑
你当前父组件里用<Row :is="item"/>是错误的,:is是用于动态切换组件类型的,这里你只需要重复渲染Row组件,直接用v-for循环控制数量即可,同时要给每个子组件绑定ref来获取实例。
2. 绑定子组件Ref以获取实例
在父组件中定义一个ref数组存储所有子组件实例,然后在v-for的Row组件上绑定这个ref。
3. 实现数据收集方法
通过遍历ref数组,取出每个子组件暴露的响应式数据,整理成普通对象后就可以存入localStorage。
修改后的完整代码
子组件(Row.vue)
你的暴露逻辑没问题,无需修改:
<template> <div class="row"> <p>Key:</p> <input type="text" v-model.trim="key"> <p>Type:</p> <select name="type" v-model="type"> <option value="Integer">Integer</option> <option value="String">String</option> <option value="List">List</option> </select> <p>Required:</p> <input type="checkbox" name="required" v-model="required"> <button>More options</button> </div> </template> <script setup> import { ref } from 'vue'; const key = ref('key'); const type = ref('Integer'); const required = ref(true); defineExpose({ key, type, required }) </script> <style scoped> .row { display: flex; } p{ padding: 20px; } </style>
父组件
<template> <div> <!-- 修正渲染逻辑,绑定ref到每个子组件 --> <Row v-for="(_, index) in items" :key="index" ref="rowRefs"/> <button @click="addComponent">+</button> <button @click="logComponentsData">获取所有数据</button> </div> </template> <script setup> import { ref } from 'vue'; import Row from './Row.vue'; // 用数组长度控制组件数量,元素内容无关紧要 const items = ref([]); // 存储所有子组件实例的ref数组 const rowRefs = ref([]); const addComponent = () => { // 随便push一个值,只要增加数组长度即可 items.value.push(null); }; const logComponentsData = () => { // 遍历子组件实例,收集数据 const allData = rowRefs.value.map(component => ({ key: component.key.value, type: component.type.value, required: component.required.value })); console.log(allData); // 存入localStorage localStorage.setItem('formData', JSON.stringify(allData)); }; </script>
关键说明
- 父组件的
v-for只需要循环items的长度,元素内容不需要是对象,因为你不需要动态切换组件类型,所以去掉了:is属性。 rowRefs是一个ref数组,Vue会自动把每个Row组件的实例存入这个数组中,顺序和v-for的顺序一致。- 因为子组件暴露的
key、type、required都是ref对象,所以需要取.value来获取实际值,整理成普通对象后才能用JSON.stringify存入localStorage。
内容的提问来源于stack exchange,提问作者Ignacio Sambrailo
相关产品推荐
相关产品推荐

