![【萌主机】宝塔内核EP面板虚拟主机——稳定高速,CF优选接入体验](https://moe.al/GGP.png)
![“可乐云”机场](https://mulingyuer-1253375624.cos.ap-guangzhou.myqcloud.com/%E5%9B%BE%E7%89%87%E7%A9%BA%E9%97%B4/%E2%80%9C%E5%8F%AF%E4%B9%90%E4%BA%91%E2%80%9D%E6%9C%BA%E5%9C%BA07.png!Anti_theft)
![毒鸡汤API网站](https://www.mulingyuer.com/usr/uploads/2024/07/4208340342.png)
前言模板方法模式的核心在于:定义一个操作中的算法骨架(模板方法),并将某些步骤延迟到子类中实现。通常我们会抽象一个父类,父类封装了子类的算法框架,包括实现一些公共方法和所有方法的执行顺序,子类继承父类,可以自己重写父类的方法。在模板方法模式中,子类实现中相同部分被上移到父类中,而将不同的部分留给子类来实现,最后由父类的模板方法来控制整个算法的执行顺序和流程,子类只关心具体的算法实现。这种方式十分依赖抽象类,但是JavaScript中很难去模仿一个抽象,但是我们也可以用自己的方式去实现。咖啡和茶这个是一个非常经典的例子,有助于我们理解什么是模板方法模式。泡一杯咖啡泡咖啡的步骤通常如下:把水...
前言组合模式真的很难在一些业务项目上有所体现,但是当我们完完全全从零触发去构建一些东西的时候,组合模式还是很有用处的。组合模式是一种结构型设计模式,它可以让你将对象组合成树形结构以表示部分整体的层次结构。组合使得用户对单个对象和组合对象的使用具有一致性。在组合模式中,通常有两种类型的对象:叶子对象(Leaf):不包含子对象的对象。容器对象(Composite):包含叶子对象或其他容器对象。注意重点是这个一致性,我们通过上层类型约束,要求叶子对象和容器对象都需要实现我们指定的接口,然后我们就可以放心的进行组合了。最终我们可以发现,组合这些对象,得到的是一种树形结构,因此组合模式也被称为树枝...
前言命令模式(Command Pattern)是一种行为设计模式,它将一个请求或简单操作封装成一个对象,从而使你可以使用不同的请求、队列或日志请求来参数化其他对象。同时支持可撤销的操作。命令模式主要包含以下几个角色:命令(Command)接口 - 声明执行操作的接口。此接口通常定义了一个执行具体命令的方法。具体命令(Concrete Command) - Command 接口的实现对象,它定义了绑定在接收者上的动作之间的关联。当命令的 execute() 方法被调用时,将会把动作转发给接收者去执行。客户(Client) - 创建一个具体命令对象并设置其接收者。有时客户负责创建并设置命令对...
前言发布订阅模式使用上也非常广泛,比如vue的响应式数据就用到了发布订阅模式,前端的原生事件也是发布订阅模式,这种模式主要解决的就是异步的问题,用于代替回调函数,且使得两个对象是松耦合的联系再一起。发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。在 JavaScript 开发中,我们一般用事件模型 来替代传统的发布—订阅模式。发布订阅实现var event = { eventMap: new Map(), on(eventName, callback) { let eventL...
迭代器模式是一种行为设计模式,它允许您遍历集合中的元素,而无需暴露其底层表示(列表、堆栈、树等)。简单点来说就是自己去实现一个for循环。var each = function( ary, callback ){ for ( var i = 0, l = ary.length; i < l; i++ ){ callback.call( ary[i], i, ary[ i ] ); // 把下标和元素当作参数传给 callback 函数 } }; each( [ 1, 2, 3 ], function( i, n ){ alert ( [ i, n ]...
前言代理模式应用非常广泛,比如es6的proxy,接口的反代,vue的响应式数据也用到了代理模式,由于用的很平常,导致对它的认知很模糊。代理模式是一种结构型设计模式,它允许你提供对象的替代品或占位符。代理控制着对原始对象的访问,并允许在将请求传递给对象前后执行一些操作。举个例子,比如前端常用的一个性能优化的方式:事件委托(事件代理)我们给子元素的父元素绑定click事件,通过冒泡的方式统一在父元素处理事件逻辑,这样减少了事件的绑定。这种方式其实又有点像是:中介者模式中介者模式是一种行为设计模式,它通过引入一个中介对象来管理一组对象之间的交互。中介者模式可以将对象之间的复杂多对多关系简化为...
前言策略模式常常用于解耦代码中的多种方案实现,比如表单校验,我们将校验的规则解耦出来,封装成一个个策略,然后在需要使用的dom上,使用这些策略,从而省去在具体的校验函数中一大堆if else的判断,当然也许不是if else。再举个例子,比如代码的压缩方式,我们可以使用gzip,或者br的方式,或者其他,他们都是为了达到压缩目的,又是多种方案可选的形式。使用策略模式计算奖金很多公司的年终奖是根据员工的工资基数和年底绩效情况来发放的。例如,绩效为 S 的人年终奖有 4 倍工资,绩效为 A 的人年终奖有 3 倍工资,而绩效为 B 的人年终奖是 2 倍工资。假设财务部要求我们提供一段代码,来方...
前言单例模式在强类型语言中常常是使用一个类来实现,哪怕在ts中,常见的单例示例也是使用class来实现,但是事实上在js中,不一定非得要用类来实现,我们不应该将实现方式看的太死板,使用class也只是手段的一种,在js中我们有很多种方式达到相同的效果。单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。拙劣的模仿在强类型语言中,会给类一个getInstance的方法用于获取实例对象,在js中我们也可以这么写:function User(name) { this.name = name; this.instance = null; } User.prototy...
前言一直很难去真正理解JavaScript的多态到底是什么,从各种教程上对多态的解释都是:同一操作作用于不同的对象上面,可以产生不同的解释和不同的执行结果。举例说明:移动这个功能,作用在汽车上,他能实现100公里每小时,如果作用在自行车上,只有20公里每小时,一个加油,一个用脚蹬,实现方式和结果完全不同。但是这也没能解释js中的多态到底是什么?如果从代码上去看的话,可以如下:/** 汽车 */ function Car() {} /** 自行车 */ function Bicycle() {} /** 移动 */ function move(obj) { if (obj inst...
探讨nuxt3采用了Hydration水合这样一个概念,用于处理服务端生成静态html与客户端js脚本的结合,实现一个可动态交互的页面应用,这个过程被称之为水合。水合的过程可能会相对复杂一些,需要考虑到脚本加载、DOM的匹配、交互的激活(事件)、状态管理等等。其中状态的管理,我目前使用的时候,发现它并不是理想中的那种状态。理想中可能是:服务端渲染时发起了一个api请求,获得了用户的数据,此时我们会将其存储到状态管理中,比如pinia之类的,然后客户端获取到服务端返回的数据,然后自己将pinia的数据恢复到内存中,如果使用了持久化存储,应该会自己将其存储到local之中。但是,实际情况是,...
前言配置站点地图 sitemap.xml和robots.txt有利于SEO的快速抓取,对于一些站点工具来讲,站点地图可以帮助快速分析整个站点的内容,robots则更好的控制爬虫的抓取。准备工作安装nuxt的seo整合模块:@nuxtjs/seopnpm i @nuxtjs/seo -Dnuxt.config.ts中加入该模块:export default defineNuxtConfig({ modules: ['@nuxtjs/seo'] })配置站点链接事实上我们还应该配置一下站点的链接,站点链接用于在站点地图中拼接出完整的访问链接,但是在开发模式下站点地图的...
前言从写博客主题至今,对于代码高亮的行号,一直是比较头疼的,以前初学前端的时候,有过一些尝试,比如利用代码里面的行高是固定的,然后创建一个伪元素,伪元素的内容就是一行一个数字,然后通过脚本生成一个9999行的内容,然后伪元素父容器再做个内容溢出剪切,实现了一个代码行号的处理。最近博客主题评论下有人想要增加代码行号,我记得之前掘金是没有代码行号的,最近打开发现有了,于是就想办法给研究出来了。于是就有了这篇教程,方法也很简单。其实这个行号甚至与highlight.js关系不大,只是作为一个关联关系,可以用其他的同类竞品替代。教程[hide]在处理行号之前,我们需要保证代码已经被highlig...
前言该文章解决了以下问题:我有一台小主机,但是它只有一个网口,于是我安装了pve来进行服务器管理,但是我又想搞点魔法,因为软件层的代理,有时候无法满足一些偏门的网络请求,哪怕设置了全局啥的。于是我们就得安装OpenWrt来搞点魔法,并通过旁路由的形式共享同一个网口。但是魔法这个东西我们不想影响整个局域网内的设备,因为我们的实际需求,可能是个别设备,甚至只是个别时段才需要用到魔法,为此本教程就是来解决这些问题的。教程[hide]定制自己的固件我们可以自己去OpenWrt的官网实现自定义定制编译,也可以使用第三方的。官网:openwrt进去后输入x86,找到Generic x86/64选项。...
前言一般情况下确实用不到这种极端处理方案,因为有名的插件依赖,基本上能碰到的bug情况是非常少见的。这篇文章解决的问题是:将 node_modules 中的模块自己修改后,又不想影响全局引入方式,或者说不方便去修改该模块的引入的时候使用的。教程中使用的是pnpm方式,如果你使用npm或者yarn,原理是一样的,可以参考完再自己去看对应的命令使用方式,大差不差的。[hide]教程假设我们已经将模块自己改好并打包好了,此时我们一般会得到一个dist目录,这个是模块打包后的产物,假设这个模块在node_modules中的文件夹夹名字是test,那么你就需要将dist放置在自己新创建的test目...
前言更新系统需要下载很多相关依赖,如果在国内,我建议是先换源,换成国内源再更新,如果是vps主机,应该就不用考虑这个事情了,不知道换源可以看我之前的文章。教程首先更新软件包索引:sudo apt update然后升级已安装的软件包:sudo apt upgrade如果你想更加果断,比如你是新装的系统,不需要考虑包之前的依赖啥的,可以直接全面升级:sudo apt full-upgrade这种方式也适合有时候的内核更新。完事后我们清理下无用的安装包:sudo apt autoremove一般情况下不需要重启系统,如果你不放心可以重启一下:reboot查看系统版本完事后重新连接ssh,我们可...
前言终于有机会上生产环境实战了,特意写上一篇文章方便以后使用。首先我们在本地开发的时候确实需要配置Nestjs的CORS,因为前端在开发阶段使用的api往往是我们本地起的服务,通过ip+端口的形式访问我们的后端,在浏览器中就会触发安全限制,报CORS跨域。为此在开发阶段我们就需要配置它。但是当我们上了生成环境后,就略有不同了。首先node本身没法去映射域名,所以我们需要通过Nginx或者其他做一个反向代理,想域名映射到本地的node服务上去,但是这就产生了问题,就是前端实际上请求的是nginx,nginx再跟nestjs沟通,但是nginx本身就是后端的,所以它不存在跨域的问题,反倒是前...
前言最近重置debian12后,ssh连接发现报了错:Error: Handshake failed: no matching host key format于是我用运营商的vnc去查看ssh的配置文件,发现已经将PermitRootLogin yes开启了。就很奇怪,问了下ai发现是协议问题。教程输入:sudo -i先提权,再输入:nano /etc/ssh/sshd_config在配置文件末尾添加以下内容:HostKeyAlgorithms ssh-rsa然后CTRL + O保存,CTRL + X退出编辑。重启下ssh服务:service ssh restart此时再用root账号连...
前言当我在使用prisma配合MongoDB来创建数据的时候,发现后端报错了,提示:Prisma needs to perform transactions, which requires your MongoDB server to be run as a replica set.https://pris.ly/d/mongodb-replica-set主要原因是因为prisma在创建数据的时候需要使用到事务,但是MongoDB使用事务就需要副本集,副本集类似于一份数据存多份的处理方案。折腾了好久才搞定,特此分享。教程修改配置首先我们需要找到MongoDB的安装位置,在它的bin目录下...
前言调用prisma的初始化命令并指定链接的数据库类型为MongoDB后:npx prisma init --datasource-provider mongodb它会自己去下载一些相关的依赖,但是此时报错了:Downloading Prisma engines for Node-API for windows [ ] 0%Error: request to https://binaries.prisma.sh/all_commits/efd2449663b3d73d637ea1fd226bafbcf45b3102/windows/query_eng...
前言需要注意的是,我们的pinia仓库持久化操作只有在客户端渲染时操作才能触发,比如当第一次访问页面时,你可能直接在setup中给仓库存储内容,这是无效的,我们需要保证在客户端渲染时触发才行,比较好的办法就是在onMounted生命钩子中触发。究其原因就是服务端是没法操作local、cookie这些浏览器配置,而在setup中的代码,是会在服务端也运行的,这就可能导致部分代码到了客户端不再运行。教程安装依赖pnpm i @pinia/nuxt @pinia-plugin-persistedstate/nuxt安装成功后在nuxt.config.ts中配置模块:// nuxt.config...
前言Nuxt3的环境变量配置有点和平时vue项目的不同,它为了考虑服务端渲染和客户端渲染两种情况,以及安全相关的考量,它的环境变量用起来会有点繁琐。在官方的预设中,你可以使用.env这个文件名的环境变量文件,但是它只会在开发中使用,并不会在构建生产的时候使用,所以我的建议就是放弃使用.env文件名,转而使用指定具体文件的形式。但是即便我们指定了环境变量文件,它也不会出现在Nuxt提供的useRuntimeConfig配置composable中,考虑到安全,我们在服务器渲染时可能有部分环境变量不能出现在客户端中,以防有人恶意获取从而产生破坏。所以nuxt并没有一股脑的把环境变量挂载上去,而...
前言实现了文件上传,自然要实现文件下载,经过我的实践总结出两个下载本地文件的方式:第一种是通过api请求,以返回文件流的形式将本地文件返给前端,前端自己接受到文件流后自己把Blob转一下;这种方式的话可以监听文件是否下载完成,完后下载完后删除本地磁盘上的文件。第二种是后端将文件存储在本地磁盘上,创建一个访客也能访问的下载目录,将文件丢到这里,再放开这个目录供访客下载,后端只需要在api返回下载地址即可。这种方式对于用户来说会更加方便,因为可以使用不同的下载工具下载文件。前端也省事,直接创建a链接元素,触发点击就是使用浏览器下载文件了。教程[hide]文件流下载我就不详细写服务了,直接在控...
前言当我们在服务器去拉取git仓库代码使用时候,比如生产环境中,我们去拉取代码,肯定要保证拉取成功,但是git如果本地文件有变化,就会导致拉取失败,一般情况下我们都是通过添加脚本的形式实现生产环境自动拉取,从而节省人力,如果因为本地文件与仓库不同就拉取失败,这就显然并不健壮。而且生产环境基本上都是可以让远程仓库直接覆盖本地文件的,一切以远程仓库文件为准,所以我们需要实现让远程仓库强制覆盖本地。教程假如我希望让远程的develop分支覆盖本地,就先fetch请求远程仓库对应分支的最新资源git fetch origin develop完毕后我们进行覆盖git reset --hard or...
最近评论