feat: 创建示例页面实践(修改闭包对象属性)

master
LCJ-MinYa 2 weeks ago
parent 3ed93709bb
commit 7f2b339eb2

@ -12,6 +12,7 @@
- **UI 组件**: Element Plus, TailwindCSS, SCSS
- **代码规范**: ESLint (v9), Prettier, Stylelint
- **图标方案**: Iconify, SVG
- **代码缩进**: 使用tab四个空格缩进
## 📂 项目结构
```text

@ -4,7 +4,7 @@
1. 类型确认:询问用户是创建 “单文件 (.vue)” 还是 “文件夹 (含 index.vue)”。
2. 模块定位:确认目标模块(位于 src/views/ 下,如 demo, tool, python 等,严格执行二级目录结构,不允许深层嵌套)。
3. 命名决策:
* 根据功能点,提供 3 个 CamelCase驼峰命名 建议。
* 根据功能点,提供 3 个 camelCase驼峰命名 建议。
* 唯一性检查:检查 src/views/{module}/ 目录下是否已有同名文件或文件夹,确保不冲突。
第二阶段:文件构建 (Step 4)
@ -20,7 +20,7 @@
第三阶段:自动化路由配置 (Step 5)
* 操作目标:修改 src/router/modules/{module}.ts。
* 执行逻辑:找到文件中的 titleArr 数组变量,并在末尾追加新页面的配置对象:
* 执行逻辑:找到文件中的 titleArr 数组变量,并在末尾追加新页面的配置对象**切记只能追加,不能修改原始代码**
```javascript
{
key: '{pageName}',

@ -178,6 +178,10 @@ const titleArr = [
key: 'eventListenner',
title: '事件监听器的一些总结',
},
{
key: 'ModifyClosureObject',
title: '如何修改闭包对象',
},
];
// @/views/demo/**/*.vue

@ -0,0 +1,141 @@
<template>
<div class="p-5 space-y-5 !bg-gray-100">
<el-card header="如何修改闭包内对象属性">
<div class="mb-4">
<p class="text-gray-600 mb-2">
JavaScript 闭包内的变量通常是私有的如果闭包内定义了一个对象我们有几种方式可以修改它的属性
</p>
<ul class="list-disc ml-6 text-sm text-gray-500">
<li>通过闭包返回的 Setter 方法进行修改</li>
<li>如果闭包直接返回了该对象的引用可以直接修改其属性</li>
<li>通过原型链或特定的 Hack 方式不推荐但存在</li>
</ul>
</div>
<el-divider content-position="left">示例展示</el-divider>
<div class="space-y-4">
<div class="bg-white p-4 rounded border">
<h4 class="font-bold mb-2">闭包内部状态</h4>
<pre class="bg-gray-50 p-2 rounded text-xs">{{ JSON.stringify(closureState, null, 2) }}</pre>
</div>
<div class="flex gap-4">
<el-button
type="primary"
@click="handleUpdateViaSetter"
>
通过 Setter 修改年龄 (age + 1)
</el-button>
<el-button
type="success"
@click="handleUpdateDirectly"
>
直接修改引用属性 (name = 'New Name')
</el-button>
<el-button
type="warning"
@click="resetState"
>
重置状态
</el-button>
</div>
</div>
<el-divider content-position="left">核心代码原理</el-divider>
<pre class="bg-gray-800 text-white p-4 rounded text-xs overflow-x-auto">
function createClosure() {
//
const privateObj = {
name: 'Initial Name',
age: 25
};
return {
// 1
updateAge(newAge) {
privateObj.age = newAge;
},
// 2
getData() {
return privateObj;
}
};
}
</pre
>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { message } from '@/utils/message';
/**
* 模拟一个产生闭包的函数
*/
function createClosure() {
const privateObj = {
name: '张三',
age: 20,
};
return {
//
getData() {
return privateObj;
},
//
setAge(age: number) {
privateObj.age = age;
},
//
reset() {
privateObj.name = '张三';
privateObj.age = 20;
},
};
}
const closureManager = createClosure();
const closureState = ref({ name: '', age: 0 });
//
const refreshDisplay = () => {
const data = closureManager.getData();
// Vue
closureState.value = { ...data };
};
const handleUpdateViaSetter = () => {
const currentAge = closureManager.getData().age;
closureManager.setAge(currentAge + 1);
refreshDisplay();
message('通过 Setter 修改成功', { type: 'success' });
};
const handleUpdateDirectly = () => {
const data = closureManager.getData();
//
data.name = '被直接修改的名称 ' + Math.floor(Math.random() * 100);
refreshDisplay();
message('通过引用直接修改成功', { type: 'success' });
};
const resetState = () => {
closureManager.reset();
refreshDisplay();
message('状态已重置');
};
onMounted(() => {
refreshDisplay();
});
</script>
<style scoped lang="scss">
pre {
font-family: 'Courier New', Courier, monospace;
}
</style>
Loading…
Cancel
Save