JsonDiff
Line-level LCS diff between two JSON values; tinted by add / del / eq, like git diff.
Basic usage
CfJsonDiff runs JSON.stringify on left / right to produce two multi-line strings, then computes a longest-common-subsequence diff.
- Added line: green background,
+prefix - Removed line: red background,
-prefix - Common line: transparent background,
prefix
Suited to config version comparison, audit diffs, and API response replay.
背景
1 { 2- "name": "ChuFix", 3- "version": "0.1.0", 4+ "name": "ChuFix UI", 5+ "version": "0.2.0", 6 "features": [ 7 "theme", 8- "density" 9- ] 10+ "density", 11+ "i18n" 12+ ], 13+ "beta": false 14 }
<script setup lang="ts">
import { CfJsonDiff } from '@chufix-design/vue';
const left = {
name: 'ChuFix',
version: '0.1.0',
features: ['theme', 'density'],
};
const right = {
name: 'ChuFix UI',
version: '0.2.0',
features: ['theme', 'density', 'i18n'],
beta: false,
};
</script>
<template>
<CfJsonDiff :left="left" :right="right" />
</template> <script setup>
import { CfJsonDiff } from '@chufix-design/vue';
const left = {
name: 'ChuFix',
version: '0.1.0',
features: ['theme', 'density'],
};
const right = {
name: 'ChuFix UI',
version: '0.2.0',
features: ['theme', 'density', 'i18n'],
beta: false,
};
</script>
<template>
<CfJsonDiff :left="left" :right="right" />
</template> import { CfJsonDiff } from '@chufix-design/react';
export default function Demo() {
const left = {
name: 'ChuFix',
version: '0.1.0',
features: ['theme', 'density'],
};
const right = {
name: 'ChuFix UI',
version: '0.2.0',
features: ['theme', 'density', 'i18n'],
beta: false,
};
return (
<>
<CfJsonDiff left={left} right={right} />
</>
);
} Hide line numbers
Line numbers are on by default. In embedded docs or comment threads they can be noisy — turn them off and keep just the diff text.
背景
{ "user": { "id": "u_001", - "plan": "free" + "plan": "pro", + "renewedAt": "2026-05-01" }, "settings": { - "theme": "dark", + "theme": "light", "density": "comfortable" } }
<script setup lang="ts">
import { CfJsonDiff } from '@chufix-design/vue';
const before = {
user: { id: 'u_001', plan: 'free' },
settings: { theme: 'dark', density: 'comfortable' },
};
const after = {
user: { id: 'u_001', plan: 'pro', renewedAt: '2026-05-01' },
settings: { theme: 'light', density: 'comfortable' },
};
</script>
<template>
<CfJsonDiff :left="before" :right="after" :line-numbers="false" />
</template> <script setup>
import { CfJsonDiff } from '@chufix-design/vue';
const before = {
user: { id: 'u_001', plan: 'free' },
settings: { theme: 'dark', density: 'comfortable' },
};
const after = {
user: { id: 'u_001', plan: 'pro', renewedAt: '2026-05-01' },
settings: { theme: 'light', density: 'comfortable' },
};
</script>
<template>
<CfJsonDiff :left="before" :right="after" :line-numbers="false" />
</template> import { CfJsonDiff } from '@chufix-design/react';
export default function Demo() {
const before = {
user: { id: 'u_001', plan: 'free' },
settings: { theme: 'dark', density: 'comfortable' },
};
const after = {
user: { id: 'u_001', plan: 'pro', renewedAt: '2026-05-01' },
settings: { theme: 'light', density: 'comfortable' },
};
return (
<>
<CfJsonDiff left={before} right={after} lineNumbers={false} />
</>
);
} Sizes
Three font sizes consistent with the rest of the JSON family.
背景
size = sm
1 { 2 "id": 1, 3- "status": "pending" 4+ "status": "approved", 5+ "approvedBy": "admin" 6 }
size = md
1 { 2 "id": 1, 3- "status": "pending" 4+ "status": "approved", 5+ "approvedBy": "admin" 6 }
size = lg
1 { 2 "id": 1, 3- "status": "pending" 4+ "status": "approved", 5+ "approvedBy": "admin" 6 }
<script setup lang="ts">
import { CfJsonDiff } from '@chufix-design/vue';
const left = { id: 1, status: 'pending' };
const right = { id: 1, status: 'approved', approvedBy: 'admin' };
</script>
<template>
<div style="display:flex; flex-direction:column; gap: 12px;">
<div>
<div style="font-size: 12px; color: var(--fg-3); margin-bottom: 4px;">size = sm</div>
<CfJsonDiff :left="left" :right="right" size="sm" />
</div>
<div>
<div style="font-size: 12px; color: var(--fg-3); margin-bottom: 4px;">size = md</div>
<CfJsonDiff :left="left" :right="right" size="md" />
</div>
<div>
<div style="font-size: 12px; color: var(--fg-3); margin-bottom: 4px;">size = lg</div>
<CfJsonDiff :left="left" :right="right" size="lg" />
</div>
</div>
</template> <script setup>
import { CfJsonDiff } from '@chufix-design/vue';
const left = { id: 1, status: 'pending' };
const right = { id: 1, status: 'approved', approvedBy: 'admin' };
</script>
<template>
<div style="display:flex; flex-direction:column; gap: 12px;">
<div>
<div style="font-size: 12px; color: var(--fg-3); margin-bottom: 4px;">size = sm</div>
<CfJsonDiff :left="left" :right="right" size="sm" />
</div>
<div>
<div style="font-size: 12px; color: var(--fg-3); margin-bottom: 4px;">size = md</div>
<CfJsonDiff :left="left" :right="right" size="md" />
</div>
<div>
<div style="font-size: 12px; color: var(--fg-3); margin-bottom: 4px;">size = lg</div>
<CfJsonDiff :left="left" :right="right" size="lg" />
</div>
</div>
</template> import { CfJsonDiff } from '@chufix-design/react';
export default function Demo() {
const left = { id: 1, status: 'pending' };
const right = { id: 1, status: 'approved', approvedBy: 'admin' };
return (
<>
<CfJsonDiff left={left} right={right} size="sm" />
<CfJsonDiff left={left} right={right} size="md" />
<CfJsonDiff left={left} right={right} size="lg" />
</>
);
} API
| Prop | Type | Default | Description |
|---|---|---|---|
left | unknown | — | Old value, rendered as removed lines |
right | unknown | — | New value, rendered as added lines |
lineNumbers | boolean | true | Show line numbers |
bordered | boolean | true | Border |
size | 'sm' | 'md' | 'lg' | 'md' | Font size |
className | string | — | Forwarded to root <pre> |
Type exports:
type DiffOp = 'eq' | 'add' | 'del';
interface DiffLine { op: DiffOp; text: string; depth: number; }
反馈与讨论
JsonDiff · Discussion