给大家分享一个做前端开发必须要装的没有一插件,就是这个插件,在这里面搜索就可以安装,安装完了之后呢,里面有好多这种强大的功能,能提高我们的研发效率。比如说这个是我创建的一个没有一文件,对吧?他现在合适其实是乱的,我们可以右键这里面有一个合适化这个文档 呀,他能瞬间给你把代码搁的话,好,还有一些其他的功能,比如说我,那么我点空格,他其实能出来好多种提示,也就说我这个八点上这些属性我其实是都可以用的。还有一个插件也必须要安装的,就是这个 eas, 另一层 就这个插件检测我们的代码的规范。还有一个必须安装的就是美化的没代码格式化的工具,就是这个这个插件,这样的话比如说我在这里面写代码,是吧?我可以我可以把它的格式 调的乱一些,对吧?调乱了之后,那我点保存的时候,他会自动的帮我们更换代码,这样的话能提高咱们的研发的效率。大家还有没有什么好用的插件,欢迎评论区留言。
粉丝4.8万获赞44.1万

fool 核心团队成员 and fool 开源了他的技能数, fool use 运动 c s s slide f 这些明星项目背后的技术战,现在你的 ai agent 也能学会 agent skills 是 让 ai 获取专业知识的标准格式。 and fool 作为 v 生态核心贡献者,把他十年积累的最佳实践全部做成了 skills 集合。 这个集合包含三类技能,第一, and for 本人的偏好设置 es linked p n p m v test, 配置一键同步。第二, v o nxt v t 官方文档生成的技能。第三,社区精选的最佳实践, 安装超简单,一行命令, andfull 的 全部技能就装进了你的 a a i full 组件怎么写? fit 插件怎么配? uno c s s 原子化怎么用? a i 直接调用对应技能,给你最正确的答案。 最厉害的是,这些技能通过 github 直接引用官方文档保持实时同步 full 更新了新特性,技能库自动跟进,永远是最新最准确的知识。 想让你的 ai 拥有大佬同款技能术,点赞收藏评论区见追星,不盲从,实测出真知,我是锋芒 ai!

real 团队成员 and 酷又一神作,它就是 real skills 集合,它可以让 ai 输出的代码更贴近 real 社区的习惯,让 ai 按正确方式写 real 代码使用也特别简单,直接在项目里面安装 and few skills, 然后选择你使用到的寄宿站, 再选择你的 ai 编辑器就可以了。我本地测试了下,安装 enterprise skills 生成的微代码,质量和完成度确实变高了,可以让我们在 web coding 时更加得心应手,感兴趣的可以试试关注我,了解更多最新资讯和实用技术。

大家好啊,今天给大家分享一下在 v 项目当中让你效率翻倍的几款软件,非常好用。那刚好前几天清华大学出版社给我寄来了一本循序渐进 v g s 三前端开放实战。 这本书我看了一下,比较适合 bu 技术站的初级开发者,里面包含了 bu 二和 bu 三的内容,有常见组间库和插件的使用,还有电商后台管理系统的实战。并且这本书呢,也有对应的视频代码、 ppt 资料,在每个章节的开头都有对应的二维码, 可以直接扫码看对应章节的视频,还挺方便的。推荐 view 的初学者买一本来看看,非常适合入门。那我们今天要推荐的第一款插件呢,就是这个别名路径跳转,你没看错,别的 usco 的插件都是一 英文命名的,他这个就是中文,你直接在 visco 的插件里面搜这个就可以了。那这个有什么作用呢?因为我们在项目当中有时候会有 and 这种别名对不对?但是有的这种别名之后,你跳转的时候会比较麻烦,有时候会跳不过去,那安装这个插件之后呢,你就可以直接选中, 哎,就直接可以跳过去了,非常方便。第二款插件呢,是我们之前推荐过一次的,叫 autotrac strict for view, 这个是在你写 view 结构的时候, 直接生成你对应结构的 class 名称,给你举个例子啊,这里现在我们把刚才那个 class 名给删了对不对?现在我们右键,然后点击一下,哎,我们会发现他一一对应这个 content, button, 他都会一一对应的,在这下面 帮你确认好,你直接在最下面直接编写你的样式就可以了。那第三个插件呢,是我们推荐的 css navigation, 这个插件呢,主要的作用是 当你写好这个克拉斯的时候,在这个文件里面,你比如说你想跳转过去是比较麻烦的,但是有了这个插件之后呢,你可以选中然直接跳转到下面去, 看到没有,可以直接跳转到下面去编写你的 style 样式,非常方便。下面一款呢是 pass intensions, 当你引入一些新的文件的时候,他会给你自动提醒,比如说 important, 对吧?然后这个时候呢,你点点,这个时候他会给你自动提示,你说我要引入一张图片,就会很方便的给你提醒。那再下面一个呢,这个插件是由官方 推荐安装的一个插件,以前有一也有一个 view 二版本的,现在升级了,升级成 view 三的插件版本了,这个也不用大家多说了,写 view b 装啊, 语法高量呀,然后语法提示,然后下面一个 will helper, 它呢跟这个 villa 这个插件呢,有点类似,只不过它会有更多的 语语语法的支持,写起来会更方便一些。那上面几款呢,就是我平时在项目当中用到的这些 view 插件,会非常好用,大家也可以尝试一下。

面试一个负责过高流量 v o e 三项目的终极前端,我问你们项目首屏加载需要五秒,你怎么系统性优化? 他回答,用路由览加载压缩图片,再用 c d n 加速。我追问,具体如何分析性能瓶颈?如何确定关键渲染路径?哪些资源需要预加载?如何利用 v o e 三的翻译特性? 监控指标怎么定?他开始猎取技术名词,但缺乏系统性,很多开发者只知道零散的优化技巧,却不懂如何打一场完整的性能攻坚战。 系统性的优化 v o e 三手屏性能需要打好六场战役。如果这道题目你也不会回答的话,我整理了让大厂 hr 沉默的必考题库,包含 v o 灵魂拷问、 react 高频陷阱、 js 十连问点个赞,评论区甩六六六,打包带走。 第一,战役性能分析与度量标准工具矩阵 lighthouse 加 web page test 加 chrome devtools performance 面板 关键性能指标 fcp, 用户看到内容的时间 lcp 主要内容加载完成时间 tti 页面完全可交互的时间 c l s 视觉稳定性指标, 建立性能基线,记录优化前的各项数据,设定可量化的目标。第二,战役代码分割与懒加载策略,路由级分割 v o u router 的 动态 encrypt, 实现按需加载组建级分割 define s x component 延迟加载,非关键组建 第三方库分割 icards, 按需引入,避免全量引入。使用 v o 三的 tree shaking 特性,消除死代码 编辑优化配置配置 white roll up 的 代码分割策略,合理设置 chint 大 小域值。第三,战役资源优化与加载策略图片资源四版斧格式选择 webp 加 jpe g p n g 兜底 尺寸适配 s r k, 根据屏幕大小加载合适尺寸。览,加载 interception observer api, 实现视口内加载。域加载关键图片添加 preload 字体优化字体子集化只包含实际使用的字体 font display swap 避免 f o i t。 本地字体优先避免从 google fonts 等外部加载 关键 css 提取,将首屏必须 css 内联,非关键 css 异步加载。第四,战役构建配置与交付优化构建工具选型 white 基于 esm 的 极速构建,开发体验优秀。 webpack 五,成熟稳定 module federation 支持微前端 构建配置优化。压缩策略 turbo 多进程压缩 css 压缩 h t m l 压缩缓存策略内容哈希实现长期缓存预构建,依赖 white 的 预构建加速二次启动 交付策略 c d n。 部署静态资源全球加速 http 斜杠二或 http 三多路附用头部压缩 brought 来压缩比 gzip 更高的压缩率。第五,战役运行时优化与高级技巧 vivo 三,编辑时优化 patch flag 精准更新,减少虚拟 d o m 对 比静态提升,将静态节点提升到渲染函数。外部树结构打平,减少深层嵌套。对比组建优化技巧,使用 vmail 缓存虚拟 d o m 指数合理使用 shallow riff 和 shallow reactive, 避免不必要的响应式转换。域加载与域取,关键路由域加载用户可能访问的下一个页面,非关键路由域取, 空闲时加载其他资源。第六,战役监控体系与持续优化性能监控 r u m performance api 收集用户实际性能数据, 合成监控自动化脚本,定期测试关键路径,核心业务指标与业务转化率关联分析告警机制,设置性能域值 lcp 超过二点五秒触发告警错误追踪资源加载失败率监控用户体验评分,定期抽样调研, 持续优化文化性能预算,在 ci 除以 cd 流水线中集成性能检查性能回归测试,每次发布前运行性能测试团队培训,建立性能优化意识。这回厉害, 这道题考察的是从前端工程化到用户体验的全链路性能优化能力,这是高级 v o i 开发者必须掌握的核心技能。最后,你优化过的最有挑战性的性能问题是什么?最终提升了多少性能指标?

