diff --git a/package-lock.json b/package-lock.json
index eb0ac12..d22c4e3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"@capacitor/cli": "^5.7.2",
"@capacitor/core": "^5.7.2",
"@capacitor/ios": "^5.7.2",
+ "@ionic/vue": "^8.7.6",
"@vue/cli-service": "^5.0.9",
"@vue/compiler-sfc": "^3.5.22",
"basic-ftp": "^5.0.5",
@@ -2150,6 +2151,26 @@
"node": ">=16.0.0"
}
},
+ "node_modules/@ionic/core": {
+ "version": "8.7.6",
+ "resolved": "https://registry.npmmirror.com/@ionic/core/-/core-8.7.6.tgz",
+ "integrity": "sha512-ufV64Pl0BYSoNla+DaTRXTS3hX6MQZZJPhAR3fJQ4N5Fg/vwMcHADQffstKZeoPqk6mbJoLqoTBjcWvaLRdO0g==",
+ "license": "MIT",
+ "dependencies": {
+ "@stencil/core": "4.38.0",
+ "ionicons": "^8.0.13",
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/@ionic/core/node_modules/ionicons": {
+ "version": "8.0.13",
+ "resolved": "https://registry.npmmirror.com/ionicons/-/ionicons-8.0.13.tgz",
+ "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@stencil/core": "^4.35.3"
+ }
+ },
"node_modules/@ionic/utils-array": {
"version": "2.1.6",
"resolved": "https://registry.npmmirror.com/@ionic/utils-array/-/utils-array-2.1.6.tgz",
@@ -2359,6 +2380,26 @@
"node": ">=16.0.0"
}
},
+ "node_modules/@ionic/vue": {
+ "version": "8.7.6",
+ "resolved": "https://registry.npmmirror.com/@ionic/vue/-/vue-8.7.6.tgz",
+ "integrity": "sha512-gK5x5Y0ZpZAW12gjvyBO9oUfwDZxMS7y0xcO0P9qzo++h3ZLcFcSGjHs8D4isUY/mF6mRagt1Y/5b0xDhgUBBw==",
+ "license": "MIT",
+ "dependencies": {
+ "@ionic/core": "8.7.6",
+ "@stencil/vue-output-target": "0.10.7",
+ "ionicons": "^8.0.13"
+ }
+ },
+ "node_modules/@ionic/vue/node_modules/ionicons": {
+ "version": "8.0.13",
+ "resolved": "https://registry.npmmirror.com/ionicons/-/ionicons-8.0.13.tgz",
+ "integrity": "sha512-2QQVyG2P4wszne79jemMjWYLp0DBbDhr4/yFroPCxvPP1wtMxgdIV3l5n+XZ5E9mgoXU79w7yTWpm2XzJsISxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@stencil/core": "^4.35.3"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -2936,6 +2977,28 @@
"@rollup/rollup-win32-x64-msvc": "4.34.9"
}
},
+ "node_modules/@stencil/vue-output-target": {
+ "version": "0.10.7",
+ "resolved": "https://registry.npmmirror.com/@stencil/vue-output-target/-/vue-output-target-0.10.7.tgz",
+ "integrity": "sha512-IYxDe+SLCkwhwsWRdynE31rTK1zN3hVwwojQ/V9lrN8Gnx4PTvrUQHiRno9jFo1dk+EaBZWX9gZSmXta0ZaZew==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@stencil/core": ">=2.0.0 || >=3 || >= 4.0.0-beta.0 || >= 4.0.0",
+ "vue": "^3.4.38",
+ "vue-router": "^4.5.0"
+ },
+ "peerDependenciesMeta": {
+ "@stencil/core": {
+ "optional": true
+ },
+ "vue": {
+ "optional": false
+ },
+ "vue-router": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
diff --git a/package.json b/package.json
index 0de50b6..1997e9e 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"@capacitor/cli": "^5.7.2",
"@capacitor/core": "^5.7.2",
"@capacitor/ios": "^5.7.2",
+ "@ionic/vue": "^8.7.6",
"@vue/cli-service": "^5.0.9",
"@vue/compiler-sfc": "^3.5.22",
"basic-ftp": "^5.0.5",
diff --git a/src/App.vue b/src/App.vue
index f6ac6bc..b087e95 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -6,5 +6,4 @@
\ No newline at end of file
+
diff --git a/src/components/Header.vue b/src/components/Header.vue
index f4e711e..4a1397f 100644
--- a/src/components/Header.vue
+++ b/src/components/Header.vue
@@ -5,8 +5,8 @@
-
') updateToolbarState() @@ -175,6 +190,7 @@ const formatText = (command, value = null) => { return } + // 处理列表格式切换:如果已是列表则取消列表 if (command === 'insertUnorderedList' && isAlreadyInFormat('list')) { document.execCommand('insertUnorderedList', false, null) updateToolbarState() @@ -189,13 +205,16 @@ const formatText = (command, value = null) => { return } - // 检查嵌套限制 + // 检查嵌套限制,防止在列表、引用中再次插入列表或引用 if ((command === 'insertUnorderedList' || (command === 'formatBlock' && value === 'blockquote')) && isInListOrQuote()) { return } + // 执行格式化命令 document.execCommand(command, false, value) + // 更新工具栏状态以反映当前格式 updateToolbarState() + // 触发输入事件以更新内容 handleInput() } @@ -283,39 +302,40 @@ const insertQuote = () => { } // 插入待办事项列表 +// 创建一个可交互的待办事项元素,包含复选框图标和可编辑内容区域 const insertTodoList = () => { const selection = window.getSelection() if (selection.rangeCount > 0) { const range = selection.getRangeAt(0) - // 检查嵌套限制 + // 检查嵌套限制,防止在列表或引用中插入待办事项 if (isInListOrQuote()) return // 创建待办事项容器 const todoContainer = document.createElement('div') - todoContainer.contentEditable = false + todoContainer.contentEditable = false // 容器本身不可编辑 todoContainer.className = 'todo-container' - // 创建图标元素 + // 创建图标元素(复选框) const icon = document.createElement('img') icon.className = 'todo-icon' - icon.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png' + icon.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png' // 未完成状态图标 icon.alt = '待办事项' - // 创建内容容器 + // 创建内容容器(可编辑区域) const contentSpan = document.createElement('div') - contentSpan.contentEditable = true + contentSpan.contentEditable = true // 内容区域可编辑 contentSpan.className = 'todo-content' - contentSpan.textContent = '待办事项' + contentSpan.textContent = '待办事项' // 默认文本 - // 组装元素 + // 组装元素:将图标和内容区域添加到容器中 todoContainer.appendChild(icon) todoContainer.appendChild(contentSpan) // 插入到当前光标位置 range.insertNode(todoContainer) - // 添加换行 + // 添加换行,确保待办事项下方有空白行 const br = document.createElement('br') todoContainer.parentNode.insertBefore(br, todoContainer.nextSibling) @@ -338,19 +358,21 @@ const insertTodoList = () => { } }, 0) - // 添加事件监听器到图标 + // 添加事件监听器到图标,实现待办事项完成状态切换 icon.addEventListener('click', function () { - // 根据当前状态切换图标 + // 根据当前状态切换图标和样式 if (this.src.includes('rtf_icon_gtasks.png')) { - this.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks_light.png' - contentSpan.style.color = 'var(--text-tertiary)' - contentSpan.style.textDecoration = 'line-through' + // 切换到完成状态 + this.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks_light.png' // 完成状态图标 + contentSpan.style.color = 'var(--text-tertiary)' // 灰色文字 + contentSpan.style.textDecoration = 'line-through' // 添加删除线 } else { - this.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png' - contentSpan.style.color = 'var(--note-content)' - contentSpan.style.textDecoration = 'none' + // 切换到未完成状态 + this.src = '/assets/icons/drawable-xxhdpi/rtf_icon_gtasks.png' // 未完成状态图标 + contentSpan.style.color = 'var(--note-content)' // 正常文字颜色 + contentSpan.style.textDecoration = 'none' // 移除删除线 } - handleInput() + handleInput() // 触发内容更新 }) // 添加事件监听器到内容区域,监听内容变化和按键事件 @@ -365,8 +387,8 @@ const insertTodoList = () => { }, 0) } - contentSpan.addEventListener('input', checkContent) - contentSpan.addEventListener('blur', checkContent) + contentSpan.addEventListener('input', checkContent) // 内容输入时检查 + contentSpan.addEventListener('blur', checkContent) // 失去焦点时检查 // 添加焦点事件监听器,确保工具栏在待办事项获得焦点时保持可见 contentSpan.addEventListener('focus', () => { diff --git a/src/main.js b/src/main.js index 39e2da9..a08a540 100644 --- a/src/main.js +++ b/src/main.js @@ -3,30 +3,48 @@ import { createRouter, createWebHashHistory } from 'vue-router' import { createPinia } from 'pinia' import App from './App.vue' -// Pages +// 导入页面组件 +// 便签列表页面 import NoteListPage from './pages/NoteListPage.vue' +// 便签编辑页面(用于新建和编辑便签) import NoteEditorPage from './pages/NoteEditorPage.vue' +// 文件夹管理页面 import FolderPage from './pages/FolderPage.vue' +// 设置页面 import SettingsPage from './pages/SettingsPage.vue' -// Router +// 配置路由规则 +// 定义应用的所有路由路径和对应的组件 const routes = [ + // 根路径重定向到便签列表页面 { path: '/', redirect: '/notes' }, + // 便签列表页面路由 { path: '/notes', component: NoteListPage }, + // 编辑便签页面路由(带便签ID参数) { path: '/notes/:id', component: NoteEditorPage, props: true }, + // 新建便签页面路由 { path: '/editor', component: NoteEditorPage }, + // 编辑便签页面路由(带便签ID参数) { path: '/editor/:id', component: NoteEditorPage, props: true }, + // 文件夹管理页面路由 { path: '/folders', component: FolderPage }, + // 设置页面路由 { path: '/settings', component: SettingsPage } ] +// 创建路由实例 +// 使用Hash模式以支持静态文件部署 const router = createRouter({ history: createWebHashHistory(), routes }) -// App +// 创建并挂载Vue应用实例 +// 配置Pinia状态管理和Vue Router路由 const app = createApp(App) +// 使用Pinia进行状态管理 app.use(createPinia()) +// 使用Vue Router进行路由管理 app.use(router) +// 挂载应用到DOM元素 app.mount('#app') \ No newline at end of file diff --git a/src/pages/FolderPage.vue b/src/pages/FolderPage.vue index d881412..e78f698 100644 --- a/src/pages/FolderPage.vue +++ b/src/pages/FolderPage.vue @@ -29,12 +29,14 @@