- 博客(150)
- 资源 (20)
- 问答 (1)
- 收藏
- 关注
原创 图片标签用 img 还是 picture?它们的真正区别是什么?
在网页制作中,图片处理是每个前端开发者都会遇到的基本任务。面对 img 和 picture 这两个标签,不少人都有误解。有人认为它们可以互相替代,有人在不该用复杂方法的地方用了复杂方案。今天,我们来彻底弄清楚这两个标签的真正用途。img标签 是 html 中最基本也最常用的图片标签。picture标签 不是用来替代 img标签 的,而是为了解决 img标签 处理不了的特殊情况。很多人以为 img标签 不能做响应式图片,这是不对的。错误三:响应式图片用 picture。img 标签的响应式能力。
2025-12-09 15:10:25
373
原创 TypeScript 核心特性详解:枚举、泛型、命名空间和模块
TypeScript 为 JavaScript 带来了强大的类型系统,让大型项目开发更加稳健。在实际开发中,建议优先使用模块来组织代码,配合枚举和泛型来增强类型安全。只有在需要与旧代码兼容或开发特定类型的库时,才考虑使用命名空间。枚举是 TypeScript 中的特殊数据类型,让我们可以为数值设置有意义的名字。这种混合使用会增加代码的复杂性,建议保持枚举成员类型一致。模块是当前推荐的代码组织方式,每个文件都是一个模块。泛型让我们可以创建可重用的组件,同时保持类型安全。模块:现代代码组织方式。
2025-12-09 14:54:38
440
原创 前端怎么防止用户复制?这10种方法让你的内容更安全
用户还是可以按下F12禁用 JavaScript 或绕过事件监听。不利于 SEO、无障碍访问(屏幕阅读器无法读取),且加载慢。后端配合:服务器动态生成字体文件,定期更换映射关系。"这是一段需要保护的机密内容,不能被轻易复制""这段文字通过CSS生成,无法直接选中和复制"用户仍可查看源代码或使用其他手段复制。4.用户按F12就触发debug功能。// 将每个字符用span包裹。• 字符a在字体中实际显示为b。• 字符b显示为c,以此类推。
2025-12-03 15:26:06
402
原创 Vue3 和 Vue2 的核心区别
通过代码对比,可以更清楚地看到 Vue3 在开发体验、性能、灵活性和工程化方面有明细的提升。Vue 2 虽可通过 vue-class-component 或 vue-property-decorator 支持 TS,但配置复杂且类型推导弱。它解决了Vue2中一些让人头疼的问题,比如动态添加属性不响应、组件必须包在一个根元素里等等。Vue 2 需手动操作 DOM 或使用第三方库(如 portal-vue)。下面通过10个常见的对比例子,让你快速看懂Vue3到底新在哪儿、好在哪儿。
2025-12-03 15:17:49
370
原创 Vue3快速查阅宝典
在 Vue 3 中,setup 是一个新的组件选项,用于定义组件的逻辑和状态。在模板中的元素或组件上使用 ref 属性来定义一个引用名称,然后在组件的 JavaScript 代码中通过 $refs 访问到这个元素或组件。作用域插槽,它允许你在一个组件中定义具有局部作用域的插槽。与传统的 watch 不同,watchEffect 会在属性变化时自动执行副作用函数,并且可以返回一个清理函数,用于在组件卸载时清理副作用。$attrs 可以用于获取父组件传递的属性值,或者在组件内部未在 props 中声明的属性。
2025-11-05 11:29:26
638
原创 Vue3教程简介
这个API用来加载异步组件,异步组件的好处我想大家也知道,就是用不到他就不加载,用到了才会加载,这大大降低了首屏加载时间,是优化的重要手段。Vue3出了很久了,我之前也体验过,但是没有很好地出过一篇讲解他的用法的文章,昨天我又好好体验了一把,并总结了一些用法,分享给大家。Teleport是传送门组件,他可以将你的组件,挂载到任意一个节点之下,只要你指定一个选择器,可以是id、class。还记得之前vue2的父传子,子改父,的做法吗?这个API主要主要作用是:将子组件的东西暴露给父组件,好让父组件可以使用。
2025-10-31 16:15:58
686
原创 Vue3这两个方法,将掀起组件创建新狂潮!
✅ 动态生成组件类型(如:根据配置渲染不同组件)一、为什么需要它们?从模板到虚拟DOM的进化史。二、h函数与createVNode的关系解密。4.1 与Vue2的render函数对比。1.1 模板的局限(Vue2时代)三、核心用法详解(带场景化示例)✅ 需要精细控制渲染逻辑的场景。1.2 虚拟DOM的革命性。✅ 高阶组件(HOC)开发。❌ 已有现成模板组件的场景。四、Vue3的颠覆性变化。4.2 性能优化新特性。5.3 与JSX的配合。3.1 基础元素创建。3.2 组件创建模式。5.2 性能陷阱规避。
2025-10-31 15:51:00
253
原创 Vue3这些实用技巧,提升前端开发效率必备
在上面例子中,使用了 useIntersectionObserver 函数来监听元素的可见性,当元素进入可视区域时,就可以执行一些操作,比如加载数据。在一些重效果的项目中,首页会有很多的图片需要加载,如果一进入就开始加载,可能会导致页面展示的滞后。有时候,我们会遇到这样的需求:一个组件的逻辑在某个地方,但它的渲染位置却要在其他地方,比如模态框、下拉菜单等。在标签页切换的时候,一个页面需要导入多个组件,这个时候,如果不希望切换的时候,将组件初始化,可以利用 KeepAlive组件来实现想要的效果。
2025-10-31 15:41:08
434
原创 Vue3组件通信难题?用这个API轻松搞定父调子
在 Vue 3 的组合式 API(Composition API)中,defineExpose是一个关键的函数,只用于在 script setup语法中显式暴露组件内部的属性和方法供父组件访问。这函数解决了组合式 API 默认封闭太强的问题,使父组件能够通过 ref引用访问子组件的暴露出来的特定内容。总的来说,defineExpose 是 Vue 3 中一个强大的辅助函数,用于在封闭的。它增强了组件间的交互能力,同时保持了组件的封装性。未暴露的属性/方法父组件无法访问,避免意外依赖。
2025-10-31 15:29:34
211
原创 Vue3的异步DOM更新:nextTick的正确使用方法
Vue的DOM更新不是同步的,而是异步的。当我们修改数据时,Vue不会立即更新DOM,而是将这些更新操作放入一个队列中,在下一个事件循环中统一执行。数据变化后不能立即获取更新后的DOM,需要使用nextTick来确保在DOM更新后再执行操作。掌握nextTick的使用方法,能够帮助开发者避免很多常见的坑,写出更稳定可靠的Vue应用。如果不使用nextTick,直接操作DOM,很可能操作的是更新前的状态。点击按钮后,控制台输出的是"初始消息",而不是"更新后的消息"。Vue3中nextTick的变化。
2025-10-31 15:14:16
406
原创 六个高级Vue3知识技巧
虽然我们已经熟悉了一些常见的 Vue 3 知识,但还有一些不太常见但实用性很强的点可以帮助我们进一步优化和提升 Vue 3 应用的性能和开发效率。在上面的例子中,我们使用了teleport标签,并通过to属性指定了渲染的目标位置,本例中就是body标签。例如,假设我们有一个模态组件,并且希望将其内容渲染到 body 标签下的元素而不是当前组件的父元素。通常,Vue 组件需要包装在一个根元素中,但有时我们想要返回多个根元素,这就是 Fragments 可以帮助我们解决问题的地方。
2025-10-31 14:55:57
522
原创 Vue3的写法简介
Vue3 里,除了将两个 destroy 相关的钩子,改成了 unmount,剩下的需要注意的,就是在。正如你看到的那样,无论是代码行数,还是代码的精简度,script setup 的方式是最简单的形式。学习 Vue3 并不代表你需要新学习一个技术,Vue3 的底层开发思想,跟 Vue2 是没有差别的。如果你熟悉相关的生命周期,只需要记得在 setup 里,用 on 开头,加上大写首字母就行。所以我们需要关心的,就是 Vue2 里的内容,怎么用 Vue3 的方式写出来。但是我的建议是,你不需要关心它。
2025-10-31 14:39:17
579
原创 50个常用的JavaScript技巧汇总
49.判断为空值(null, undefined, “”)代替||处理 null/undefined。4.数字转字符串 / 字符串转数字。21.函数节流(throttle)22.函数防抖(debounce)5.使用typeof检查变量类型。16.删除对象中 falsy 值。19.立即执行函数(IIFE)45.设置 innerHTML。14.从对象中提取部分属性。31.检查字符串开头/结尾。20.函数缓存(记忆化)23.获取当前时间戳。39.判断是否为数组。九、DOM 操作技巧。50.判断是否为数字。
2025-10-31 11:20:48
186
原创 前端面试过程中常被问到的几个问题,必掌握
在深入探讨具体问题之前,重要的是要了解为什么 JavaScript 是现代开发的基石。事件循环是 JavaScript 中的一个基本概念,它处理异步代码的执行方式。JavaScript 是单线程的,这意味着它一次只能执行一个操作。这就是闭包的实际应用!在 JavaScript 中,函数可以“记住”其周围环境中的变量。当您想创建私有变量或在函数调用之间维护状态时,例如,在事件处理程序或基于计时器的函数中,可以使用闭包。let:ES6 中引入的 let 具有块级作用域,这意味着它的值只能在定义的块内访问。
2025-10-31 11:00:31
595
原创 后端一次返回十万条数据?Vue3 可以这样优雅处理
十万条数据,就算每条数据只有几个字段,内存占用至少20-50MB。最近有个朋友问我:“后端一次性返回十万条数据,页面直接卡死了,怎么办?如果对用户体验要求很高,再考虑虚拟滚动等更复杂的方案。如果需要显示大量数据但又要求流畅滚动,虚拟滚动是最佳选择。它的原理是只渲染用户能看到的部分,看不见的数据先不渲染。优先和后端沟通:最好让后端支持分页,这是最根本的解决方案。做好加载状态:大数据加载需要时间,要显示加载提示。把繁重的数据处理放到后台线程,不影响主线程渲染。如果确实需要显示大量数据,可以分批次渲染。
2025-10-31 10:33:01
539
原创 Vue3 的 ref 和 reactive 到底用哪个?
ref和reactive是Vue3的Composition API里最常用的两个核心成员,专门用来创建响应式数据的。ref:可以包装任何类型的值,包括基本类型(数字、字符串等)和对象类型。但它们用起来不一样,适合的场景也不一样。reactive:只能包装对象类型(包括数组)。就是数据一变,页面自动跟着更新,不用你手动刷新。其实它们干的是一件事就是:让Vue能监听到你的数据变化。• reactive的旧值和新值相同(Proxy特性)案例1:表单处理 - 推荐 reactive。
2025-10-30 16:27:06
787
原创 Vite 大型项目优化方案
Vite 作为现代前端构建工具,在大型项目中需要进行针对性优化以确保开发体验和构建性能。集成 vite-plugin-bundle-analyzer进行可视化分析。使用 vite-plugin-cdn-import插件实现 CDN 替换。使用 unplugin-auto-import自动按需导入 API。使用 vite-plugin-pwa添加渐进式 Web 应用支持。使用 vite-plugin-parallel开启多线程构建加速。使用 vite-plugin-inspect检查插件中间状态。
2025-10-30 15:18:05
629
原创 别再用 PX做单位了!CSS 新特性,轻松实现响应式布局
更重要的是,这种“阶梯式”的调整是不连贯的,在断点之间,布局仍然是僵硬的。是时候从 px 的思维定势中解放出来了,clamp() 这个现代 CSS 特性,并不是什么遥不可及的黑科技,它们的浏览器兼容性已经非常好(主流浏览器早已支持)。分享一个强大的 CSS 新特性,它将改变我们编写响应式样式的方式,让我们告别繁琐的媒体查询,轻松实现流畅的“流体式”布局。最终,字体大小会在 24px 到 48px 之间根据屏幕宽度平滑地过渡,不再有断点之间的跳变,这是真正的“流体式”设计!clamp() 在布局中的应用。
2025-10-30 11:24:10
319
原创 Vue 3.0 源码导读
这个模块是基于上面模块而写的浏览器上的 runtime,主要功能是适配了浏览器环境下节点和节点属性的增删改查。很明显,这个模块就是 Composition API 的核心了,其中的 ref 和 reactive 应该重点掌握。这个模块则基于上个模块,针对浏览器做了适配,如对 textarea 和 style 标签做了特殊处理。大部分 Vue 开发者应该不会用到这个模块,因为它是专门用于自定义 renderer 的。代码仓库中有个 packages 目录,里面是 Vue 3 的主要功能的实现,包括。
2025-10-29 11:34:18
394
原创 Vue3之Composition API讲解
要知道, Composition API 之所以被提出和使用,就是为了让我们更加方便地进行组件复用,将状态经过函数式地传递过程中,由于JavaScript函数传参是值传递的,而基本类型不具备引用,为了保证属性的响应式,将使用ref来创建包装对象进行传递。toRefs将reactive对象转换为普通对象,其中结果对象上的每个属性都是指向原始对象中相应属性的ref引用对象,这在组合函数返回响应式状态时非常有用,这样保证了开发者使用对象解构或拓展运算符不会丢失原有响应式对象的响应。watch可作用于单一函数。
2025-10-29 11:18:44
926
原创 Vue3的数据响应式原理
秘诀就在之前看到过的activeEffect,它是一个来存储当前执行函数的全局变量,当get时,把这个函数设置为activeEffect,当set时,再触发这个activeEffect,就可以了。这是因为,需要考虑到函数的执行是会出现嵌套的,如果仅仅是赋值,activeEffect可能出现错误,使用栈结构之后,每次执行函数入栈,执行完出栈,就不会出现这种错误。需要说明的一点是,在Vue2.x中,响应式数据如果仍是对象,会递归执行,但Vue3.x中会在访问数据时才决定要不要执行,这会带来一定性能的提升。
2025-10-29 11:01:56
871
原创 基于 Vue3 及TypeScript 项目后的总结
在使用的层面,我们从options Api,变成了composition Api,慢慢的在实际的业务中,我们抛弃了原本的data、methods、computed那种隔离式的写法。在语法层面,两个有差异。关注点分离,应该分两层意思:第一层意思就是,Vue3的setup,本身就把相关的数据,处理逻辑放到一起,这就是一种关注点的聚合,更方便我们看业务代码。这里我需要明确的是,Vue3是完全兼容Vue2的这种options Api的写法,但是从理念上来说,更加推荐setup的方式,来写我们的组件。
2025-10-28 15:34:04
1048
原创 Vue3 王炸!一行代码终结双向绑定的所有烦恼
它提供了强大的双向绑定能力,是构建可复用表单组件的基石。但同时,在 script setup 风格的组件中实现一个自定义的 v-model,总免不了那几行“祖传”的样板代码。使用 Vue 3.4 的 defineModel,上面的 CustomInput.vue 可以被简化成什么样?从三件套的繁琐样板代码,到一行直观的声明,defineModel 带来了极致的简洁和优雅。假设我们要创建一个自定义的输入框组件 CustomInput.vue,并希望父组件能通过 v-model 绑定它的值。
2025-10-28 15:02:10
134
原创 不必争论 v-if 和 v-show,Vue3 新指令来了
v-memo 不是用来替代 v-if 或 v-show 的,它是专门解决那些令人棘手的渲染性能问题。面对这个问题,v-if 和 v-show 显得有些无力,而 Vue3 有一个专为解决此问题的指令——v-memo。v-once 本质上就是 v-memo 的一个特例,v-once 等同于 v-memo=“[]”。v-if 和 v-show 的争论,解决的是“有或无”的渲染问题,但现代前端应用中,更大的性能挑战来自于“多与少”的更新问题。需要注意的是 v-memo=“[user.status]”。
2025-10-28 14:52:14
165
原创 如何在关闭浏览器标签前,可靠地发送 HTTP 请求?
而如果我们需要更大的灵活性,比如使用 PUT 方法更新资源或需要设置特定的请求头,fetch({ keepalive: true }) 是更好的选择。通过在 fetch 的 init 对象中设置 keepalive: true,我们可以告诉浏览器:“这个请求很重要,请在页面卸载后继续完成它。在这个过程中,任何在 unload 事件处理器中发起的标准异步 fetch 或 XMLHttpRequest 请求都会面临一个问题:请求刚刚发出,页面就已经被销毁了。然而,这看似简单的需求,在实践中却充满了挑战。
2025-10-28 14:38:12
725
原创 不用 if else,如何优雅处理 JavaScript 条件判断?
如果使用传统的 if-else 语句,对复杂的条件进行逻辑判断,代码很容易变得冗长难维护,分享几种替代的写法。
2025-10-28 11:56:52
209
原创 抛弃 localStorage,这个存储方案更安全更高效
在前端开发的世界里,浏览器存储一直是我们处理客户端数据持久化的重要工具。多年来,localStorage 凭借其简单易用的 API 和跨会话持久化能力,成为了许多开发者的默认选择。然而,随着 Web 应用复杂度的提升、安全要求的加强,以及性能优化的迫切需求,localStorage 的局限性也逐渐显露。IndexedDB 是一个面向对象的数据库系统,专为大量结构化数据的客户端存储而设计。测试表明,在处理超过 500KB 数据时,IndexedDB 的性能优势尤为明显,页面响应性能可提升 40% 以上。
2025-10-28 11:32:02
444
原创 当用户同时打开多个标签页时,如何同步它们之间的状态和数据?
如果这些标签页之间的数据和状态无法同步,就会导致用户体验的割裂和数据的不一致,给用户带来困惑。因此,核心挑战在于:如何在一个标签页中触发一个动作,并通知其他所有同源标签页进行响应?它创建了一个命名的“频道”,所有连接到该频道的上下文都可以自由地发送和接收消息。当客户端状态逻辑变得异常复杂,多个标签页可能同时修改数据导致冲突时,SharedWorker 能够提供一个清晰、健壮的架构。通过合理选择并应用这些技术,我们可以打造出无缝、一致的多标签页用户体验,让 Web 应用更加专业和贴心。
2025-10-27 15:25:48
695
原创 前端文件下载的多种方式:从简单到高级
用户体验: window.location.href会导致当前页面跳转,如果下载失败或响应不是文件流,用户体验可能不好。文件名控制在后端: 文件名由服务器的 Content-Disposition头部决定,前端无法直接控制(除非文件名在URL参数中)。这是目前最灵活和强大的前端下载方式,尤其适用于需要认证、动态生成内容或处理从API获取的二进制数据。理解这些方法的原理和适用性,可以帮助你为不同的下载需求选择最合适的解决方案。不适用于Blob数据: 不适用于前端生成的Blob数据下载。
2025-10-27 14:58:52
1140
原创 Vite+Vue3 微前端该用啥方案?五大主流方案实战对比
Vite+Vue3「Vite 的 ES 模块天然优势」:微前端最头疼的 “模块隔离” 和 “资源加载”,在 Vite 的原生 ES 模块支持下直接降维打击 —— 开发环境不用打包,子应用随用随加载,热更新速度比 webpack 快 10 倍不止。「Vue3 的 Composition API」:子应用和主应用的状态通信、逻辑复用更灵活,配合 TypeScript 的类型提示,多人协作不容易出乱子。「生态成熟度」:2025 年的 Vite 插件生态已经能轻松搞定微前端的样式隔离、路由劫持、依赖共享,比两
2025-10-27 14:30:20
1127
原创 前端实现大文件上传全流程详解
在日常开发中,大文件上传是个绕不开的坎——动辄几百 MB 甚至 GB 级的文件,直接上传不仅容易超时,还会让用户体验大打折扣。用 spark-md5 库计算文件哈希,但有个关键优化:「不读取整个文件」,而是抽样读取部分片段(首尾分片全量 + 中间分片抽样),既能保证哈希唯一性,又能大幅提升大文件的计算速度。后端需要检查「完整文件」和「已上传分片」的存在性,返回给前端决策依据。所有分片上传完成后,前端需要通知后端「合并分片」,后端按分片序号排序,用「流(Stream)」拼接成完整文件(避免内存溢出)。
2025-10-24 16:54:34
785
原创 Vite 工作原理
这段简易手写代码虽然没有实现 Vite 的热更新、依赖预构建缓存等高级特性,但已经完整展现了其核心原理:利用浏览器原生 ESM,通过开发服务器动态处理模块引用和文件解析,跳过打包步骤,实现极速开发体验。重写后的路径/@modules/vue会被服务器拦截处理,这一步的核心是「找到」「node_modules」「中对应的依赖文件」,并以浏览器可识别的 ESM 格式返回。这样一来,浏览器会向服务器发起/@modules/vue的请求,而不是直接报错,为后续的裸模块加载铺路。
2025-10-24 16:02:42
554
原创 前端如何判断用户是否离开了当前页面?
浏览器在处理页面卸载时,并不会等待 unload 事件处理器中的异步操作(如 fetch 或 XMLHttpRequest)完成。当用户导航到其他页面后,如果点击“后退”按钮,浏览器可能会直接从缓存中恢复上一个页面,而不是重新加载它。sendBeacon() 方法可以异步地向服务器发送少量数据,并且浏览器保证会将其启动并排队发送,而不会阻塞或延迟页面的卸载过程。通过组合运用这些现代 API,我们不仅能准确地判断用户的行为,还能在不牺牲性能和可靠性的前提下,打造出更智能、更友好的用户体验。
2025-10-24 11:29:52
778
原创 无感刷新Token:如何做到让用户“永不掉线”
摘要:本文探讨了如何实现无感刷新Token机制,解决Access Token有效期短与用户体验之间的矛盾。通过双Token(Access Token和Refresh Token)认证系统,当Access Token过期时,利用Refresh Token自动获取新Token,避免用户频繁登录。文章详细介绍了工作流程,并提供了基于Axios拦截器的实现方案,包括并发请求处理和错误降级机制,在保障安全性的同时提升用户体验。
2025-10-24 11:03:12
706
原创 前端性能优化提升方案总结
项目中,可以将静态资源(JS、CSS、图片、字体)部署到 阿里云或腾讯云等 CDN,让用户从最近的节点获取资源。在多页面应用(MPA)或微前端场景中,把公共依赖(如 React、Vue、Lodash 等)提取出来,通过 浏览器缓存 或 CDN 共享加载,可以避免重复下载同一依赖,减少首屏加载体积。在多页面应用(MPA)或微前端场景中,把公共依赖(如 React、Vue、Lodash 等)提取出来,通过 浏览器缓存 或 CDN 共享加载,可以避免重复下载同一依赖,减少首屏加载体积。
2025-10-24 10:26:25
1017
原创 对Webpack的深度解析
在开发阶段,webpack-dev-server会启动一个本地开发服务器,所以我们的应用在开发阶段是独立运行在localhost的一个端口上,而后端服务又是运行在另外一个地址上,所以在开发阶段中,由于浏览器同源策略的原因,当本地访问后端就会出现跨域请求的问题,通过设置webpack proxy实现代理请求后,相当于浏览器与服务端中添加一个代理者,当本地发送请求的时候,代理服务器响应请求,并将请求转发到目标服务器,目标服务器响应数据后再将数据返回给代理服务器,最终再由代理服务器将数据响应给本地。
2025-10-09 14:56:21
905
原创 浅谈Node.js以及对fs模块的理解及常用方法
第三个参数为options,默认值为null,其中有encoding(编码,默认为utf8)、flag(标识位,默认为w)和mode(权限位、默认为0o666),也可直接传入encoding。第三个参数为options,默认值为null,其中有encoding(编码,默认为utf8)、flag(标识位,默认为w)和mode(权限位、默认为0o666),也可直接传入encoding。同步创建,参数为一个目录的路径,没有返回值,在创建目录的过程中,必须保证传入的路径前面的文件目录都存在,否则会抛出异常。
2025-09-23 17:08:19
496
原创 VS Code中安装统计代码行数插件统计代码行数
本文介绍了在VSCode中使用VS Code Counter插件统计代码行数的方法:首先在扩展商店安装插件,然后通过"查看>命令面板"菜单启动统计功能,按Enter键开始统计,最后可查看总体和单个文件的代码行数统计结果。该插件能快速统计项目代码量,方便开发者掌握代码规模。
2025-08-15 14:28:55
445
原创 Vue3中自定义路由页面重定向
首先思路是获取到新页面的路由地址路径,然后根据路由地址路径进行判断处理,如果浏览器中输入了新页面路由路径地址,进行路由判断(获取路由路径地址有2种方式,一种是通过vue3里面自带的属性currentRoute.value.query.redirect来获取;另一种是通过js方式window.location.href获取浏览器地址栏中的地址,然后进行截取路径)如果输入的路径是新页面路径则跳转到新页面,否则就走之前的首页,这样就可以对新页面的路由进行重定向修改,从而解决此问题。
2025-05-08 10:25:49
353
ecshop二次开发中关于discuz和Ucenter的问题?、、
2016-04-25
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