React如何在页面展示动态填充对象的所有键值对(含嵌套对象)
递归遍历对象实现全量键值对展示
核心实现逻辑为通过递归逐层遍历对象属性,遇到嵌套子对象时继续向下遍历,直到拿到所有非对象类型的最终值,同时支持保留层级结构或扁平化输出两种展示形式。
原生JS通用实现
/** * 递归遍历对象,返回扁平化的全量键值对 * @param {object} obj 要遍历的目标对象 * @param {string} parentKey 上层键名前缀,用于拼接嵌套结构的完整键名 * @returns {Array<{key: string, value: any}>} 所有键值对组成的数组 */ function traverseObject(obj, parentKey = '') { const result = [] for (const key in obj) { const currentKey = parentKey ? `${parentKey}.${key}` : key const value = obj[key] // 判断是否为纯对象,排除null、数组等类型,有数组遍历需求可自行调整判断逻辑 if (typeof value === 'object' && value !== null && Object.prototype.toString.call(value) === '[object Object]') { result.push(...traverseObject(value, currentKey)) } else { result.push({ key: currentKey, value: value }) } } return result } // 示例对象测试 const info = { address: { city: {__old: 'city1', __new: 'city2'}, country: {__old: 'country1', __new: 'country2'}, lineOne: {__old: 'lineOne1', __new: 'lineOne2'} }, personalId: {__old: '55555555', __new: '555555556'} } console.log(traverseObject(info))
输出结果
针对你给出的示例对象,运行后会得到如下结构的键值对:
- info.address.city.__old: "city1"
- info.address.city.__new: "city2"
- info.address.country.__old: "country1"
- info.address.country.__new: "country2"
- info.address.lineOne.__old: "lineOne1"
- info.address.lineOne.__new: "lineOne2"
- info.personalId.__old: "55555555"
- info.personalId.__new: "555555556"
前端框架实现示例
React 版本(带层级缩进展示)
function ObjectViewer({ data }) { const renderNode = (obj, level = 0) => { return Object.entries(obj).map(([key, value]) => { const isObj = typeof value === 'object' && value !== null && !Array.isArray(value) return ( <div key={key} style={{ marginLeft: level * 16 }}> <span style={{ fontWeight: 'bold' }}>{key}: </span> {isObj ? renderNode(value, level + 1) : JSON.stringify(value)} </div> ) }) } return <div>{renderNode(data)}</div> }
Vue3 版本(带层级缩进展示)
根组件:
<template> <ObjectViewer :data="info" /> </template> <script setup> import ObjectViewer from './ObjectViewer.vue' const info = { // 你的动态对象 } </script>
ObjectViewer.vue 组件:
<template> <div v-for="(value, key) in data" :key="key" :style="{ marginLeft: level * 16 + 'px' }"> <strong>{{ key }}:</strong> <template v-if="isPlainObject(value)"> <ObjectViewer :data="value" :level="level + 1" /> </template> <span v-else>{{ JSON.stringify(value) }}</span> </div> </template> <script setup> const props = defineProps({ data: { type: Object, required: true }, level: { type: Number, default: 0 } }) const isPlainObject = val => typeof val === 'object' && val !== null && Object.prototype.toString.call(val) === '[object Object]' </script>
内容的提问来源于stack exchange,提问作者edonzeqiri
相关产品推荐
相关产品推荐