好,做了个开源项目啊, will differ, 跟大家介绍一下它的功能组件的懒挂载和懒更新啊,什么意思呢?就跟图片的懒加载是一样的啊,当一个组件进入到仕图之后,它才开始挂载啊,或者说当一个组件进入到仕图之后,它才开始更新 啊,以这个案例为例啊,你看这边,我有个卡片,里面是 a 组件,这个 a 组件呢,它比较大啊,它就把这个 hello world 啊,这边有 hello world, 它把这个 hello world 呢给挤到下面去了啊,如果用户不滚动的话,它就看不到 hello world, 看不到就不挂载,我们来看一下啊, lightyear runner 啊,从这个 will differ 里面导出了一个 lightyear runner 这个组件儿啊,它有个默认插槽,默认插槽就是船我们用来揽挂载的组件啊,还有个 forback 插槽,这个呢,就是我们的一个 loading 站位符啊,当我没有进入到仕途的时候,就展示这个 loading。 好,我们来看一下这个 hello world 的 组建啊,逻辑也不复杂,我里面就是一个计时器,一直在跑啊,如果这个逻辑比较复杂的话,他是比较占内存的,是吧,如果用户没看到的话,哎,我不挂载,他是不是就节约一点内存呢啊,我们来看一下实际的使用案例啊,我左下角有一个指示器啊,表示 hello world 是 否挂载了啊,你看现在是 a 组键,我可以往下滚动。现在 hello world 还没有展示出来啊,你看我往下滚动滚动, 哎,展示出来了,它就挂载了,那现在才开始计时对吧,那我们也可以来调试一下啊,大家如果感兴趣学习 vivo 原码的,也可以点击左下角的小黄车,跟着我们一起学习 vivo 的 原码,后面也会把这些组建的实现原理给大家做一个讲解,包括目前我们课程的福利内容也有很多,大家如果感兴趣的话,可以点击左下角查看详情。 好,看一下啊这边,嗯,这里应该是 load, 你 看,这里是 load, 现在并没有显示 helloward, helloward 还没出来,看,我往下走啊,走,走走走,挂载了。好,这个时候 helloward 出来了,你看这不, helloward, helloward 里面有个计时器一直在跑是吧?啊,七八九,你看啊,当它离开的时候,它就不更新了, 但是计时器还是一直在跑啊,那现在是十二,它不更新了,走,你看是吧,试图又开始更新了,你看我移出,哎,它又不更新了,它不闪了 啊,进来啊,他又开始更新了啊,就这么一个功能啊,如果你们遇到这种啊,逻辑比较复杂的组建啊,不希望用户没看到他的时候也挂在啊,就可以用这个 will differ 来试一下啊。这边有文档啊,这边有文档,大家可以感兴趣的话可以来看一下这个文档,然后这边也有实际的使用案例啊,这边有个演示啊, 下面这些 a p i 也都是有的啊,主要介绍一下这个组建的功能。那我们这节就讲到这里啊。

大家好,欢迎来到前端进阶课堂 real 三最佳实践。我是前端小组,今天我们来跟着 nt4 去学 real 的 最佳实践,我们去揭秘 real 核心团队成员的代码结闭和最佳实践。在 github 上, nt4 的 名字几乎代表了 real 生态的最前沿,而他最近开源 nt4 scales 的 仓库, 我们今天就来扒扒一下大佬的这个仓库,去梳理一套能让你的 vivo 项目脱胎换骨的规范。我们将从最基础的响应式变量开始,一步步深入到逻辑赋用于代码以组建架构,带你领略什么叫做优雅。而这一第一个章节就是心智模型的大一统。为什么我们只用 r e f? 当我们去开始写一个新组建的时候,第一件事情往往是定义数据,这时候经典的选择困难就出现了,用 i e f 还是 reactive? 在 nt for 的 代码事件里面,这个答案就只有一个,就是 i e f。 很多人为了写不写点 value 而使用 reactive, 但其实在解构 reactive 对 象的时候,响应式就会无声无息地丢失掉, 然后这很容易去出现一个 bug。 比如说我们在这个情况下,我们使用 reactive 去对一个 state state 来进行一个响应式,那我们进行解偶之后, 它这里通过 watch loading, 但其实它其实不会永远不会被触发这具体它的问题的出现,那其实可以翻看我过往的和前头小组一起学六三元码的一个课程视频。但如果我们使用 count 去进行 i e f 的 话,那其实无论是你解 o 之后,它其实都不会出现这个问题。 而 nt4 它的一个 ief first 的 一个策略是什么?就是统一使用 ief, 即使是对象,那这带来了一个巨大的认知常识,就是看到变量就知道它需要点 value, 只要结构就知道使去使用 to ief 的 一个 api, 就 即使我们重置的整个对象响应式其实依然是存在的。 我们来可以看一下。又回到那个例子啊,用 state, 用 ief 来进行处理,哪怕你用 reset 一 点 value 去重新设置,那其实它的响应式依然是存在的,而这个也就是复位,它没法去做到这一点。而第二点就是一个精准控制响应式, 就是将那些庞大的第三方实力不去做一个深度的响应式。 view 的 响应式系统非常强大,但如果不加节制的乱用,那它就会对我们的业务造成一些性能的滥用。那 n n t four 的 代码里面其实就是无时无刻就使用 share ief, 那比方说我们用使用 interest 实力 macbooks 对 象,地图对象,或者成千上万行的纯静态接收数据塞进到 i f 的 时候, vivo 它会去尝试地归地,将每一层属性都穿上 post 的 马甲,这就是完全的性能上的一些浪费啊。举一个例子, 我们去做一个 etht 的 一个啊, instance 的 一个实力的代理,或者说我们对一个 huge justin list 来进行一个代理,那其实它会每一行每一个数据都会被代理, 那这时候我们就去使用 share i f, 而 share i f 就 跟它 a p i 名字一样,就是 view 只监听点 value 的 变化,而忽略 对象内部的一个属性。它适用于什么呢?它适用图表,实体地图对象以及纯展示的大列表,我们可以看这样子,就直接使用 share i f, 然后修改数据,是直接替换引用,然后去发去触发追踪,搞定了内部 状态。接下来我们看组建之间如何优雅地传递数据,就是 purpose 和 model。 在 view 三点四之前,父子组建通信,往往伴随着繁琐的样板代码, nt4 极力推崇利用最新的红来简化这一过程。那我们来看一下这个响应式结构, 我们是通过 define purpose 来进行这个我们就在 watch effect 中直接去使用 message view, 它其实会编辑,会自动地去处理响应式追踪 define model, 它以前为了实现 we 干 model, 我 们需要定义 purpose 在 in map 事件就就是会做一些重复性的工作,那 n t four 就 在新项目中就已经完全全面转换转向了 define model, 我 们来看这个,它直接通过啊, constant model value 就 define model, 然后再修改 model value, 点 value 会自动通知副键,就像 ief 一 样,非常的简单。 那我们组建写好了,但是业务逻辑很复杂怎么办?这时候就需要去提出组建式函数,再去灵活地兼容 maybe ief anti four, 它是 real use 的 作者,它对封装 hulk 有 着近乎偏执的标准,它核心原则其实就只有一个,灵活的兼容。它认为就不优秀的封装就是强迫用户闯入 i e f, 但是优秀的封装应该是同时去啊, 支持普通值 i e f get 函数的时候,它应该是两者通吃。那它是怎么做的呢?它其实是使用 mu 三点三的 to 或者是 use 的 on i e f 去去将输入参数的一个规范化,大家可以看到在这里去接收普通值 i e f 或者 get 函数,然后 to 外头自动去进行一个解包, 然后再进行一个处理,那逻辑复用做好了,我们最后来看一下如何通过工具链和类型系统,就是简化我们的代码。在 nt4 scales 中, t s 不 仅是用来报错的,而是用来自动推导的。它首先第一点就是让组建支持发行,就是不要在组建中去写 any, 就 如果你的组建是一个列表渲染器,那他应该知道 列表像的具体的一个结构,然后同时自动导入,像 ief compute, 像矩阵变量一样使用,去保持代码的一个整整洁。 大家可以看到在这里这里的 item 就 会自动拥有 t 的 类型提示。那我们总结一下 nt4 的 一个风格的路由开发,核心 逻辑就是一致性优先就全员 i f 全员自动导入,然后性能其实无感化的,用 share i f 处理静态大数据,然后包括类型及文档,用范型组建和 t s 推导。好的,本期节目就到此结束了啊,欢迎大家订阅分享以及转发我的频道,我们下期节目再见。

