feat: lodash 示例

master
LCJ-MinYa 1 week ago
parent 1fd6983305
commit c3aac354e1

@ -186,6 +186,10 @@ const titleArr = [
key: 'formChangeTrack', key: 'formChangeTrack',
title: '表单敏感字段变更追踪标记', title: '表单敏感字段变更追踪标记',
}, },
{
key: 'lodashExamples',
title: 'Lodash 经典用法',
},
]; ];
// @/views/demo/**/*.vue // @/views/demo/**/*.vue

@ -0,0 +1,248 @@
<template>
<div class="p-5 space-y-5 !bg-gray-100">
<!-- 1. 对象深度比较 -->
<el-card header="1. 对象深度比较 (isEqual)">
<template #header>
<div class="flex items-center justify-between">
<span>1. 对象深度比较 (isEqual)</span>
<el-tag>_.isEqual(obj1, obj2)</el-tag>
</div>
</template>
<div class="flex gap-4">
<div class="flex-1">
<h4 class="mb-2 font-bold">对象 A</h4>
<el-input
v-model="objAStr"
type="textarea"
:rows="5"
placeholder="输入 JSON 对象"
/>
</div>
<div class="flex-1">
<h4 class="mb-2 font-bold">对象 B</h4>
<el-input
v-model="objBStr"
type="textarea"
:rows="5"
placeholder="输入 JSON 对象"
/>
</div>
</div>
<div class="mt-4">
<el-button type="primary" @click="checkEqual"></el-button>
<div class="mt-2">
结果:
<span v-if="compareResult !== null" :class="compareResult ? 'text-green-500 font-bold' : 'text-red-500 font-bold'">
{{ compareResult ? '完全一致' : '不一致' }}
</span>
<span v-else class="text-gray-400">待比较</span>
</div>
</div>
</el-card>
<!-- 2. 深拷贝 -->
<el-card header="2. 深拷贝 (cloneDeep)">
<template #header>
<div class="flex items-center justify-between">
<span>2. 深拷贝 (cloneDeep)</span>
<el-tag>_.cloneDeep(obj)</el-tag>
</div>
</template>
<div class="space-y-2">
<p class="text-gray-600">原始对象包含嵌套属性修改副本不会影响原对象</p>
<div class="flex gap-4">
<div class="flex-1 border p-2 rounded">
<h4 class="font-bold">原始对象 (source)</h4>
<pre class="bg-gray-50 p-2 text-sm">{{ sourceObj }}</pre>
<el-button size="small" class="mt-2" @click="changeSource">.info.age + 1</el-button>
</div>
<div class="flex-1 border p-2 rounded">
<h4 class="font-bold">深拷贝副本 (cloned)</h4>
<pre class="bg-gray-50 p-2 text-sm">{{ clonedObj }}</pre>
<el-button size="small" class="mt-2" @click="changeCloned">.info.age + 1</el-button>
</div>
</div>
<div class="mt-2 text-sm text-blue-500">
操作提示点击上方按钮修改属性观察两个对象互不干扰
</div>
</div>
</el-card>
<!-- 3. 防抖与节流 -->
<el-card header="3. 防抖与节流 (debounce & throttle)">
<template #header>
<div class="flex items-center justify-between">
<span>3. 防抖与节流 (debounce & throttle)</span>
<div>
<el-tag class="mr-2">_.debounce</el-tag>
<el-tag>_.throttle</el-tag>
</div>
</div>
</template>
<div class="flex gap-8">
<!-- 防抖 -->
<div class="flex-1">
<h4 class="font-bold mb-2">防抖 (Debounce)</h4>
<p class="text-sm text-gray-500 mb-2">停止输入 500ms 后触发搜索</p>
<el-input
v-model="debounceInput"
placeholder="快速输入文字试试..."
@input="handleDebounceInput"
/>
<div class="mt-2 text-sm">
实际触发次数: <span class="font-bold text-blue-600">{{ debounceCount }}</span>
</div>
<div class="mt-1 text-xs text-gray-400">最后触发时间: {{ debounceTime }}</div>
</div>
<!-- 节流 -->
<div class="flex-1">
<h4 class="font-bold mb-2">节流 (Throttle)</h4>
<p class="text-sm text-gray-500 mb-2"> 1000ms 最多触发一次点击</p>
<el-button type="primary" @click="handleThrottleClick">
疯狂点击我 (1s 响应一次)
</el-button>
<div class="mt-2 text-sm">
实际触发次数: <span class="font-bold text-orange-600">{{ throttleCount }}</span>
</div>
<div class="mt-1 text-xs text-gray-400">最后触发时间: {{ throttleTime }}</div>
</div>
</div>
</el-card>
<!-- 4. 常用数组操作 -->
<el-card header="4. 常用数组操作">
<template #header>
<div class="flex items-center justify-between">
<span>4. 常用数组操作</span>
<div>
<el-tag class="mr-2">_.uniq</el-tag>
<el-tag class="mr-2">_.shuffle</el-tag>
<el-tag>_.chunk</el-tag>
</div>
</div>
</template>
<div class="space-y-4">
<!-- Uniq -->
<div>
<h5 class="font-bold text-sm">数组去重 (_.uniq)</h5>
<div class="flex items-center gap-2 mt-1">
<span class="text-gray-500">原数组: [1, 2, 2, 3, 1, 4]</span>
<el-icon><ArrowRight /></el-icon>
<span class="font-mono bg-blue-50 px-2 py-1 rounded">{{ uniqResult }}</span>
</div>
</div>
<!-- Shuffle -->
<div>
<h5 class="font-bold text-sm">数组乱序 (_.shuffle)</h5>
<div class="flex items-center gap-2 mt-1">
<span class="text-gray-500">原数组: [1, 2, 3, 4, 5]</span>
<el-button link type="primary" @click="doShuffle"></el-button>
<span class="font-mono bg-orange-50 px-2 py-1 rounded">{{ shuffleResult }}</span>
</div>
</div>
<!-- Chunk -->
<div>
<h5 class="font-bold text-sm">数组分块 (_.chunk)</h5>
<p class="text-xs text-gray-400"> ['a', 'b', 'c', 'd', 'e'] 按大小 2 分块</p>
<div class="mt-1 font-mono bg-green-50 px-2 py-1 rounded w-fit">
{{ chunkResult }}
</div>
</div>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { isEqual, cloneDeep, debounce, throttle, uniq, shuffle, chunk } from 'lodash-es';
import { message } from '@/utils/message';
import { ArrowRight } from '@element-plus/icons-vue';
import dayjs from 'dayjs';
// --- 1. isEqual ---
const objAStr = ref(`{
"name": "Gemini",
"skills": ["coding", "writing"]
}`);
const objBStr = ref(`{
"name": "Gemini",
"skills": ["coding", "writing"]
}`);
const compareResult = ref<boolean | null>(null);
const checkEqual = () => {
try {
const objA = JSON.parse(objAStr.value);
const objB = JSON.parse(objBStr.value);
compareResult.value = isEqual(objA, objB);
if (compareResult.value) {
message('对象完全一致', { type: 'success' });
} else {
message('对象不一致', { type: 'warning' });
}
} catch (e) {
message('JSON 格式错误,请检查输入', { type: 'error' });
compareResult.value = null;
}
};
// --- 2. cloneDeep ---
const sourceObj = ref({
name: 'Project X',
info: {
age: 1,
status: 'active'
}
});
//
const clonedObj = ref(cloneDeep(sourceObj.value));
const changeSource = () => {
sourceObj.value.info.age++;
};
const changeCloned = () => {
clonedObj.value.info.age++;
};
// --- 3. debounce & throttle ---
const debounceInput = ref('');
const debounceCount = ref(0);
const debounceTime = ref('-');
const throttleCount = ref(0);
const throttleTime = ref('-');
//
const handleDebounceInput = debounce((val: string) => {
debounceCount.value++;
debounceTime.value = dayjs().format('HH:mm:ss.SSS');
console.log('Debounced input:', val);
}, 500);
//
const handleThrottleClick = throttle(() => {
throttleCount.value++;
throttleTime.value = dayjs().format('HH:mm:ss.SSS');
message('节流点击触发成功');
}, 1000);
// --- 4. Array Operations ---
const uniqResult = computed(() => JSON.stringify(uniq([1, 2, 2, 3, 1, 4])));
const shuffleSource = [1, 2, 3, 4, 5];
const shuffleResult = ref(JSON.stringify(shuffleSource));
const doShuffle = () => {
shuffleResult.value = JSON.stringify(shuffle(shuffleSource));
};
const chunkResult = computed(() => JSON.stringify(chunk(['a', 'b', 'c', 'd', 'e'], 2)));
</script>
<style scoped>
/* Scoped styles if needed, Tailwind is mostly used */
</style>
Loading…
Cancel
Save