广告
广告
广告
前言最近才发现,nuxt3项目打包后会产生两份css内容,一份是内联样式,一份是css文件样式,最终是css文件样式覆盖了内联,但是这两份样式是一模一样的,而且都是vue组件才会有这种情况,让人不得不怀疑是不是打包出现问题了。事实上也并非如此,这是nuxt3的一个特性,且仅在使用vite的时候才会有,这个特性就是inlineStyles内联样式,这样html可以很快的渲染出东西,大概是这样一个意思。如果你不需要,或者部分组件不需要,可以通过配置进行修改。教程[hide]我们找到nuxt.config.ts文件,配置如下内容:export default defineNuxtConfig(...
前言以前使用PostCSS做css兼容性处理,常常就是使用autoprefixer做个浏览器前缀处理就完事了,但是实际上如果真要实现所谓的兼容性处理,css甚至还需要做转换处理,类似于js的async...await的语法转换处理。autoprefixer只是自动添加浏览器前缀,而本次使用的postcss-preset-env除了自动添加浏览器前缀,并且会根据目标浏览器自动转换成兼容的格式,包含许多其他 CSS 提案的 polyfill。举个例子::root { --main-color: #06c; } body { color: var(--main-color);...
前言最近在写新的项目,其中遇到一个问题,我的登录页和注册页相关的页面,他们的布局是相同的,所以理所当然的封装了一个layout组件,然后每个页面自己import引入它并使用,这么看其实没有问题。但是当我给layout增加了一个持久的动画的时候,切换页面由于组件会重新渲染,这就导致动画又重新开始了,显得整体非常突兀。于是不得不将layout组件提升到route-view路由视图的外层,然后又要考虑其他layout布局也要生效,于是就有了仿nuxt的动态布局的需求。我希望在路由的meta配上一个layout属性,然后通过这个属性指定对应的布局组件。[hide]代码注意事项首先不能直接从rou...
先确保能访问外网输入ping命令测试:ping -c 4 www.baidu.com意思是ping 4次指定网址,这里是ping的百度。然后返回如果有响应值就是可以的,例如:PING www.baidu.com (183.240.98.161): 56 data bytes 64 bytes from 183.240.98.161: seq=0 ttl=49 time=32.139 ms 64 bytes from 183.240.98.161: seq=1 ttl=49 time=32.683 ms 64 bytes from 183.240.98.161: seq=2 ttl=49 ...
前言这个是无意间看到b站的一个视频,发现挺好的,css实现本身还不吃太高的配置,视频链接如下:【Sass实现星空效果【渡一教育】】教程中使用了scss的除法运算法,但是这个用法在新版本中已经弃用了,现在推荐使用math语法,如果你的scss版本是新版本的,比如1.77.1,使用这种方式会报错。教程配置Math语法支持在vite的scss中配置如下;// vite.config.ts export default defineConfig({ css: { preprocessorOptions: { scss: { additionalData:...
前言当我们访问一些需要登录才能访问的页面,通过路由守卫我们会被重定向到登录页,同时会在链接参数里携带一个redirect字段,表示登录完成后跳转到redirect的路由。单独考虑这个问题,我们只需要在登录页处理这个问题就行了,但是随着业务的变化,有时候不一定只在登录页使用,这个重定向的功能可以在多处使用。总不能在每个要用到重定向的地方加if判断是否存在redirect字段吧。为此我封装了一个专门处理重定向的hooks:useRedirect.ts代码[hide]// useRedirect.ts import type { RouteLocationRaw } from "vu...
前言当我们使用Object.keys获取某个对象的key数组的时候,ts推导出来的类型是string[],当我们再通过forEach去遍历这个key数组时,由于string类型与对象具体的key不一致,导致报错:素隐式具有 "any" 类型,因为类型为 "string" 的表达式不能用于索引类型。我感觉ts这里的推导能力太差了,明明已经把具体的对象传递给他了,结果它直接返回一个string[]类型来一劳永逸,导致后续通过string类型去拿对象的value,就导致类型不匹配了。解决办法以前的我会这样写:const kindMap = { balance: 1, gpu: 2 };...
前言这是个非常有意思的情况,由于我一直没有平板设备,所以这个问题一直都没有遇到,我一直相信在pc端通过媒体查询就可以适配到所有的机型,加上我用手机查看的时候,也是没有问题的,所以一直相信至今。结果我最近收了一台二手平板来帮助我学习的时候,发现出了一个大问题,在pad端访问我的主题,首页文章的卡片字体会突然被放大了,我以为是css的问题,结果调试的时候发现css没有变化,但是实际渲染的字体大小由原来的13px变成了20.0549px,这显然有问题。而且我发现只有p元素字体会发生这种情况,贼奇怪,难道语义标签会带着隐性的兼容问题?这是在平板中的效果,p元素的字体比标题还大了。这张是我在电脑端...
前言之前的vite很多文章一直推荐使用的是rollup-plugin-visualizer插件,但是这个插件真的一点都不好用,和webpack的体积分析差太多了。这次新项目中也需要用到体积分析,需要我找了很久,找到一个新的插件,基本上可以和webpack的体积分析差不多体验了。插件:vite-bundle-analyzer效果图:相比较之前的还是挺好用的。教程先安装依赖:pnpm i vite-bundle-analyzer -D然后去vite.config.ts中配置:import { defineConfig } from "vite"; import { ana...
前言git仓库如果有人提交了一次改动,然后你本次改动也修改了相同的文件,提交数据时就会触发文件diff,此时git会产生一条merge记录,我们需要手动调整好冲突保存在push到仓库。如果merge产生太多了会对整个git历史记录变得复杂,实际上大部分情况下这个meger内容是不重要的,有的公司会要求我们在拉取数据时使用rebase,用于去除meger的产生。命令一般是:git pu11 -r命令中的 -r 选项实际上是 --rebase 的简写形式。它告诉 Git在从远程仓库拉取更新时,使用rebase 而不是默认的 merge 策略。下面解释-下 rebase 和 merge 的区别...
前言在事件代理中,往往有的时候我们需要生效的部分会存在其他元素影响,比如我可能需要响应一个卡片的点击事件,但是这个卡片里面自身又有其它link元素,比如卡片的分类,tag标签等,当我们点击分类或者tag标签,由于事件冒泡的原因,他也会触发事件代理的click事件,也就是父级元素的click事件。但是显然我们不需要响应他们,如果单纯通过event.target去排查,是不够完善的,有可能这个target是一个无class的元素,或者是同时存在多个的元素,我们可能还希望通过指定他们的父级元素class来进行排除。教程const blackClassList = ["article-...
什么是接口接口是对象能响应的请求的集合我们经常说一个库或者模块对外提供了某某 API 接口。通过主动暴露的接口来通信,可以隐 藏软件系统内部的工作细节。这也是我们最熟悉的第一种接口含义。 第二种接口是一些语言提供的关键字,比如 Java 的 interface。interface 关键字可以产生一 个完全抽象的类。这个完全抽象的类用来表示一种契约,专门负责建立类与类之间的联系。 第三种接口即是我们谈论的“面向接口编程”中的接口,接口的含义在这里体现得更为抽象。Java中的抽象类java中为了实现对象的多态性会使用向上转型的超类型来作为值的约束,这个向上转型的超类型就是抽象类或者inter...
单一职责 SRP个类应该仅有一个引起它变化的原因。更具体地说,单一职责原则意味着一个类应该只负责一项职责或功能。如果一个类承担了过多的职责,那么在软件的修改过程中,修改某一功能可能会影响到由这一类管理的其他功能。遵循单一职责原则可以使类更加独立,从而容易理解、维护和扩展。在JavaScript中类往往是弱化的,因此单一职责往往更多的应用在对象和方法上。代理模式中的单一职责我们实现一个图片的懒加载它需要做两件事件,第一件是创建img图片并添加到页面中,第二件就是占位图设置和实际图片加载完成后重新赋值src。利用单一职责,我们将其拆分成两个方法:var myImage = (function...
前言最近在阿里云盘上搞到了几份视频资源,由于挺大的,就不想长时间开电脑下载,加上已有pve主机了,直接在pve上下载并存到pve自己的磁盘上不就行了。于是我一开始就通过Alist这个网盘聚合的工具来实现下载,但是发现有一个很蛋疼的问题,当我通过alist将网盘的文件复制到挂载的本地磁盘上时,虽然文件确实有在下载,但是没有任何提示,没有进度条,我唯一能拿来做判定条件的就是pve的网络波动,但是这样也不是万能的,因为下载到一半突然直接网络波动消失了。我心想完蛋,怕是白下了,估计是哪个文件下载失败报错了啥的。为了解决这个问题,我能想到的最佳方案就是用pve去虚拟一个windows系统,然后wi...
前言适配器模式是一种结构型设计模式,它允许对象在不改变对象接口的前提下,在不兼容的系统之间进行交互。适配器模式通常用于将已有的类的接口转换为另一个接口,以便系统中的其他组件可以与之交互。在适配器模式中,通常涉及三个角色:目标(Target)接口:当前系统期望使用的接口,它定义了客户端所需的特定域的操作。需要适配的类(Adaptee):已存在的类,其接口不符合目标接口的要求。适配器(Adapter):实现目标接口,并在内部封装有一个需要适配的对象实例。适配器负责接收调用并将其转换为对适配对象的接口调用。适配器模式往往不是一开始就会去使用的,因为没有人能知道未来会发生了什么,使用它往往是因为...
前言状态模式是一种行为设计模式,用于在一个对象的内部状态改变时改变其行为。这种模式通过将每个状态封装成独立的类,并将动作委托到代表当前状态的对象,从而实现状态与行为的分离。状态模式的组成三个主要部分:环境类(Context):维护一个指向当前状态对象的引用,并将所有与该状态相关的工作委托给它。抽象状态类(State):定义一个接口以封装与环境类的一个特定状态相关的行为。具体状态类(Concrete State):实现抽象状态类的接口的类,为具体状态提供了行为的实现。说白了就是将状态和状态具体的逻辑封装成一个个状态对象,通过抽象状态类统一接口方便调用,我们通过事件或者其他去触发的是环境类上...
前言装饰者模式是一种经典的设计模式,它允许向对象动态地添加额外的功能。这种模式通过创建装饰类来包裹原始类的实例,从而达到增强原始类功能的目的,同时不影响原始类的结构。装饰者模式在设计之初是想称为包装器模式的,因为从结构上看,这种说法更加符合它,通过一个对象包裹另一个对象,甚至多个对象进行嵌套。在JavaScript中实现一个装饰者模式是非常简单的一件事,因为是一本动态语言,它都不用像java那样需要写一个类来包装源对象,最简单的做法就是直接改写对象的原属性,在实际的代码中,常常用函数来进行实现装饰器模式。 var obj = { name: 'sven', ...
前言中介者模式(Mediator Pattern)是一种行为设计模式,其主要目的是降低多个对象间的通信复杂性。这种模式提供了一个中介者对象,这个对象通常封装有具体对象之间交互的方式,使得对象之间不需要显式地相互引用,从而使其耦合松散,可以独立地改变它们之间的交互。中介者模式就是为了解耦多个对象之间的关联,让他们不在相互依赖,而是依赖一个公共的对象,这个对象就是中介者。中介者模式优化后:中介者模式例子:购买商品我们有一个手机购买页面,手机目前配置选项有:颜色,我们需要根据用户选择的颜色和购买数量,来控制购买按钮是否可以点击,已经库存是否足够。<body> 选择颜色: &...
前言职责链模式,它为请求的发送者和请求者之间实现了解耦,他将具体的请求者连成一条链,并沿着这条链依次处理请求,直到有一个对象处理它为止。这么说可能不好理解,其实就是将复杂的条件判断进行了解耦处理,具体我们看下面的例子。商城购买我们现在有一个优惠活动,如果用户交了500元定金,他在购买的时候可以收到100元优惠卷,如果是交了200元定金则收到50元优惠卷,如果没有定金,那就没有优惠卷,库存有限的情况下不一定保证能买到。假设我们有这三个参数:orderType:表示订单类型(定金用户或者普通购买用户),code 的值为 1 的时候是 500 元 定金用户,为 2 的时候是 200 元定金用户...
前言享元模式是一种性能优化的模式,它通过共享对象的方式,减少实例对象的数量,它将对象的属性拆分为内部属性和外部属性,内部属性是可以共享的,外部属性是无法共享的,我们将共享的部分封装到对象中,然后大家共用这一个对象,通过方法或者直接赋值外部属性给这个对象,从而实现对象的复用。但是赋值的过程是会耗时的,这就是典型的时间换空间的优化方式了。享元模式是一种结构型设计模式,旨在减少应用程序中的内存使用或计算开销,通过共享对象实例来优化性能。初识享元模式假设有个内衣工厂,目前的产品有 50 种男式内衣和 50 种女士内衣,为了推销产品,工厂决 定生产一些塑料模特来穿上他们的内衣拍成广告照片。 正常情...
前言模板方法模式的核心在于:定义一个操作中的算法骨架(模板方法),并将某些步骤延迟到子类中实现。通常我们会抽象一个父类,父类封装了子类的算法框架,包括实现一些公共方法和所有方法的执行顺序,子类继承父类,可以自己重写父类的方法。在模板方法模式中,子类实现中相同部分被上移到父类中,而将不同的部分留给子类来实现,最后由父类的模板方法来控制整个算法的执行顺序和流程,子类只关心具体的算法实现。这种方式十分依赖抽象类,但是JavaScript中很难去模仿一个抽象,但是我们也可以用自己的方式去实现。咖啡和茶这个是一个非常经典的例子,有助于我们理解什么是模板方法模式。泡一杯咖啡泡咖啡的步骤通常如下:把水...
前言组合模式真的很难在一些业务项目上有所体现,但是当我们完完全全从零触发去构建一些东西的时候,组合模式还是很有用处的。组合模式是一种结构型设计模式,它可以让你将对象组合成树形结构以表示部分整体的层次结构。组合使得用户对单个对象和组合对象的使用具有一致性。在组合模式中,通常有两种类型的对象:叶子对象(Leaf):不包含子对象的对象。容器对象(Composite):包含叶子对象或其他容器对象。注意重点是这个一致性,我们通过上层类型约束,要求叶子对象和容器对象都需要实现我们指定的接口,然后我们就可以放心的进行组合了。最终我们可以发现,组合这些对象,得到的是一种树形结构,因此组合模式也被称为树枝...
前言命令模式(Command Pattern)是一种行为设计模式,它将一个请求或简单操作封装成一个对象,从而使你可以使用不同的请求、队列或日志请求来参数化其他对象。同时支持可撤销的操作。命令模式主要包含以下几个角色:命令(Command)接口 - 声明执行操作的接口。此接口通常定义了一个执行具体命令的方法。具体命令(Concrete Command) - Command 接口的实现对象,它定义了绑定在接收者上的动作之间的关联。当命令的 execute() 方法被调用时,将会把动作转发给接收者去执行。客户(Client) - 创建一个具体命令对象并设置其接收者。有时客户负责创建并设置命令对...
前言发布订阅模式使用上也非常广泛,比如vue的响应式数据就用到了发布订阅模式,前端的原生事件也是发布订阅模式,这种模式主要解决的就是异步的问题,用于代替回调函数,且使得两个对象是松耦合的联系再一起。发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。在 JavaScript 开发中,我们一般用事件模型 来替代传统的发布—订阅模式。发布订阅实现var event = { eventMap: new Map(), on(eventName, callback) { let eventL...
最近评论