大家好,今天呢给大家分享一个物流标准知识图谱项目,这个项目呢后端使用的是 java 呃,基于 spring boot 框架去开发,前端呢基于 vivo, vivo 框架去进行的一个开发。 那么我们首先呢看一下整个的这个业务系统,这个系统呢相对来说难度适中,功能丰富度呢也相对适中,主要呢是基于我们的业务知识,某一个行业的业务知识构建了整个的知识图谱, 那么我们看到的这个所有的节点呢,都是一个具体的核心的业务对象,那么点与点之间的关系就构成了我们的整个的知识图谱。 这个项目呢,对于节点管理和年限管理都有相应的这个功能操作,可以新增的一个知识点,也可以做一个修改的知识点, 同时可以做增身奶茶,都是可以做的,也可以进行这个多个的同时伸出 连线呢,同样的原理,我们每一条连线都有一个提示点和一个目标点,那么每一个点的名称可以在这里输入,那么所有的点的名称呢,都是前面设置的这个节点名称,这就是我们的知识图谱的一个管理的一个操作。 除了这个知识库的管理呢,同时该系统还有一些什么用户数据呀,角色呀,菜班管理,部门管理,岗位管理这些这些呢其实都是根据我们的这个业务系统可以划分相关的权限。 嗯,那么刚才呢粗略的介绍了一下整个的系统的功能,下面我们具体看一下代码, 首先我们看一下前端代码,前端呢我们整个的首页是我们的知识图谱部分,那我们首先看一下知识图谱的这个前端代码, 在我们的 index 这个文件夹下,这里面呢就是整个知识图谱的一个展示区。首先我们做一个 这个宽度为百分之百,高度为八十 vh 的 这个画布,在这个画布下自此了详细的这个功能实现,我们通过一叉四这个框架来实现整个这个,这是图谱的一个渲染, 下面呢是做一个我们数据的一个配置,我们的类型呢是一个图谱类型,那中间的数据呢?我们通过这个 h e b p 协议请求来实现我们与后端接口的调 u, 所有的接口呢我们可以看一下啊,我今天教大家一个怎么看前后端接口的方法,我们在这个页面里边按一下 f 十二, f 十二呢,我们打到 network 这个这里面,呃,现在我用的是谷歌浏览器,用很多的包括 ie 浏览器啊, i h 啊什么的都是有这个功能的,嗯, 这时候我们再刷新一下,我们就会看到前后端有一个数据的一个接口,我们打开这个 fetch, 这里面就是所有的这个接口的数据了。最后一个是 graph, 我 们看一下日期 post, 它的返回值就包括我们所有的点的信息,我们线的信息,这就是我们的实际的这个数据接口了, 那么我们看一下它的位置在哪,我们把这个 node graph 这个复制一下,这个呢就是我们前端的一个路增地址,我们可以做一个搜索, 我们可以查看这个搜索的这个知识图谱,这就是我们知识图谱的一个管理。那么这时候我们可以看一下我们的 id。 第二呢,同样我们刚才看到的是一个 node graph, 我们看到 nod 这个地址是 center, nod 是 这个路径,那么下一层的 graph 呢?其实是这个请求,我们是一个 get 请求, get 请求呢,我们会请求到所有的数据, 我们刚才一看呢,我们这个确实是一个 get 请求,它的这个请求的返回数据呢,我们有一个数据结构,首先呢是我们的这个 message 和 date, 这两个是我们操作是否成功的一个标志。核心的数据呢是在我们 date 里面。 date 呢,包括了 null 和我们的 nines。 null 呢,是我们的所有的节点数据,那所有的节点数据都在我们的 null 里面。 link 呢,是负责点与点之间的连接关系, 负责整个的这个业务逻辑的操作,在我们 nuke 里面。嗯, 下面呢,我们具体看一下我们的代码啊,我们 hold 代码首先是获取了我们的 node 节点数据,获取数据之后这是我通过我们数据库查询。 嗯,先来讲一下这个整体的逻辑啊,其实刚才一进来以后,我们发现这个是这个编辑。这里面我们其实啊在系统里面分成了这几类, ctrl 了、 service、 map、 统密四个核心的文件夹。那么 ctrl 了呢?是什么?是我们的控制层, 所有的前端与后端刚才说的是通过 http 协议来进行交互的,那么所有的 api 接口都是通过 control 这一层去写的,我们看到这个 get 就是 我们的一个 get 子球,那 control 呢?我们会 呃做一些操作,但是我们是做一些次量级的操作,主要呢是负责和前端接口做一个对应,不做具体的业务逻辑,业务逻辑呢,大多是在 service 里面去实现, 我们可以看一下,我刚才点一下 service, 那 service 呢,又分为我们的接口层和我们的实现内,那实现内呢,是写一些具体的实现的一个方法, 我们看到这里面大多数都会有一个 map, map 都会调一个 map, map 呢,其实是与 java 语言与我们的 m、 c、 h 与库之间的一个连接, 因为呢,我们的 java 语言怎么去连接数据库呢?就需要一个中间层去实现。我们 map 呢?点击之后会有一个具体的搜索语句,你看我们的这里面有一个 insert, insert into 什么的,也就是我们的搜那个,呃,搜搜索语句嘛, 然后这有我们的 select、 select 什么么, from 什么么,这其实都是我们的 c 和语句,那我们通过 java 的 这种方式来实现与 c 和语句的这个绑定,那么就可以实现我们去查询数据库。 那其实我们总结一下啊,其实主要是四层弹出了负责与前单代码去做交互。 ctrl 了呢,不做具体的业务逻辑啊,去掉 service, service 去来实现 service 呢?在实现 myson 后查询的时候,我们去掉 map, 那 map 呢?这里面看到的所有的 map 呢,都是一些这个还是一些 java? 它呢?会调我们具体的这个啊, 具体的这个 circle 语言,在我们的 member 这下面的这个叉 ml 文件里面去写我们的 circle, 去实现 circle 的 插曲,那这就是一二三四四层的一个加固。 那有的同学可能问了,东面是什么呀?东面其实就是我们一些业务对象,我们数据库里面会存一些对象,比如我们的节点会有一些节点的序号,节点的名称等等,同时我们读取到数据以后,怎么在扎拉里面去做存储,这里面就是通过我们这里的一个, 嗯,来实现,通过这个业务对象来实现,这个呢就是我们全部的这个后端扎拉元的一个代码。我们重新看一下这个这个 知识图谱啊,首先是获取我们 node 的 这个节点数据,获取 node 数据呢之后我们还要获取所有的连接数据, 那么下面呢就是针对我们所有的 node 作为一个复循环,为什么我们要获取它的名称, 它的这个呃大小,这个大小呢是指我们点上的大小,我们发现我们的页面上有的点大,有的点小,其实就是通过我们这个大小来控制的,我们可以通过这个参数来做一个控制, 之后呢我们还可以实现我们的这个线的连接,嗯,这呢是从开始垫底,我们的点呢放到一个我们的这个 map, map 的 这个列表里面,然后下面呢其实是我们的所有的连线,我们要便利我们所有的连线,我们确定它的起始点是哪儿,它的中指点是哪儿,从而来获取我们的这个这个连线的这个数据结构。 最后呢把我们点和线这个都按照这个规分的格式,就是我们刚才看到的这种格式来组装起来,算得到的它的序号是多少,昵称是多少,那它的免线呢?它的这个起始点和终止点的昵称分别是多少? 那么这就是我们的这个,哎,刚才说错了,这是我们的这个点的名称,它不是序号 啊,就可以实现我们的这个前端的渲染,前端渲染之后呢,就可以基于我们这个获取的数据来进行我们这个知识图谱的一个渲染,那这就是我们知识图谱的这个过程,那同样呢,对于其他的页面我们也可以打开看一下啊。 呃,包括知识图谱的监听管理、权限管理,这里面都是通过相关的功能来实现,这里面还有一些用户的个人中心。 嗯,登录注册这些还有一些其他的功能,我就不再过多的讲解了,感兴趣的同学呢,欢迎你的私信,我爱你哦。如果基于这个项目感觉还不错,其实我们可以再做一个深入的研究,如果基于这个知识图谱,我们可以加一些大模型,加一些 pdf, 或者千万的智能问答, 其实也是可以做的,那么如果有需要也可以欢迎私信。好了,今天先讲到这里,欢迎关注。

