33 <ul class =" nav" >
44 <li :class =" { act: activeTab === 'hot' }" @click =" changeTab('hot')" >最热</li >
55 <li :class =" { act: activeTab === 'news' }" @click =" changeTab('news')" >最新</li >
6+ <li :class =" { act: activeTab === 'book' }" @click =" changeTab('book')" >收藏</li >
67 <li :class =" { act: activeTab === 'menu' }" @click =" changeTab('menu')" >菜单</li >
78 </ul >
89 <div class =" fixed-icon" >
2627 <NewsPosts v-if =" newslist .length > 0 " :list =" newslist " />
2728 <p v-else >{{ nonewlist }}</p >
2829 </div >
30+ <div class =" content" :class =" { act: activeTab === 'book' }" >
31+ <Bookmark :bookmarkData =" bookmarkDataList " />
32+ </div >
2933 <div class =" content" :class =" { act: activeTab === 'menu' }" >
3034 <SettingMenu />
3135 </div >
3539<script >
3640import HotPosts from " ./components/HotPosts.vue" ;
3741import NewsPosts from " ./components/NewsPosts.vue" ;
42+ import Bookmark from " ./components/Bookmark.vue" ;
3843import SettingMenu from " ./components/SettingMenu.vue" ;
3944import Refresh from " ./components/SVG/Refresh.vue" ;
4045
@@ -52,11 +57,15 @@ export default {
5257 lastScrollPosition: 0 , // 存储滚动位置
5358
5459 themes: " light" , // 主题风格
60+
61+ // 从 bookmark 页面共享的书签数据(localStorage: bookmarkData)
62+ bookmarkDataList: [],
5563 };
5664 },
5765 components: {
5866 HotPosts,
5967 NewsPosts,
68+ Bookmark,
6069 SettingMenu,
6170 Refresh,
6271 },
@@ -135,6 +144,97 @@ export default {
135144 });
136145 }
137146 },
147+
148+ // 获取本地存储中的书签数据
149+ getBookmarkDataFromLocalStorage () {
150+ try {
151+ const raw = localStorage .getItem (" bookmarkData" );
152+ if (! raw) return [];
153+ const parsed = JSON .parse (raw);
154+ return Array .isArray (parsed) ? parsed : [];
155+ } catch (e) {
156+ return [];
157+ }
158+ },
159+
160+ // localStorage 变更监听(来自 bookmark 页面写入)
161+ handleLocalStorageChange (e ) {
162+ if (e && e .key === " bookmarkData" ) {
163+ this .bookmarkDataList = this .getBookmarkDataFromLocalStorage ();
164+ }
165+ },
166+
167+ // chrome.storage 变更监听(来自内容脚本/其他页面写入)
168+ handleChromeStorageChange (changes , area ) {
169+ if (area !== " local" ) return ;
170+ if (changes .bookmarkData || changes .bookmarks ) {
171+ // 主动同步 storage.local 中的临时数据到本地存储
172+ this .syncFromStorageLocal ().then (() => {
173+ this .bookmarkDataList = this .getBookmarkDataFromLocalStorage ();
174+ });
175+ }
176+ },
177+
178+ // 将 storage.local 的数据合并进 localStorage('bookmarkData')
179+ async syncFromStorageLocal () {
180+ return new Promise ((resolve ) => {
181+ const browserAPI = typeof browser !== " undefined" ? browser : chrome;
182+ browserAPI .storage ? .local .get ([" bookmarkData" , " bookmarks" ], (result ) => {
183+ const local = this .getBookmarkDataFromLocalStorage ();
184+
185+ // 确保有默认列表 id=0
186+ let defaultList = local .find ((item ) => item .id === 0 );
187+ if (! defaultList) {
188+ defaultList = { id: 0 , name: " 默认" , list: [], sort: 1 };
189+ local .unshift (defaultList);
190+ }
191+
192+ // 处理单个书签(向后兼容)
193+ if (result && result .bookmarkData ) {
194+ const single = result .bookmarkData ;
195+ // 去重:先从所有列表移除相同 URL
196+ local .forEach ((folder ) => {
197+ folder .list = (folder .list || []).filter ((item ) => item .url !== single .url );
198+ });
199+ // 添加到默认列表开头
200+ defaultList .list .unshift (single);
201+ }
202+
203+ // 处理批量书签
204+ if (result && Array .isArray (result .bookmarks ) && result .bookmarks .length > 0 ) {
205+ result .bookmarks .forEach ((bm ) => {
206+ // 如果已存在相同 URL,则更新;否则添加
207+ let updated = false ;
208+ local .forEach ((folder ) => {
209+ const idx = (folder .list || []).findIndex ((i ) => i .url === bm .url );
210+ if (idx !== - 1 ) {
211+ folder .list [idx] = { ... bm };
212+ updated = true ;
213+ }
214+ });
215+ if (! updated) {
216+ defaultList .list .unshift ({ ... bm });
217+ }
218+ });
219+ }
220+
221+ // 持久化
222+ try {
223+ localStorage .setItem (" bookmarkData" , JSON .stringify (local));
224+ } catch (e) {}
225+
226+ // 清理已消费的临时数据
227+ const removeKeys = [];
228+ if (result && result .bookmarkData ) removeKeys .push (" bookmarkData" );
229+ if (result && result .bookmarks ) removeKeys .push (" bookmarks" );
230+ if (removeKeys .length > 0 ) {
231+ browserAPI .storage ? .local .remove (removeKeys, () => resolve ());
232+ } else {
233+ resolve ();
234+ }
235+ });
236+ });
237+ },
138238 },
139239 created () {
140240 // 获取风格主题
@@ -195,6 +295,16 @@ export default {
195295 } else {
196296 this .getNewsPosts (); // 获取最新列表
197297 }
298+
299+ // 同步一次 storage.local -> localStorage,并初始化读取书签数据
300+ this .syncFromStorageLocal ().then (() => {
301+ this .bookmarkDataList = this .getBookmarkDataFromLocalStorage ();
302+ });
303+
304+ // 监听 localStorage 与 chrome.storage 的变更
305+ window .addEventListener (" storage" , this .handleLocalStorageChange );
306+ const browserAPI = typeof browser !== " undefined" ? browser : chrome;
307+ browserAPI .storage ? .onChanged ? .addListener (this .handleChromeStorageChange );
198308 },
199309 // 绑定滚动事件,自动记录滚动位置
200310 mounted () {
@@ -209,6 +319,9 @@ export default {
209319 if (container) {
210320 container .removeEventListener (" scroll" , this .recordScroll );
211321 }
322+ window .removeEventListener (" storage" , this .handleLocalStorageChange );
323+ const browserAPI = typeof browser !== " undefined" ? browser : chrome;
324+ browserAPI .storage ? .onChanged ? .removeListener ? .(this .handleChromeStorageChange );
212325 },
213326};
214327< / script>
0 commit comments