这节课呢,我们将会学习到一个极其重要的知识,就是路由,我们可以看到我们上节课呢,已经布局成了这个样子了,然后呢,我们现在要切换,切换到不同的页面,什么叫页面呢?我们从直观上来讲,我们在这个网站里边切换页面,实际上切换哪个区域啊?是不是就切换这个区域啊? 你看我们这边啊,左边是不动的,对吧?切换来切换去啊,都是切换那个这块区域啊,你看文章也是切换这块区域,只是这块区域变化。其实呢,你们以后呢,在别的项目里边也会发生类似的事情,比方顶部的导航栏不变,页角不变,就是中间这个区域变化, 或者是呢整个页面全部变完了,都有可能啊,无论是怎么变,总之呢,是有一块区域在变化,这个区域不同的东西呢,就是不同的页面。在我们过去啊,传统的工程里边,一个页面呢,其实就是一个 atm 文件,比方说我们首页可能就是这个页面啊, 然后呢,我们的文章页可能就是 blog atm, 呃,然后呢,我们的关于我们呢就是 aboves atm, 对吧?但是呢,现在我们用 view 做开发,我们要做的是什么呢?单页应用程序,什么叫单页呢?只有一个页面,从头到尾都只有这个页面啊?你看我们的网网页原代码啊, 一个 d i v 里边啥都没有,全靠 g s 在这个 d i v 里面构建。但是呢,抽象来讲啊,概念上呢,我们也把它叫做页面,只不过呢,这个页面呢,不再是我们传统的 atm 页面了。那这个区域到底是啥呢?其实 就是一个主见,我们在 view 里边切换页面,实际上是切换什么呢?切换的就是一个主见,就这么简单。那么也就是说我们这一块区域啊,中间这一块区域, 实际上它它代表着不同的页面,实际上呢,每个页面呢就是一个组件,因此呢,我们在我们的工程结构里边呢,可以在 s r c 里边新建一个文件夹,我们给它取个名字叫 view, 加个意思吧, views 表示的是啊,我这里呢 view 呢,以 view, 这就是一个试图啊,一个试图就是个页面,当然你也可以把它命名为配几式,也可以啊,无所谓的,看你们公司的约定吧,我们无忧里面通常的就是写的是无忧子好,然后呢,我们新建个文件啊,比方说我们首页的话,我们可以建一个 home 第二 view 文件,那么这就是一个首页的页面。当然呢,你也可以按照我们以刚之前的做法啊,新建个文件夹, home 表示首页,首页里面新建一个 index 点 view, 对吧?因为读这个文件夹的话,默认就读的是它。也可以啊,无所谓,看你们公司吧,因为这是我个人比较喜欢的一种做法啊,一个文件夹里边新建一个 index 点 view, 那表示的是我们首页啊,来写一个,随便写一个啊,就首页 好。然后呢,同样道理呢,我们可以建立一些其他的页面啊,比方说我们建立一个关于 about, 关于我好首页,关于还有什么呢?呃,还有文章,项目 效果和留言版,我们把这各种页面的组件都建起来了。那么现在问题来了,在我们的这个区域,这个区在哪里写的?是不是在 ap 里边写的呀?在这里边写的。那么这里涉及到一个问题,这里要渲染哪个组件呢?我到底是把 home 组件放这,还是把这个 blog 组件放这,还是把 mac 的组件放这?到底把哪个组件放这呢? 逻辑是什么呢?我们希望根据页面不同的地址,就你访问的是什么地址,你无论访问什么地址,我都是同一个页面,对吧?只有一个页面应这个是叫 at, 没有 我就用 t s 给你渲染出不同的主见放到这个区域,对不对?比方你访问这个地址,我就给你渲染博客主见,你访问一个斜杠,那我就反宣渲染首页啊,就这么个意思。因此呢,我们这里就会产生三个问题,一个来,第一个问题,如何来?根据地址,不同的地址地址不一样,我就渲染不同的主见,这个该怎么去做?第二个 问题,比方说根据这个地址找到这个主线了,那我把这个主线放到哪个区域?放到这呢?还是覆盖整个区域呢?目前看得清楚啊,应该放到这,那代码上怎么来表达呢?怎么让程序知道你要放到这个区域呢?对吧?这是第二个问题,你要告诉程序啊。第三个问题, 如何无刷新的切换主线?比方说我们点这个导航点了过后,哎,这个区就变了,并且呢,页面不要刷新,因为一刷新的话,没有必要你又全部去重新请求这个 atm, 又全部重新请求 gs, 然后呢?又重新全部运行,是 gs 啊,因为页面一刷新,全部要重来一次,从这里开始 全部要重新运行时,没有必要,我们只需要切换这个这个区就行了,能够更好的提高效率,这些都是我们这节课要解决的问题。有这节课呢,代码没几行,大道理一大堆,不然的话,我只只是把代码告诉你们,你们也不知道什么意思。而且将来呢,如果说稍微变一下,你不又不知道,怎么不知道怎么办呢?所以一定要把原理理解清楚。那么要解决这些问 问题呢,我们自己可不可以手写代码?可以啊,将来呢,我给大家讲一讲啊,我们自己手写应该怎么做来做。但是呢,我们更多的时候在工程里边往往是使用的是别人已经写好的一个无 u 插件。哎,无 u 是可以安装插件的啊,我们之前都没有用过插件,那么这以后我们会用到第一个无 u 插件就是路由插件。 路由的根本意思是什么意思呢?其实就是根据不同的地址,不同的路径,然后得到不同的东西,那么这里呢,就是得到不同的主见 啊,这就是路由的本质意识。关注都已剪辑号的同学打断一下啊,我是袁老师,总听我讲短视频,这回呢,来听听我讲的大课,我给大伙呢专门录制了一套大吃课,现在呢,免费送给你们, 不管你手上现在看的是什么样的资料,都应该先停下来,先来看一看我这套大师课。一方面呢,这套课程里边的内容都是前端最核心的知识,其他的知识都是在这个基础上生长出来的, 你先掌握好了这个,再学啥都事半功倍。而且呢,自此以后你对前端技术的理解不会存在任何的障碍, 另一方面呢,这套课还能够提升你的眼光,让你具备分辨好坏的能力。看过大师课之后啊,有一些不入流的资料,课程博客论坛你就看不上眼了,这种能分辨好坏的能力也能够为你将来的学习省下不少的时间。 所以呢,还没有领到课程的同学,赶快抓住免费领取的机会,进评论区第一条,加入粉丝群,然后根据提示领取就可以了。好,那么要使用这个插件呢,我们首先要安装它,呃,找到我们的工程啊,把它停止 好,首先呢我们安装一下路由,名字叫做 view rotor, 安装好了这个音耐过后呢,它有没有效果了?没有效果对吧?你并没有用它啊,所以说 啊,效果呢,还是没变,那么接下来我们一步步来啊,首先呢我们怎么来用这个路由呢?启动文件里边,我们在创建无忧实力之前,我们就首先要应用这个插件,怎么应用呢?就是使用这个无忧的构造函数里边提供那个静态方法 叫 use。 这 use 什么意思啊?就是使用插件啊,使用一个 view 插件,那么这个插件里边传的是一个插件对象,那插件对象是啥呢?其实就是那个 view rotor 啊,我们把 view rotor 导入进来。 view rotor, 五九 rotar 啊,导入进来就把这个东西传进去就 ok 了哈,这就是使用一个五九插件,这个东西呢实际上是一个构造函数,我们通过六来创建一个五九 rotor 的构造函数, 那么这里边要填一个,填一些配置啊,我们先暂时不不写配置,这里写的是配置,我们先暂时不写啊,那么会得到一个 rotor 的实力, 路由的实力,我们需要把这个路由的实力呢配置到无忧里边去。哎,现在是不是无忧里边多了一个配置啊,叫做 rotor 啊,使用了插件,然后呢把路由配置了进去啊,按照这个写就 ok。 无忧点意思啊无忧点意思啊,我说怎么回事啊?

那如果说我们要去定制,去拓展它的功能,我们需要用什么呢?也就是自己去定义一些新的插件啊,那这些插件在哪里?比如说我现在要去定义一个能够支持 view 的 这个插件,那其实你就直接安装一个插件名叫什么呢?叫比如说 vt 杠 plugin 杠 view, 这个时候呢,其实你就可以去使用了,当然现在它的名字改了啊,叫 vtgs plugin view, 这个只是换了一个组织名,然后放在一个不一样的地方。好,这样一换一来呢,你的项目等到把 vt 中间的这个配置给它改一下以后,就比如像这样来改啊,就能够支持 vivo 了,我们来试一试是不是可以啊?在这呢,我们直接偏偏卖 重新安装一下,安装完之后呢,在里面我们就把这个向上面呢改一个东西啊,就比如说叫做 app demo, 这个里面呢,我们把 script 直接用它啊, set up t s, 当然我们其实没有 script 都没关系啊,我们只要有一个模板就行了。 template 我 们就说 你好好保存一下,这样就可以了。那么接下来呢,它就能够去做这个翻译的处理。我们来看一下这边依赖安装好没有?依赖安装好了以后呢,它的导入应该也没有问题啊,在这里我们来指定一下它的 bundle, 把这个一定要指定成 bundle, 然后呢再把上面给它指定一下啊,把这个 node next 呢改成 yes next 好 就可以了啊,这这基本上是不管是 view 还是 react 它的通用应用的一个配置,就按照这样。然后呢我们再来到这边,把 view 插件指定进去,好保存一下,那你定义好了这个 view 的 文件以后,在这一块内容里面呢,就要改变了, 直接把它导进来。 app 导进来,然后呢创建这个 app 啊,比如说 console app 等于 create, 这时候呢需要把依赖导进来, 从 view 里面导进来啊。 view 好, 当然我们刚才 view 的 依赖是没有装吧,我们在 dependencies 里面把 view 也安装一下。 view 的 版本的话,那就直接用三点六点五吧,然后在这儿就可以导入 view 了。 pmmi 安装一下 view, 然后呢在这边来导入 view, pmmi 三点五点二十五,这个版本给错了。 好,再重新安装一下,然后呢再在这边来导入 view, 导入以后呢,把它的 create app 导进来, 然后再来抽象啊,抽象好之后一步一步。呃,这个呢报错,可能因为是这个编辑器的问题,因为我们没有没有按照根目录来打开它,这个我们可以先不管,再我们直接 app 点 mount 放下来啊。啊,这个内容呢,其实就是 document 点 query selector, 把它的选择器给它找到啊,在这边的话对应的是哪一个呢?因为我们这里现在没给给它传一个 div。 呃,就叫 app 吧, 然后呢再导进来,这个呢就直接 app 好 保存,我们再重新来启动一下。启动之后呢,端口号还是在八零八零啊,刷新一下,看一下里面的结果,现在目前没有任何东西说明我们这个呢没有出手化成功啊,但是也没有报错,我们看一下这边写错了,没有 template, json, view, action, 什么 restart server, 这个应该没问题啊,在这个里面写的有没有问题? app 点 mount, 这个也没有写错吧,在这个里面有没有导入 i id? app 下面导入的是它 s r c, 我 们重新再来启动一下, 把它的结果给到这边,我们可以还可以多写几个啊,就是像把 script 呢,也给它补充一些样式的话也是一样的,把样式也给它补充进去,好保存。这边呢导进来的,它这里还在报错啊, view 我们安装好了吗?三点五点二十五,这个版本没有问题,重新再启动,把依赖安装一下,然后呢我把这个编辑器重新启动一下。 好,现在这个没有报错了啊,这个现在没有报错了,那这个后面呢,也是一样的,我们给它取一个结果,再呢放大一点,从它下面得到的这个内容啊,再重新启动 p m d v 八零八零端口刷新一下, 这个时候呢,大家其实可以看到还是没有东西,对吧?我们这边呢检查一下,一个是 view 的 插件有给过去端口号呢也是八零八零, 但是最终没有渲染出来,在 app 里面没有给定进去那个东西进去,我们可以把这里稍微改一下吧,改成井号啊,因为刚才这个井号写掉了,这里的话就出来了。你好啊,整个内容呢,大家可以看到完全通过插件的方式,直接可以去拓展 view 的 一个支持。

刚刚面试一个做了两年 vo 一 三的终极前端,我问 vo 三的 ref 和 reactive 有 什么区别?什么时候该用哪个?他说, ref 用于基本类型, reactive 用于对象。我追问,那如果一个对象层级很深,你用 reactive 包装后修改深层属性,试图会更新吗?为什么? 如果我用 reactive 包装了一个数据库,直接给数据库重新赋值,为什么试图不更新? ref 的 value 到底做了什么?他回答的支支吾吾,很多开发者只是机械地使用这两个 api, 却不清楚背后的响应式原理, 导致项目出现性能问题和难以调试的 bug。 如果这道题目你也不会回答的话。我整理了让大厂 hr 沉默的必考题库,包含 vo 灵魂拷问、 react 高频陷阱、 js 十连问、点个赞,评论区甩六六六,打包带走 nice。 深入理解 vo 三的响应式系统需要掌握四个层次,第一层,响应式基础与两种 api 的 设计初衷。 ref 处理基本类型的响应式,通过 value 访问,因为基本类型在 javascript 中按值传递,需要包裹在对象中才能追踪变化。 reactive 处理对象的响应式,使用 proxy 代理整个对象,递归地将所有属性转为响应式。 为什么需要两个 ref 可以 包装任何类型的值,包括对象。当包装对象时,内部会调用 reactive, 而 reactive 只能用于对象。 ref 提供了更统一的 api, 尤其是在组合函数中返回多个指示。第二层,响应式原理与依赖收集 vo 三使用 proxy 代理对象拦截、 get, set, delete, property 等操作。依赖收集在 effect 中访问响应式数据时 会触发 getter, 将当前 effect 收集为依赖。触发更新修改响应式数据时触发 setter, 通知所有依赖进行更新。 深层响应式 reactive 会递归地转换对象的所有嵌套属性,但注意这可能导致性能问题。 第三层,性能优化与陷阱规避,避免超大 reactive 对 象地归代理耗时且可能产生不必要的依赖追踪。浅层响应式 shallow reef 和 shallow reactive 指代理。第一层,避免深层地归 解构丢失响应式使用 tufts 将响应式对象转换为普通对象,但每个属性都是 ref。 保持响应式响应式数据与原始数据,通过 tour 获取原始对象,用于性能关键场景。 第四层,组合式函数与响应式结合自定义组合式函数,利用 ref 和 reactive 封装可附用的逻辑,返回响应式数据和方法。 异步状态管理,在组合式函数中处理异步操作,使用 ref 存储异步结果,配合 watch 和 unmounted 清理副作用与 typescript 集成。使用范行为组合式函数提供类型推断,如 use fetch 测试组合式函数,利用 vo test bullets 或单独测试响应式逻辑,这可厉害。这道题考察的是你对 vo i 三核心响应式系统的理解深度,以及在实际项目中如何正确高效地使用它们。这是区分五 u 三开发者是初级应用还是中级进阶的关键。

hi, 欢迎回来,那么在开始本节之前呢,请你先下载本节的相应的资料。这一节的内容呢, 我比起上一节呢做了一些小的改进,我修改了里面的其中一些组建的内容,主要是这里的 circle property, 我 把这里的固定的文字替换成了 slot, 并且在 app view 中呢添加了这样一些 slot。 所以呢,这一节的代码和上一节我们所使用的这个应用的代码呢, 稍微有那么一点出入,要么你手动自己改一下,也就是把 circle property 这个地方的 slot 改出来,并且把这个地方呢稍微改一下,改成 circle size, 还有 circle rotate。 要么呢,你就直接下载本节的课程资料就可以了。那么我们这一节要做的呢,就是完成 我们目前没有覆盖的最后一个组建 circle property 这样一个组建的测试。那么这个组建的测试呢,其实和之前差不多啊,同样,我们先完成这里的渲染测试,渲染测试的我们要测试这里的 input 元素,这里的 label 元素,然后呢是交互测试。交互测试的话呢,因为我们这里只有一个交互,就是这里的 input 输入框,和之前的 checkbox 还有 select 一 样,我们都是要测试这样一个 input 里面它的值在随着用户交互之后,它的值发生的变化是否在我们的预期之内。那接下来你可以尝试一下去完成我们的渲染测试,或者再进一步尝试一下完成我们的交互测试。 当然这里的话呢,可能会有一一两点比较麻烦的地方,各位呢,可以尝试着去解决一下,当然解决不了也没关系啊,重点呢是要你自己有这样一个探索的过程。那么接下来呢,我就带各位看一下该如何解决 这个组建的测试。那么同样的,我们需要先创建相应的测试文件, circle property test t s 我 们导入相应的这样一些东西, itv 还有 itue 写上 script。 首先呢,是我们测试的这样一个文件名,然后呢是第一个组,第一个组呢,就负责我们的 random test, 对 吧?我们写上第一个测试, it should random the input correctly。 然后呢,我们需要在每次测试之前都重复运行我们的渲染逻辑,那这个地方的渲染的部分呢,就和之前稍微有一点不一样了,我们来看一下 before each, 然后下面使用我们的 random, 对 吧? random 写上我们的 circle property, 那 这个地方呢,我们的 circle property 呢,它需要接收这个 slot, 那 这个 slot 我 们该怎么传进去呢?啊,这是一个问题啊,虽然看起来它好像没有报错,这样渲染出来也是可以的,但是呢,我们接下来如果没有这样一个传入的 slot 的 话呢,待会儿 我们去查询这个 label 标签的时候,我们该寄予怎样的标准来查询呢?我们之前查询 label 标签都是通过 label 标签里面的文本值,但这里的文本值呢,变成了 slot, 那 这里我们该怎么查找呢?所以呢,这里的 slot 我 们是必须要传进去的,那么这个地方呢,稍微麻烦一点, 我们就算来到 testing library 找到它里面的 view 这个部分,这里呢,关于渲染的内容的话呢,其实它什么都没有额外的介绍,可以看到 render 后面它也没有告诉我们该怎样去 传入相应的这样一些需要额外传入的东西,比如这样一个组建,我们该怎样传入它的 prompt, 在 测试的时候以及该怎样传入它的 slots, 但是呢,哎,各位还记得吗?我们之前有说过啊, view 官方其实有提供一个工具叫做 view test tutorials, 而我们这个 testing library view 它是基于这样一个官方测试工具的, 那么是不是意味着官方测试工具中所对应的这样一些写法,我们也可以在 testing library 中去用呢?我们可以来尝试一下。打开来到 view test youtube, 来到它的官网,我们来看一下它的文档,在下面找到 getting started, 我 们来到它的 渲染的部分,那么在 view 官方库有也就是这个叫做 view test utos 的 这个地方呢,它所对应的渲染的这个函数呢叫做 mount, 就是 挂载,然后可以看到它的挂载方式呢,和我们之前的这个做法其实是一样的,我们之前的 random 也是传入要渲染或者说挂载的这样一个组建,那么它这里也是一样,但是呢, 后面它多传入了一个对象,这个对象后面呢就是它可以传入的这样一些东西,可以看到这里它可以传入 prompts, 对 吧?那可以传入 prompts 是 不是还可以传入 slot 呢?我们来搜索一下 slot, 这里没有,那我们在这里全区搜索一下 slot, 这里的版本是不是有点不对劲啊? 哦,这里是 v 一 的版本哈,它官网给的这个地址不太对,我们来到最新版最新的这个官方文档中,我们来 getting started, 下面我们在这里呢搜索这个 slots, 找到这里的 slots, 来看一下这里的写法。好,这里它给了一个简单的例子,它要测试的组建呢叫做 component view, 然后这个组建呢,使用了很多的 slots, 那 么在测试这样一个带有 slot 的 组建的时候呢,可以看到它的做法就是往这个 mount 函数,也就是渲染这个组建的函数中间的后面的这个对象中传入这样一个叫做 slots 的 东西,而这个 slots 呢,可以根据我们这个叉 叉槽的 name 进行传递,也可以传入这个默认叉槽对应的这个值,因为我们的 view 中的这个 slot 叉槽它可以有多种,对吧?那我们这里使用的是默认的叉槽,所以呢,我们选传入这个 default 就 可以了,那是不是意味着我们的 random 也可以这么写?为了验证这个猜想呢,我们直直接看一下这个 random 函数的源码,那么可以看到它抽象出来的这个函数 random 它会接收两个参数,第一个参数是 test component, 这个我们是没什么意义的。第二个呢是参数是 options, 我 们来看一下这个 option 参数,它的类型是 random options, 那 么刚好就可以看到 random option 这个参数下面它所对应的属性有 props 啊,这个可以理解,每个组键 很多组间都会有它的 props, 那 么这里还有一个叫做 slot, 那 么这里呢,我们基本上可以发现它的结构和我们的 view test youtube 的 结构是差不多的,那我们可以参照一下这里的写法, slots, 然后这里我们写上 default, 然后这里传入的文本内容呢,我们就写成 circle property, 希望是没有问题的。接下来的话呢,我们首先要对我们的 input 元素进行查询,然后进行搜索,然后进行测试。那这个地方呢,并不涉及到我们 slot, 所以呢,我们暂时不用操心。那这个地方有个问题, 我们这里要进行测试的组建它里面的这个 input 的 标签类型是 number, 和我们之前的 check box 还有 combo box 都不一样。那么它所对应的 rule 到底是什么呢?难道是 number 吗?那很明显没有,也没有这个 input, 对 吧?所以呢,我们要去 m d n 文档找一下它的 rule 角色。我们搜索 input element, 来到 m d n 文档,在右边找到 technical summary, 那么可以看到它所对应的这个角色呢,其实就取决于它的这样一个 type 属性。那我们这里的 type 属性呢?是 number 对 吧?啊,就在这里啊,它的 type 属性为 number, 那 么对应的它的角色就是 spin button, 我 们写上 spin button, 获取我们的 input。 然后呢,我们写上断言 expect input to be in the document。 此时测试呢,应该是没问题的。好,此时可以看到我们这个 circle property 这样一个文件,它的测试覆盖率就瞬间多了百分之五十啊,因为我们测试好了其中一个部分,然后第二个部分呢,就是测试我们的 label, 我 们来复制这个 it issued the label with correct text。 我 们要根据我们的这个文本内容进行查询,所以呢,这里应该是 get by text, 那 么这里的文本内容是什么呢?难道我们要手动写这里的 circle property 吗?而这里呢,我个人的推荐写法是在和渲染相关的这样一些测试中呢,我们单独写上当前这样一个测试它所对应的这个文本内容,那么我们这里的文本内容呢,我写成这个 slot text, 我 写成这个 component test, 这里的内容随便写,我只是做个演示。然后呢,我个人的想法呢,是在这里呢,对我们的组建再进行一次渲染,然后渲染的过程中呢,我们再把这里的 slot 再给它传进去,所以呢,我们复制这里的写法来到这里粘贴,然后把这个的 default 替换成我们的 slot text。 那 么下面查找的部分呢,自然就是我们的 slot text, 获得的元素就是我们的 label 存音箱,下面也是 label, 此时我们的测试就完成了,我们来看一下我们测试的结果,应该是没有报错的,对吧,看一下,没有报错,但是呢,其实各位如果在这里使用 screen 第一 bug, 你 会发现一个神奇的现象,我们之前有学过这个部分,对吧?大家会发现,在我们这当前这样一个测试 label 标签的这个测试环境中呢,它重复的渲染了两次这样 一些标签属性啊,我们可以在 vtest 的 ui 中看到更详细的,更明确的这样一些内容啊,应该是在 circle property 这个地方是吧?来看 console 啊,可以看到控制台中打印的部分呢,其实可以发现我们将这个 label 标签渲染了两次啊,这是为什么呢?这是因为我们自己在这个 before each 中,我们编辑了这个渲染的逻辑,所以呢,在下面这个 it 这样一个测试运行之前呢, 他自己就会先进行一次渲染,但这次渲染我很明显我们是用不上的,因为我们的渲染呢,要渲染我们针对性的这样一个擦槽的文字,对吧?那么这个地方虽然对我们的测试没影响,但是呢归是会影响我们 这个测试环境的独立性的。你可以尝试着使用我们的 clean up 进行手动的清理啊,也就是我们之前所学到的这个 clean up, 它是来自 testing library 中间的一个可以调用的函数。这样写好之后看一下我们,我还没有导入呢, 按下 tab 它就导入了。此时呢,再来到这个 console 中,可以看到它就只渲染了一次,因为我们把这个 before 一 直中渲染好的这个组件呢,我手动的给它清理了一下啊,这样的话呢,就不会产生什么冲突了。 当然就当前这个测试而言,其实我们清理或者不清理都是没有任何影响的。那么最简单的渲染测试完成了啊,这其实并不是本节的重点啊,本节的重点呢,其实还是在于我们的 交互测试。我们首先来看一下我们这个组建运行 dev, 我 们来看一下我们这个组建,我们这个组建呢,其实就是下面的这个 circle size, 还有 circle rotate 这两个 input 的 输入框。那我们要测试的就是 模拟用户输入对应的内容,然后呢判断这个输入框中的内容呢,和用户输入的内容是否一致啊?就这么简单,那么我们要模拟的重点就是该怎样模拟用户输入这样一个内容呢?那这里呢,我们需要回到 testing library, 在 它左边找到我们的 user interaction, 也就是所有和用户交互有关的地方。那这里我们可以看到有一个部分叫做 keyboard, 它的作用呢,就是 the keyboard a api allows to simulate interactions with the keyboard, 也就是所有模拟和用户 键盘操作相关的这样一些交互呢,都可以通过 keyboard 进行模拟,看起来好像满足我们的要求,对吧?但其实上呢,还有一个操作 在 utility a p s 这里呢,我们之前有用过里面的 select options, 那 么这里还有一个操作叫做 type type 操作呢,其实也可以满足我们的要求,只不过呢,它这里专门提到了 you should say keyboard, if you want to just simulate pressing buttons on the keyboard。 如果你只是想模拟在键盘上 输入,在键盘上按下按钮的这样一些操作的话呢,那么他推荐我们使用 keyboard, 而不是使用这里的 type。 所以呢,我们这里还是最好使用 keyboard 来模拟我们的用户输入,因为用户输入肯定是用键盘,对吧?他不可能用什么奇奇奇怪怪的方式,像我们开发的时候用什么 查找元素,然后直接修改里面的 content text, 这种操作用户肯定不会这样做,对吧?那么 keyboard 的 操作呢,其实很简单,它往里面传入的参数呢,都是字母串,只是呢,有些字母串经过转移之后,比如这里,我们可以通过这样的方式呢,模拟用户按下 shift 的 这样一个操作,那么 具体的很多模拟的部分呢,这下面都有相应的说明,如果你感兴趣的话,可以去简单看一下,那么这里我们要模拟的很简单,就是输入相应的这个数字,对吧?好,其实输入数字,比如输入三十,其实就是按一下三,再按一下零,对吧?那我对应的用户输入呢,其实就是传入 这个字母串,三十就可以了,因为可以看到它能够把对应的字母串呢拆解成单个的字母进行输入,就像它这里所说的,它输入了 f, 但实际上它模拟的操作就是输入 f, o, o 这三个字母。 ok, 那 我们接下来接下来来尝试一下这样一个 keyboard 的 操作。来到第二个组别, 我们新建一个 describe, 还是一样, user interaction, it should display the correct number in the input, after user input, 或者说 after user type, 那 么首先还是一样,我们要查找我们的 input 的 元素,对吧? get by rule, 那 么它的角色是 spin button, 获取我们的 input, 然后用户就要进行输入了,对吧? 那我们首先要获取我们的这样一个用户对象,来自我们的 uzi event 调用我们刚才看到的这个 keyboard, 那 么传入的内容呢,就是我们要输入的这个数字,那么这个数字呢?我抽象一下, input number 我 写成三十,然后呢,这里一定要注意啊,我们的 keyboard 里面传入的不能是数字,它只能传入字母串,所以呢,这个 input number 我 们要转换一下 input number two string, 然后这个 keyboard 操作和之前的 click 都是一样的,它是一个异步的操作, 所以呢,我们要加上 await, 整个函数要变成异步函数,那目前看来好像没什么问题了,对吧?那我们接下来使用断言,期望我们的 input 元素,它拥有相应的值,那么这个值就是我们 写进去的 input number, 那 这里呢,我们就要用这个 input number 这样一个数字来进行判断了,而不是它的字幕串形式。我们来看一下 vtest 哦,我还没运行,行吗?我运行一下测试, 哎,此时可以发现,我们的测试呢,啊,竟然失败了。在这个地方,我们的测试失败了,看一下这个测试的报告 report, 这个测试报告呢,很明显,它告诉我们 expected the element to have value 啊,我们预期的这样一个元素,它所拥有的这个 值应该是三十,但是接收到的值呢,是为 non, 这个就非常的神奇,为什么会为 non 呢?这里呢,还有一个部分,就是我们当前这个 circle property, 它其实还会接收这个 叫做 property 的 这样一个 model, 我 们其实缺失了这样一个 model, 或者说缺失了这样一个 props。 所以呢,这个这样一个 circle property, 它渲染出来的,它所对应的这个 input 元素中间的值呢,也是没有定义的啊。这个地方呢,其实我们 还缺少了一点,我们还需要加上这个 props, 这个 props 叫做 property, 它是一个数字,我给它写上零, 这样给他的值出手化之后呢,哎,此时呢,可以看到,他告诉我们,刚才接收到的值还是为零,现在就变成零了,那很明显,我们输入的值呢,并没有修改我们音符的元素中间的值,我们的修改是无效的, 也就是说这里模拟用户操作的这样一个 keyboard, 他 是无效的,这是为什么呢?那这里呢,我们要看一下我们用户使用这样一个组建时的场景,我们先取消我们的测试,回看一下我们整个项目, 我们用户的使用场景呢?我们以刚才的这样一个测试代码的角度来看一下,如果我们让用户来模拟我们这样一个使用场景的话,会是怎样? 我们第一个操作是查找这样一个元素,也就是这样一个 input 的 元素,那查找这个动作在用户看来该怎么做呢?好像就是拿鼠标晃一晃,或者或者拿眼睛看一下啊,明确这个元素在这里, 这个 input 的 输入框在这个地方,然后呢我们就直接让用户输入了这个三十这样一个值,其实就是按一下三和十,对吧? 比如我这里啊,我找到了这样一个 input 的 输入框,然后呢我输入三十,哎,发现什么问题没有?我们这里的值其实并没有被修改,为什么呢?正常我们的用户应该是点一下再往里面输入值,对吧?那很明显我们这里插了一个点一下的这个操作,这里相信大家就找到问题所在了吧,所以呢,我们这里还需要 让用户点一下我们要输入值的这样一个元素才行,也就是使用 click。 此时呢,我们再看一下我们的测试,此时所有的测试呢,都运行成功了啊,这里的报错呢就消失了,我们再重新运行一下, 然后来到我们的 coverage, 那 此时呢,我们的 s r c components 里面所有的组建它的测试覆盖率都是百分之百,这里的 circle property 就 没有没被覆盖的这样一些测试的部分非常简单,对吧?只是呢,这里的 s r c 里面跟目录下这两个文件,它提示我没有被测试覆盖到,但这个地方很明显 我们不需要去测试它当然看起来很烦,是吧?啊,为了解决这个问题呢,很简单,我们完全可以在我们的 vita 配置文件中,在这个 coverage 的 include 这个配置下面, 我们只包含 s r c components 下面的这些文件测试覆盖就可以了。此时我们刷新 再次来到 coverage 这里的话呢,我们所有的部分呢,它就显示测试覆盖完全了啊。再回到我们的终端这里呢,也会显示百分之百,所有的文件都是百分之百的测试覆盖,这又治好了强迫症了。那么到此呢,我们就完成了整个项目所有 组建的测试啊。今天这个组建呢,稍微比较麻烦,因为我们需要传入 props, 需要传入 slot 啊,尤其是这个 slot, 它和 view 组建的这个 slot 的 这个联系比较紧密,需要你去看一下 view 官方对这个 slot 叉槽它的处理方式啊。这里刚才我们翻了一下 view 的 官方测试工具它的写法,还翻了一下它的源码,对吧,才解决了这个问题。好,所以呢,这方面的文档是比较缺失的,如果你感兴趣的话,可以给 testing library 提交一些 pr, 帮助他们去解决这个文档缺失的部分。这一节比较重要的一下,在进行测试的时候,千万不要以 开发的角度去理解用户的操作,我们应该以用户的角度来进行测试,来理解我们用户交互的逻辑。比如刚才这个地方,我们想当然的就以为我们查询了这个元素之后,然后模拟用户输入内容,那么就应该是输入在这个元素中的。 但实际上呢,我们的用户应该是先点击这个元素再输入的,但我们之前的这个工程开发的习惯就是直接选择元素,然后修改里面的值,但是呢,用户是没有选择元素这样一个操作的,他只会点击元素, 拖拽元素,或者是把鼠标放在某一个地方点一下,他是没有所谓的选择元素这样一个操作的。所以呢,各位一定要完成这样一个思维上的转变,当然我知道这个很难,很多人其实都做不到这一点,所以导致在测试的时候呢,会有发生很多的疏漏, 这是很正常的事情。那么以上就是本期视频的所有内容,希望你能关注或定义我的频道,感谢你的观看,我们下期视频再见!

new 开发的兄弟注意了,是不是一座大数据表格就卡成 ppt 实时数据,想加个高量还得手写一堆大 m 代码?今天给大家分享个宝藏,组建 s t k table view, 专治表格性能拉胯,高量难搞的问题,直接分神。 先看这性能,传统表格渲染上千条数据卡到没法用。它内置虚拟列表,只渲染格式区域,上万条数据滚动都丝滑如得福。而且 view 二点七和 view 三通知 老项目不用重构,直接用。最香的是实时高量一行代码就能给变化的行单元格加动画,颜色,时长随便调,不用碰原声档,完全贴合 build 的 开发习惯。 官网还有在线 demo, 点开就能改代码看效果,新手也能秒会,感兴趣的赶快去试试吧!觉着有用的话记得点赞收藏关注我,专注分享有趣且实用的互联网科技资讯。

嗨,欢迎回来,之前的所有学习中呢,我们一直都没有系统性的学习过,到底测试该怎样分类,以及我们到底要做怎样的测试,对吧? 今天呢,我们就以理论的方式呢,简单带各位介绍一下关于测试的分类,还有我们大致的一个测试的方向,这样也让大家心里有一个底。那么这里呢,我们直接以 vivo 官方关于测试的部分呢,说实话,写的挺好的, 隔壁 react 写的好多了,隔壁 react 完全是不管大家的这个死活的。那么关于测试呢, view, 这里其实说的也很简短,后面呢,我会以另一篇 blog 为补充,带大家看一下具体的内容。那么这里的话呢,它大致把测试分为了这样三个类别,第一个是 unit, 即所谓的单元测试,这也是很多人一直听过的一个词,单元测试呢,其实不管是前端还是后端,它都是存在的,只是呢,在前端中,单元测试很多时候都被弱化了, 位,它有另一个东西为替代,就这里的 component, 大家可以把它理解成组建测试。大家通常意义上理解的前端开发中最小的单位,其实不是所谓的类或者说函数,而是我们的 component 的 组建,也就是一个点 view 文件,大家通常都把它作为最小单位来理解。然后呢,就是 所谓的 e to e, 也就是所谓的 n to n, 很多地方也把它叫做 e, e to e, 也就是所谓的端到端测试。那么它们三个的区别呢?其实很简单,所谓的 unit, 也就是单元测试,其实就是以 某一个东西为最小单元,可能是一个函数,可能是一个类,甚至也可以是我们的组件,所以呢,这个单元测试它到底以以什么东西为准,就决定了我们 整个测试它的编遣方向。所以呢,这个是有很多争议的,如果你只只写个后端应用的话呢,你会觉得单元测试就只针对一个函数,或者说一个 controller 进行测试就可以了,但是在前段中呢,是比较复杂的,所以呢,这里第二点显现出来了,我们的组建测试,也就是以组建为单位,测试它的 这样一个渲染是否正常,它的交互是否正常,这其实是我们之前一直在做的事情,我们在测试它的 render 渲染部分,还有 interact, 也就是 和用户交互的部分啊,这是我们一直在做的测试,并且这个地方强调了一下, these tests import more code than unit tests 啊,这个地方往往写的代码呢,是比起我们的 这个单元测试是要更多的啊。这里就不得不提到很多人会推崇的一个简单的图标,它叫做 test pyramid, 也就是所谓的测试金字塔,就是这样一个图。在大多数人的认知中呢,所谓的测试一般都是分为单元测试,集成测试,还有最上层的这个端到端的测试啊,但实际上呢,在有前端中,一般来说没有中间这个所谓的集成测试的部分,因为 中间的这个集成测试的部分呢,一般都被我们的组建测试给它替代掉了,甚至呢,很多单元测试呢,都给它囊括到了我们的组建测试中呢。其实很多时候,我们 与其说它是单人测试,不如说它是组建测试,而最后这个 end to end, 也就是所谓端端端端端测试,其实就是遵循我们用户的这样一个使用的具体流程来实现 这样一个测试。那么端端端测试呢,也是最最少的,因为它涉及到流程比较多,所以呢,测试编辑和维护都是比较麻烦的。那具体下面的介这些介绍的话呢,大家可以选择性的看一下,主要的话呢,还是这里他推荐的 工具,我看应该是在这里啊, recommendation 这个地方,在这里的单元测试下面它推荐的工具呢,有两个啊,第一个呢,很明显就是他们 view 生态官方所推荐的这样一个 vtest 啊,这也是我们在学习使用的工具。第二个呢才是 test, 虽然现在 test 还是用的人偏多,但是我相信未来肯定是属于 vtest 的, 因为 vtest 能够和我们的 vt 进行深度的集成,依靠 vt 生态,相信它其实用不了多久就能够超越 test, 并且 vtest 现在的功能呢,也越发强大,其实在功能的丰富层面上, 是要远超我们的 test 的, 只是这个迁移成本可能有点高。具体这里的内容呢,我就不细讲,因为我们其实暂时还涉及不到最上层的这样一个 e to e test, 所以呢,暂时没有讲的必要。那么接下来呢,我就以一个 vlog 为例子啊,带各位看一下关于测试的更深入的内容。这是多个作者一起写的它们 的这篇 blog 的 话呢,是基于多个企业进行调研之后编写的一份关于前端测试的一篇 blog, 我 觉得非常有价值,虽然是为了推广他们的产品,但是呢,中间关于 单元测试,组建测试,基层测试,还有端大端测试的内容呢,都非常值得各位去仔细阅读啊。这里我只挑几个我觉得比较重要的部分呢,给各位简单讲解一下。那么首先呢,就是 测试它具体在前端开发的过程中应该做什么,或者说我们在前端的应用中测试的东西到底是什么啊?就在这个地方, what to test? 好, 我们具体测试的是什么?这里它分为了五个部分,第一个部分,逻辑 及我们对应的前端应用的这样一个逻辑,它是否正确。然后呢是 random and behavior, 渲染与行为,对吧?也就是我们组建它是否能够成功渲染,以及 它和我们的用户交互是否正常,其实我们目前就停留在上面这两,当然我们目前做的还是第二层,也就是 random and behavior, 我 们现在主要还是集中在组建的测渲染测试,还有它的用户交互,行为测试上。那么逻辑测试的话呢,类似于我们的单元测试, 逻辑测试的话,一般来说就是用来测试我们的各种各样的一些小函数,小的一些工具类的,但我们目前还没有给各位展示过,对吧?那么后面呢,我们结合一些更复杂的场景呢,我们 会涉及到相应的内容。然后第三个是 accessibility, 也就是无障碍,那么这一点呢,对于前端来说是非常重要的,只不过呢,很多很多的前端开发,它其实都会忽略这一点,尤其是在中国,中国其实 基本上不怎么注重无障碍这一块,别说无障碍了,尤其很多前端开发,他对他的整个用户体验都不是很好,更别说去兼顾你的这个无障碍。那这里所谓的无障碍呢,就是我们的前端应用对于屏幕阅读器是否足够的友好, 或者说对于只用键盘来进行浏览的这个场景下呢,是否足够友好,这一点呢,我们依然没有涉及到,对吧?那么说实话,无障碍的这样一个 测试的话,它也是比较难的,因为大多数人其实没有没有通过屏幕阅读器,或者说只用键盘的方式来浏览过网页,所以呢,很多测试人员很难想象该以怎样的方式来测试我们前端的这样一些方面,这也是一个比较难的点。第四个呢就是 appearance, 即所谓的这样一个组建,它看起来的样子,这个呢也是比较抽象的。最后呢就是 user flows, user flow 其实就是刚才我们的测试金字塔上面的最上一层 e to e test, 它用来表示的就是模拟我们整个用户它的一个实际的交互行为的这样一个测试。那么很明显这样五种测试的内容呢,它是 由浅及深,由简单到复杂的,所以它给了一个更为复杂的一个模型。最下面的是 static, 也就是一些简单的代码测试,比如代码的类型检查,代码的规则检查啊,这些呢我们用一些第三方工具,比如我们用 type script, 我 们用一些 yes link, 或者是 bio me, 或者是 ex c, 相应的这样些 linter 和 format 都都能够帮我们解决相应的问题。 然后呢是单元测试 unit test, 然后再往上的话,可以看到它其实分为了很多种,这里有一点我觉得非常值得各位关注,就是这里的 component, component 就是 组建的意思,那么 component 的 测试包含了什么呢?就这里的 random, 还有 user behavior, 也就是这里的第二步渲染和我们的用户交互测试,那么可以看到它在这里的占比呢,甚至超过了我们的 unit test 单元测试,对吧?那么为什么组建的测试会 远超于单元测试呢?而不是像我们刚才看的那个金字塔一样,明明应该单元测试最多的啊,这也就是前端测试和我们 呃传统的这个测试三金字塔之间的一个冲突的地方,或者说不一样的地方。前端测试中呢,很多时候,我们的最小单元其实应该是前端的组建,尤其是在我们都以组建为单位进行前端开发的这样一个大背景下,大多数的前端测试呢,都会注重以组建为这样一个 unit 进 测试。并不是说单元测试它不重要了,而是单元的这样一个最小单位,从一个模糊的 unit 这样一个单词,变为了我们 在前端场景中更具体的 component 组建这样一个单词啊。所谓的 component test, 你 也可以理解成另类的 unit test, 它也是一种单元测试,只是划分的这个单位不一样, 仅此而已啊,这是在前端中比较特殊的一点,但是这里呢,很明显可以看到它没有强调所谓的集成测试,也就是这里的 integration test 啊,这是为什么呢?啊?这其实是因为在我们所谓的组建测试中呢,很多时候它其实就包含了一些集成测试啊,很多时候呢,就包含了这个父子组建的一些 联动起来的测试,或者说包含了一些在一个比较长的流程中,比如我们之前实现过的,在一个组建中实现用户点击选择,然后验证的这样一个 比较长的测试流程啊,这个也其实也算是一种集成测试,它们都包含在了我们的 组建测试中,也就是这里的 component, 所以呢,这个 component 看起来非常的大,它包含了大部分单元测试的中间的一些内容,它也包含了一部分集成测试中间的内容。然后呢,在这篇 vlog 的 第三点, unit, 也就是所谓的单元测试这个地方呢啊,它详细讲了一些和单元测试相关的东西,是吧, 它在这里的这样观点呢,其实就和上面这个图片完成了吻合啊,重点就是这里这一句话, however, unit tests are used less frequently in front end development because a majority of our code is intended for the web browser。 即所谓的传统的单元测试,其实在前端开发场景中呢,它是比较 少见的,因为在前端开发的场景中呢,我们的代码它基本上都是要在浏览器中运行的,所以呢,大多数都是所谓的 mostly integration, 大 多数都是所谓的集成测试啊, 所以呢,传统意义上的那种单元测试,就是以某个单个函数,单个工具类为单元的。这种单元测试的话呢,在前端中其实比较少见,更多见的还是在 强调过的以组建为单位的测试,所以呢,单元测试的概念呢?各位在前端中就不要过度的去纠结它了,我们在前端中应该着重了解的应该是这里的 component, 我 们接下来看一下 component 它讲了什么,那么在 component test, 也就是组建测试这里呢,它给了一个明确的定义 啊,这个定义的话呢,未来的话呢,有可能这个观点会发生一些转变,所以呢,各位不必去纠结,它给的定义就是 component tests bridge, the gap between unit and n to n test, 它是单元测试和端到端测试的这样一个桥梁,也就是说呢,我们的组建测试,它其实 既包含了一些单元测试的特性,它也包含了一些端到端测试,或者说所谓的集成测试的这样一些特性。所以如果大家真的要去细分这样一个所谓的前端测试,它具体属于哪一类的话呢? 如果用传统的这样一个这样一个测试金字塔去划分它,是没办法把它划分到某一个 层次中的,那只能说它位于中间这一块啊,从上到下它都有设计。所以呢,我之前的课程中呢,也一直没给各位强调过我们编辑的这样一个测试的分类,因为如果用传统的分类来讲,其实是比较难讲清楚的,那么回到这张图本节的重点呢,其实我还是希望大家 记住这样一张图中比较重要的 component unit, 还有 n to n 这三个部分就可以了。大家只需要知道,在前端测试中呢,我们应该着重关注的是我们的 component 为单位的这样一些测试,而不是去纠结它到底是所谓的单元测试,还是所谓的机身测试,还是所谓的 端端测试啊?其实在一个所谓的组建测试中呢,它这三个东西都有可能设计,或者是它可以同时实现这三个东西。那么希望这一节呢,可以让大家了解到在前端中的 测试的分类应该是怎样的,我们所谓的组建测试,它到底意味着什么?那么以上就是本期视频的所有内容,希望你能关注或定义我的频道,感谢你的观看,我们下期视频再见!

刚刚面试一个做了两年 vivo 三的终极前端,我问 vivo 三的 raf 和 reactive 有 什么区别,什么时候该用哪个?他说, raf 用于基本类型, reactive 用于对象。我追问,那如果一个对象层级很深, 你用 reactive 包装后修改深层属性,试图会更新吗?为什么?如果我用 reactive 包装了一个数值,直接给数值重新赋值,为什么试图不更新? rev value 到底做了什么?他回答的支支吾吾,很多开发者只是机械地使用这两个 a p i, 却不清楚背后的响音式原理, 导致项目出现性能问题和难以调试的 bug。 如果这道题目你也不会回答的话。我整理了让大厂 hr 沉默的必考题库,包含 vivo 灵魂拷问、 react 高频陷阱、 j s 十连问点个赞,评论区甩幺幺幺,打包带走真香,哎呀。 深入理解 view 三的响应式系统需要掌握四个层次,第一层,响应式基础与两种 a p i 的 设计初衷。 ref 处理基本类型,如 string, number 的 响应式,通过 value 访问,因为基本类型在 javascript 中按之传递, 需要包裹在对象中才能追踪变化。 reactive 处理对象的响应式,使用 proxy 代理整个对象, 地规的将所有属性转为响应式。为什么需要两个 ref 可以 包装任何类型的值,包括对象,当包装对象时,内部会调用 reactive, 而 reactive 只能用干对象。 ref 提供了更统一的 api, 尤其是在组合函数中返回多个值时。第二层,响应式原理与依赖收集 vo 三使用 proxy 代理对象,拦截、 get, set, delete, property 等操作。依赖收集在 effect 副作用中访问响应式数据时 会触发 getter, 将当前 effect 收集为依赖,触发更新修改响应式数据时触发 setter, 通知所有依赖进行更新。第三层,性能优化与陷阱规避,避免超大 reactive 对 象递归代理耗时且可能产生不必要的依赖追踪。 浅层响应式 shallow rev 和 shallow reactive 指代理第一层,避免深层递归结构丢失。响应式使用 two revs 将响应式对象转换为普通对象,但每个属性都是 rev。 保持响应式响应式数据与原始数据, 通过出肉获取原始对象用干性能关键场景,如大型不可变数据的处理,循环引用与内存泄露。正确使用 marko 标记不需要响应式的对象,避免意外代理。第四层,组合式函数 compressibles 与响应式结合 自定义组合式函数,利用 raf 和 reactive 封装可附用的逻辑返回响应式数据和方法。 异步状态管理,在组合式函数中处理异步操作,使用 rev 存储异步结果,配合 watch 和 ornamented 清理副作用与 tab script 集成。使用范型,为组合式函数提供类型推断, 如 use fetch t u ray 测试组合式函数,利用 view test tutorials 或单独测试响应式逻辑。 哇,这道题考察的是你对 vivo 三核心响应式系统的理解深度,以及在实际项目中如何正确高效地使用它们,这是区分 vivo 三开发者是初级应用还是中级进阶的关键。