【IIS】设置URL重定向 - 狼窝窝 - 博客园

mikel阅读(321)

来源: 【IIS】设置URL重定向 – 狼窝窝 – 博客园

名字解释:

URL转发分为隐含转发和非隐含转发,隐含转发就是指当前域名转发后,仍然显示当前域名,而非隐含转发者指当前域名转发后,显示被转发的地址。

 

前提:

你有一个A网站:地址是:192.168.1.223:8700

B网站:地址是 www.baidu.com

现在要在输入A网站地址后,直接跳转到B网站中【旧版域名转新版域名类似的需求】

 

具体操作:

1、在IIS上安装ARR,下载地址(http://www.iis.net/downloads/microsoft/application-request-routing)

2、完成后打开,Microsoft Web Platform Installer

 

 

3、搜索arr关键字,安装应用程序请求路由

 

4、搜索url关键字,安装url重写工具

 

5、重启服务器,才能在iis目录下看到新安装的ARR

 

6、打开ARR,在右侧功能菜单中点击   Server Proxy Settings

 

7、勾选 Enable proxy,然后点击应用

 

8、打开你要设置URL重写的网站目录,此时就能看到一个URL重写的功能

 

9、双击打开,添加规则

此时可以在当前站点增加Index.html页面,里面说明即将要做的事情。

然后规则名随便起,模式输入:^(./*)  代表匹配当前网站192.168.1.223:8700,跳转规则为输入  192.168.1.223:8700/ss  则默认都跳转至新页面

下面的URL重定向页面直接写你的目标地址即可

 

 

 

PS:如果想在输入 192.168.1.223:8700的地址时就立刻跳转到百度,则需要设置HTTP重定向

 

 

另附:

IIS配置Url重写实现http自动跳转https的重定向方法(100%解决)

 

 

 

 

 

参考:

https://blog.51cto.com/cold2076goddess/1542583

https://blog.csdn.net/kelly921011/article/details/87889062    隐含转发

https://my.oschina.net/tanyixiu/blog/123832      隐含转发

https://blog.csdn.net/kelly921011/article/details/87889062   隐含转发

解决客户端和服务器不支持一般SSL协议版本或加密套件问题_客户端和服务器不支持常用的ssl协议版本或密码套件_Huang-Bo的博客-CSDN博客

mikel阅读(352)

来源: 解决客户端和服务器不支持一般SSL协议版本或加密套件问题_客户端和服务器不支持常用的ssl协议版本或密码套件_Huang-Bo的博客-CSDN博客

错误信息
详细报错信息如下图

错误原因
这种错误通常表示客户端和服务器之间存在协议版本或加密套件不匹配的情况。在SSL(Secure Socket Layer)连接过程中,客户端和服务器需要协商一种相同的加密协议版本和加密套件,以确保数据的安全传输。
具体可能出现的原因包括:
1.协议版本不兼容:客户端和服务器可能支持不同版本的 SSL 协议,导致协议版本不匹配。

2.加密套件不匹配:客户端和服务器可能支持不同的加密套件,导致加密套件不匹配。例如,如果客户端只支持使用 AES 加密算法,而服务器只支持使用 RC4 加密算法,则它们无法协商一种相同的加密套件。

3.协议配置不正确:客户端和服务器的 SSL 协议配置可能不正确,例如使用不安全的协议版本或加密套件,导致连接失败。

解决方法
适用于Windows server 2008 R2 操作系统
1.配置支持高版本TLS协议,去到iis站点所在服务器修改注册表,配置路径如下:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols
在该层级下新建两个项,名称分别为TLS1.1和TLS1.2

2.然后在TLS1.1和TLS1.2项中再分别新增两个项Client和Server

3.然后分别再Client和Server项中新增两个(DWORD 32位值) TLS1.1和TLS1.2都要加
key:值
DisabledByDefault:0
Enabled: 1

client项

server项

4.最后重启服务器,再去到浏览器访问看效果

5.检测web站点支持的ssl协议版本号
https://www.ssllabs.com/ssltest/index.html
————————————————
版权声明:本文为CSDN博主「Huang-Bo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Habo_/article/details/129203156

领域驱动模型DDD(一)——服务拆分策略 - 键盘三个键 - 博客园

mikel阅读(324)

来源: 领域驱动模型DDD(一)——服务拆分策略 – 键盘三个键 – 博客园

前言

领域驱动模型设计在业界也喊了几年口号了,但是对于很多“务实”的程序员来说,纸上谈“术”远比敲代码难得太多太多。本人能力有限,在拜读相关作品时既要隐忍书中晦涩难懂的专业名词,又要去迎合西方大牛在撰写的过程中融入的西式故事。我想总会有一部分水平和我类似的码农们,需要一份对系统阐述DDD小白化的文本。因此,本人便自不量力地结合一些简单的项目经验,将领域驱动模型设计思想从理解到落地的实施和总结分享给诸位。当然,如果是某些行业先锋不幸看到本人稚嫩的文字时,就当作是马戏团中的小丑,一笑了之翻页便可。

思维的入门

在学习架构思想的初期,特别时面对架构模型时(例如六边形架构、领域服务拆分),我总会不自然地在对号入座,思考在模型中的这一块放到代码实现上是Controller层还是Dao层,是采用消息中间件还是NoSQL缓存。这种自动联想的“被动技能”在学习微服务设计架构思想的过程中是致命的,过于专注业务的技术实现而脱离架构思想本身的大局观,就容易陷入用“具体”无法概括“抽象”的处境。

对此,让我们先忘了平日在开发中使用的各种被分类到细致入微的技术,带着一种阅读“无用”文学而非可以模仿实操的工具书的心态一起来对领域驱动设计做一个基础性的理解。

1 常用的服务拆分方法

1.1 根据业务能力进行服务拆分

创建微服务架构的策略之一就是采用业务能力进行服务拆分,这也是目前市面上大部分产品设计初期采用的方式。主要原因是这种方法对于架构师来说是比较容易实施的,就好像在做一个分类游戏,关于用户的注册登录以及信息管理可以划分为一个业务,关于文章的发布下架以及内容更迭可以划分为一个业务。

这样的分类手段核心是以业务活动进行划分,也保证了大部分面向对象的程序员在代码实现时可以更快地、更明确地创建实体类,从而开辟出一个个针对不同业务功能的微服务。

倘若我们以程序员盘踞的技术论坛/博客为例,那么它们必须要实现最基础的三大业务:1、用户的注册登录以及用户对个人信息的操作;2、用户可以发布/修改/删除自己的文章;3、网站的后台管理员可以对前面两者进行更高权限的操作。至于更多的用户评论、用户私聊、vip充值等一些功能则是拓展,毕竟没有它们也不会影响到整个网站的正常运作,因此暂不加入讨论。

所以根据上述最基础的三大业务,如果要进行微服务架构设计(当然现实中不会有为了如此简陋的网站采用微服务,不然会被从业的程序员背地挖苦痛骂),我们可以画出相应的映射图【图1-1】:

采用业务能力进行拆分固然方便了架构师和程序员,在应对一般的企业项目时,这种方式是非常稳妥的方案,架构中每个划分出的服务内部后期可以根随功能的需求增加而逐渐迭代(例如,我现在需要文章发布时可以附带图片,那么可以在实现文章业务的服务中添加相关的接口与具体实现代码),但是整体的项目架构是保持不变的。

话虽如此,但读者们要知道上面仅仅是为了实现技术博客网站最基本业务而定义的“初代”架构。一种情况是随着整个技术博客网站的日益庞大,为了迎合用户的需要,我们不得不扩展网站的功能性,例如增添用户对文章点赞/收藏/留言,后台对文章内容是否健康的审核等等,这时候初代被划分好的服务内部就会日益“庞大”,需要我们重新操刀对其进行分解切割。

另外一种情况是由于用户量的提升,致使服务之间的远程调用、进程间的通信次数骤增而导致请求响应效率逐步低下,例如拥有庞大数量的读者用户在访问文章时不仅要通过文章服务获取文章内容,还要通过文章的作者每次调用用户服务来获取作者个人信息简介(在没有缓存机制,每个服务根据业务主体分割明确的假设情况),我们又得考虑把一些服务组合在一起:

例如当我们现在常用的注册/登录手段——利用第三方服务进行短信验证,如果只是为了实现用户注册/登录功能,完全可以并入到用户的服务中【图1-2】:

一旦不单用户登录/注册情况用到短信验证,例如要充值时候也要用到短信验证支付,那么就得把它独立出来【图1-3】:

上面的问题正是以业务进行服务拆分时难以避免的,因为业务必然是不断发展的(参考市面上众多臃肿的软件),被繁杂的业务牵着鼻子走的架构模式必然会陷入到不停拆分或重组的境地,那么服务内部以及服务之间的关系也将逐步模糊紊乱。

1.2 根据子域进行服务拆分

即使这是一段很枯燥的历史,但为了感谢曾在这个领域躬耕的技术先驱们我还是要带上这段文字:Eric Evans在他的经典著作中(Addison-Wesley Professional)提出的领域驱动设计是构建复杂软件的方法论,这些软件通常都是以面向对象和领域模型为核心。

既然是方法论,它提供的是“怎么办”的理论体系。类比蛋炒韭菜,我所能提供的是做这道菜需要什么工具和佐料,放油放蛋放盐放韭菜的先后顺序和比例,至于真正做起来火候的大小,炒菜的姿势,蛋菜的克量等都是视情况而定,并没有固定的要求。这又回到我在“思维入门”中提到的,不要用机械的“具体”去反推“抽象”理论,因为炒菜的姿势最多能影响的是菜的口味,并非是完成这道菜的必要条件。

下面让我们来理解DDD中重要的两个概念:子域和界限上下文。我先以好理解的方式在各位脑海中勾勒出这两者的基本认识,然后各位再去看专业解释会好接受的多。

如果把一个项目业务比作一个国家整体,而子域相当于国家内部的各个省份,这些省份细致地划分了国家每个地域面积大小和居住人群,而所有省份的聚合又构成了整个国家。作为限界上下文,其英文为bounded context,可以直译成“有界的环境”,那么套入前文各位可能举一反三理解成“省界”。但事实并非如此,以“省份”类比子域的话,省界并非是限制人口流动的主要原因,限制人流的本质在于一个省份有一个省份的风土人情和文化语言,例如广东省用粤语交流,福建省用闽南语交流,这些语言在省份内部是大家达成共识都能理解的,但跑到广东说福建话只会让本地人摸不着头脑。

因此,每个省份(子域)之间产生的交流障碍归根于它们各自内部通用语言环境不同(限界上下文)。这个举例或许不符合社会学对于人口流动的分析,但拿来解释子域和限界上下文还是很贴切的。

那么让我们引入教科书对二者的解释来巩固诸位对它们的记忆:子域是领域的一部分,领域是DDD中用来描述应用程序问题域的一个术语。识别子域的方法和识别业务能力一样:分析业务并识别业务的不同专业领域,分析产生的子域定义结果也会和识别业务能力得到的结果非常相近。DDD把领域设计模型的边界成为界限上下文,当使用微服务架构时,每一个界限上下文对应一个或则一组服务,我们可以通过DDD方式定义子域,并把子域对应为每一个服务【图1-4】。

1.3 拆分单体应用的难点

1.网络延时

网络延时是分布式系统中一直存在的问题。不论是以业务进行拆分还是子域进行拆分,对服务不断细化分解会导致各个服务之间的大量往返调用。即使可以通过批量处理API在一次往返中获取多个对象,从而减少延时。但是在其他情况下,解决方案是把多个服务整合到一起,用变成语言中的函数调用替换昂贵的进程通信。

2.同步进程间通信导致可用性降低

举一个最简单的例子,当我们在某东下单一件商品时创建了订单,创建订单的过程中需要获取商品的详细信息和购买者的详细信息,而这其中有一个服务出现了不可用的状态就会导致整个业务创建失败,这种同步进程通信带来的可用性降低让我们不得不折中采用异步消息进行处理。

3.服务之间维持数据的一致性

当我们对服务进行拆分后,服务之间如何保持数据一致性成为重点和难点。还是以某东为例,在活动期间大量用户可能在同一刻参与了秒杀活动,而对于仓存服务与商品服务之间如何保证它们在数量的一致性(比如前台有100个用户下单,那么对于商品来说只需要在原有的数量上减去100然后返回给前端页面作为商品信息的一部分及时展示给用户还有多少存货便可,但是实际上真正需要扣减的应该发生在仓库服务中,因为仓库服务内存储的才是实际库存),怎么让一波狂欢后实际库存与前端保持一致是业务中必须攻克的难题。

4.上帝类阻碍了服务的拆分

分解的一部分障碍就是所谓的上帝类,即全局类或则是“公用”类。上帝类通常为应用程序不同方面实现业务逻辑。

以美团外卖业务举例,一个不经思考设计的订单类中会将以下所有信息属性直接构建成一个类:商家信息属性(商家名称、商家地址等)、用户信息属性(账户、昵称、地址等)、外卖商品属性(外卖商品名称、价格、配料等)、配送方属性(配送员身份、配送员电话号码、配送起始时间、配送截止时间等)。不过这些属性涉及了不同服务中的应用程序,导致了商品系统中必然存在的订单所包含的信息变得特别庞大,并且与其他服务之间因为共同的属性保持着“暧昧”的联系。

一种解决方法是在数据库中创立一个公用的订单数据库,处理订单的所有服务使用此数据库,但这就出现了“紧耦合”的情况。

对此应用DDD将每个服务视为“孤岛”般的子域(尽量不与其他服务发生在属性的上纠葛,形成一座具有特色便于识别的“孤岛”)。所以让我们看看自己手机上美团APP中客户订单,然后再看看拿到外卖时钉在外卖上的商家收到的订单,幸运的话再看看外卖小哥送外卖时接收的订单,它们所包含的信息内容和信息数量绝对是不同。

这代表着在商家子域、用户子域、配送子域中我们根据子域的不同定义了不同侧重点的“订单”,而不是一股脑地都塞进全局订单类里让不同服务进行共享。也正是不同侧重点的“订单”只有在自己子域中才是“有效的”,“能被读懂的”(总不可能让商家去看外卖小哥的订单信息,用户去看商家的订单信息),子域便有了与之对应的界限上下文。

结语

最后我想很多人一直疑惑DDD与微服务到底有什么区别or联系?若用我浅薄的认识来解释那便是:DDD是一个抽象的设计理念,而现今微服务在开发领域的生态技术十分契合地为DDD架构思想的具象化提供了可行性。但诚如各位在文中所见,服务的分割又不仅仅只有DDD这一种方案。DDD给开发者带来的永远不是某种可以更快捷地开发“工具”,甚至夸大一点来说它依赖于技术却超脱技术。或许对于一个狂热的设计者来说,DDD给予他们一个能够决定项目拥有何种生命力与活力的机会,这种犹如“艺术创造”的思维活动便是架构的真正魅力所在。

这一章的基础内容便到此结束,下一章可能会讲一下服务的进程通信或则是Saga管理事务,尽情期待。

本文作者:键盘三个键

本文链接:https://www.cnblogs.com/jianpansangejian/p/16047304.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

删除系统盘大文件“hiberfil.sys”的方法 - 知乎

mikel阅读(564)

来源: 删除系统盘大文件“hiberfil.sys”的方法 – 知乎

删除系统盘大文件“hiberfil.sys”的方法

最近我的电脑系统C盘空间满了,在清理磁盘空间时在系统盘下有两个超G的隐藏文件,一个是pagefile.sys,2G左右,一个是hiberfil.sys,6G左右,前面一个文件虚拟内存。

而“hiberfil.sys”是系统休眠文件,其大小和物理内存一样大,它可以删除掉,但却不能手动删除掉,只要在“控制面板”中打开“电源选项”,之后在电源管理对话框的“休眠”标签下,去掉“启用休眠”前的勾,重新启动计算机后,休眠文件就会自动删除。

更直接和简便的方法如下:

1. 如果使用了休眠功能,那么打开系统盘就会有一个很大的hiberfil.sys文件,它是将用户正在运行的程序,保存在这里,再启动系统就很快了。如要清理它,可以这样操作:

2. 开始→所有程序→附件→右键命令提示符→以管理员身份运行(否则可能会出错)。

3. 在命令提示符中输入:powercfg -hibernate off 按回车(Enter键)执行命令即可关闭休眠功能。

4. 再去开始菜单的关机选项中查看,休眠菜单已经没有了。

5. 再到系统盘查看,数G大小的hiberfil.sys文件也没有了(如还有可以自行删除)。

6. 如要再次开启休眠功能,可以在命令提示符中输入:powercfg -hibernate on 按回车(Enter键)执行命令即可打开休眠功能(无需重启电脑)。

7. 还可以在控制面板的电源选项中调整启用休眠的等待时间。

进入C:WindowsSystem32 找到cmd.exe 点右键—-以管理员身份运行
在cmd模式下输入命令“powercfg -h off”回车
重新启动计算机,再去看看已经没了!
(不需要关闭账户控制)

“pagefile.sys”是页面交换文件,即虚拟内存文件,这个文件不能删除,不过可以改变其大小和存放位置:文法如下:

1. 右击“我的电脑/属性”,然后在对话框的“高级”标签下单击“性能”下的“设置”按钮,在”性能选项”对话框中切换到“高级”标签下,再单击“虚拟内存”下的“更改”按钮,即可根据需要更改页面文件的大小。

2. 先选中C盘,然后选“无分页文件”,再点“设置”按钮;之后选中要生成该文件的盘符,在下面点选“自定义大小”并输入合适的数值,此数值通常为物理内存的1.5倍,再单击“设置”,最后单击“确定”就可以了。

3. 重新启动电脑,该文件就会存放到其他分区上了。

以下是该pagefile.sys文件的一些简单点的说明.
在一些较新的具有STR功能的主板上安装了xp及更新的操作系统后,在系统区根目录下会有一个 hiberfil.sys 的文件,它的大小和内存容量一样,这是什么文件呢?原来这个就是系统的休眠功能所占用的硬盘空间的文件(Windows 默认休眠功能是处于打开状态的),电脑处于休眠状态时,内存中的所有内容将保存到硬盘,并且电脑会被关闭。电脑在返回打开状态之后,关闭电脑时打开的所有程序和文档将全都还原到桌面。也就是说,当你让电脑进入休眠状态时,Windows 在关闭系统前将所有的内存内容写入hiberfil.sys文件。

而后,当你重新打开电脑,操作系统使用Hiberfil.sys把所有信息放回内存,电脑恢复到关闭前的状态。然而,Windows 在硬盘上留下了hiberfil.sys文件,即使这个文件不再需要了。

Hiberfil.sys文件可能很大,是磁盘碎片整理程序不能整理的特殊系统文件。因此,文件Hiberfil.sys的存在将阻止磁盘碎片整理程序进行彻底的整理操作。

交通部道路运输车辆卫星定位系统部标JTT808、809、796标准大全 - panchanggui - 博客园

mikel阅读(363)

来源: 交通部道路运输车辆卫星定位系统部标JTT808、809、796标准大全 – panchanggui – 博客园

无论是开发GPS设备硬件还是开发应用软件,都要面临一个标准,这个标准就是国家交通部发布的道路运输车辆卫星定位系统部标认证标准,它涵盖了GPS硬件设备参数、功能标准,也包括了设备上传到应用平台的协议标准,同时也包括了平台对平台的互联互传的技术标准。

也就是说凡是根据交通部这个标准开发的应用平台软件,都可以接入不同厂家开发的符合国标的GPS设备发送的上传数据。因为协议是同一的,所以平台也可以将数据转发给各地的省级交通部门的运管中心。

目前国家对需要上路的客车、危险品运输车,简称两客一危,要求必须要安装符合国标的GPS,如果运输承运者没有自己的软件平台,可以使用运管局的客户端软件,并接入到运管中心进行监控,收费对于企业来说也是个负担。现在国家对与GPS终端设备的标准又进行了进一步的扩展,要求必须要加上指纹等身份识别的读卡器,强制性加,费用不低。

平台软件开发商和GPS设备开发商安装标准开发后,需要通过交通部的部标检测和认证,获得部标认证后,这样才可以参加各地的软硬件招标。交通部对平台的功能测试,主要是模拟GPS终端发送标准的协议数据,然后测试是否能正确的接收数据。

GPS应用的开发者必须要了解并掌握这些协议,平台协议主要JT/TB808、809及扩展补充协议,同时协议中对于行车记录仪部分又应用了部颁的GB19056标准,所以这些都要看,JT/T796主要是硬件设备的标准,可以参考。

JTT 808-2011 道路运输车辆卫星定位系统终端通讯协议及数据格式

JTT 796-2011道路运输车辆卫星定位系统平台技术要求

JTT 794-2011北斗完善版-道路运输车辆卫星定位系统北斗兼容车载终端技术规范

JTT 809-2011 道路运输车辆卫星定位系统–平台数据交换

行车记录仪标准GB19056

行车记录仪标准GB19056 硬件参数标准

Vue vs React:你需要知道的一切 - chuckQu - 博客园

mikel阅读(262)

来源: Vue vs React:你需要知道的一切 – chuckQu – 博客园

Vue 和 React 是创建 JavaScript 网络应用程序最常用的两种工具。但我们该如何在两者之间做出选择呢?在本篇 Vue 与 React 的对比中,我们将尝试找出答案。我们将回顾每种工具的优缺点,提供选择使用哪种工具的技巧,并帮助你开始使用。

总览

  1. 什么是Vue?
    • Vue趣事
  2. 什么是React?
    • React趣事
  3. Vue vs React:全面比较
    • React 灵活性
    • Vue 灵活性
    • 使用 React 进行开发
    • 使用 Vue 进行开发
    • React 工具
    • Vue 工具
    • React 性能
    • Vue 性能
    • React 的文档和社区支持
    • Vue 的文档和社区支持
  4. Vue vs React:总结
  5. 受欢迎程度
    • 使用 Vue 和 React 创建的知名应用程序
  6. Vue vs React:何时使用?
  7. 10条FAQ
    1. Vue 和 React 之间的实际区别是什么?
    2. 为什么 Vue 比 React 更快?
    3. 为什么 React 比 Vue 更受欢迎?
    4. Vue 比 React 更好吗?
    5. Vue 比 React 更简单吗?
    6. 如果我们知道 React,我们能学习 Vue 吗(反之亦然)?
    7. 我们应该从 React 转向 Vue 吗?
    8. Vue 比 React 更适合我的职业生涯吗?
    9. Vue 可以与 React 一起使用吗?
    10. 那么,我们应该学习 Vue 还是 React?
  8. 总结

什么是Vue?

Vue 是一个用于构建用户界面的渐进式、可逐步采用的 JavaScript 框架。它由 Evan You 于 2014 年创建,并由一个活跃的开发者社区负责维护。

Vue 设计得非常轻量级、灵活和强大。它建立在一个基于组件的架构上,以组件为中心,可以更轻松地创建动态用户界面。它还有一个强大的双向数据绑定系统,可以让我们轻松地保持数据和用户界面同步。

Vue 的API简单但功能强大,易于上手,而且体积小(约 20KB),非常适合移动应用程序或单页应用程序(SPA)。说 Vue 是一个”渐进式”框架,意味着它不会自动提供一堆我们可能不需要的东西。相反,我们可以从最基本的功能开始构建响应式应用程序,然后随着项目的发展逐步导入更多功能。所有这些都让我们避免了模板代码和尺寸过大的困扰。

Vue趣事

  • Vue 的语法受到 Angular 和 React 的启发,旨在让已经熟悉这些框架的开发人员易于学习。
  • Vue 的名称源自法语动词 “vue”(看)。
  • Vue 的标志是一个抽象的字母 “V”。

什么是React?

React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 于 2013 年创建。它最初用于构建 Facebook 网站,后来成为开发web应用程序最流行的 JavaScript 框架之一。

React 为开发人员提供了一种声明式编程风格,更易于阅读和调试。它还使用虚拟 DOM,速度比传统 DOM 更快,性能更好。

React 基于组件的方法使开发人员能够利用可快速、轻松地组合在一起的可重用组件创建强大的应用程序。这使它成为快速原型开发和应用程序的绝佳选择。

React趣事

  • 全球一些最受欢迎的网站都在使用 React,其中包括 Facebook、Netflix 和 Airbnb。
  • React 非常注重性能,其渲染速度明显快于主要竞争对手 Angular。
  • React 是最流行的前端 JavaScript 库。

Vue vs React:全面比较

现在,我们将进行一次 Vue 与 React 的压力测试,看看它们在整个开发链路中的一些关键方面有哪些优势。这些方面包括以下内容:

  • 灵活性。根据项目需求定制和调整有多容易,既可以使用其核心组件,也可以通过第三方附加组件来实现,而第三方附加组件通常无法获得同等程度的文档和支持。
  • 开发和工具。建立项目和开始编码有多容易。这一点非常重要,因为它将决定我们启动项目的速度,以及新开发人员提高工作效率的速度。
  • 性能。这一点非常重要,因为它决定了应用程序在用户设备上的运行效果。我们不应该低估这一点,因为它意味着愉快的应用体验(用户会不断回访)和令人沮丧的应用体验(用户可能会放弃)之间的差别。
  • 文档和社区支持。这将从根本上决定开发人员在遇到困难时获得帮助的速度,以及找到常见问题解决方案的难易程度。

下面就开始比较吧。

React 灵活性

React 以其灵活性而著称,因为它的核心只是一个UI库。它允许开发人员在编写代码时使用基于组件的编程方法或函数式编程方法。这意味着开发人员可以选择自己最擅长的编码风格,并以此创建功能强大的应用程序。

React 还支持各种库和工具,因此很容易与现有技术和项目集成。例如,React 可以与 Redux 结合使用以进行状态管理,也可以与 Next.js 结合使用以进行服务端渲染

  • 优点:高度可定制和可扩展;支持广泛的库和工具。
  • 缺点:可扩展性主要通过第三方插件实现。

Vue 灵活性

Vue 也提供很大的灵活性,因为我们可以在开始时只使用核心库,然后随着项目的发展逐步采用所需的内容。Vue 也支持基于组件的编程方法或函数式编程方法(包括 JSX),并支持各种库和工具。

但与 React 不同的是,这些扩展大部分都是由同一个团队开发的,因此集成和支持都非常出色。例如,Vue 甚至原生提供了服务端渲染功能。这让我们可以放心地扩展我们的项目,因为我们知道,无论将来我们需要做什么,Vue 都能满足我们的需求。

  • 优点:高度可定制和可扩展,对库和工具提供广泛的原生支持。
  • 缺点:无。

使用 React 进行开发

通过第三方插件,React 还提供路由状态管理,以管理导航流和处理应用程序数据。React 的支柱之一 JSX 可以让开发人员轻松地在 JavaScript 中编写类似 HTML 的语法,从而创建组件并将它们快速组合在一起。

  • 优点:易于设置和上手;有许多第三方插件。
  • 缺点:我们可能经常使用的许多扩展都不是官方的。

使用 Vue 进行开发

Vue 为路由状态管理提供了原生模块,从而实现了导航流和应用程序数据的管理过程。Vue 还提供模板语法,允许开发人员创建易于重用和维护的组件。

尽管如此,由于 Vue 社区不像 React 社区那么庞大,要找到好的第三方解决方案还是有点困难。(不过有一个庞大的中文 Vue 社区,我们稍后再谈)。

  • 优点:易于设置和上手;原生模块可满足大多数开发需求。
  • 缺点:没有那么多第三方插件,维护也不完善。

React 工具

React 很容易设置并开始开发,它自带用于开发和调试的 Visual Studio Code 扩展(由微软开发)。

名为 Create React App 的官方 CLI 允许我们快速设置基本的脚手架,以便立即开始编码。

React 还有一套开发人员工具(目前处于测试阶段),用于检查 React 组件、编辑props和状态以及发现性能问题。

  • 优点:用于调试和检查组件的强大工具。
  • 缺点:CLI 功能有限,性能不佳。

Vue 工具

Vue 也很容易设置和开始开发,它也有自己的 Visual Studio Code 扩展、用于快速开发 SPA 的 CLI(比 React 的 CLI 功能更全面、更强大)以及自己的插件系统

此外还有 Vue Devtools,一个用于调试 Vue 应用程序的官方浏览器 devtools 扩展。

此外,Vite 是用于现代web开发的下一代构建工具,具有极快的冷启动和增量编译时间。它是 Vue 团队的一个官方项目,因此能与 Vue 生态系统无缝集成,并提供一些高级功能,如热模块替换和tree-shaking。

  • 优点:用于调试和检查组件的强大工具,以及用于快速开发的 Vite。
  • 缺点:无。

React 性能

React 的速度相当快,因为它的设计目的只有一个而且做得很好:渲染用户界面。因此,无需太多额外工作,React 的性能就会非常出色;当然,还有进一步优化性能的具体指导原则

React 支持服务端渲染,这有助于进一步提高web应用程序的性能,尤其是在移动设备和较慢网络连接上。

  • 优点:开箱即用,性能稳定;可根据特定指南进行优化;支持服务端渲染。
  • 缺点:速度不如 Vue 快。

Vue 性能

React 在性能方面非常出色,而 Vue 甚至更快。它的虚拟 DOM 可以确保在数据发生变化时只对必要的元素进行重新渲染,因此它的性能和效率都很高。

Vue 可以比 React 做得更多,但性能仍然优于 React,这充分证明了 Vue 创建者 Evan You 的软件工程技能和强大的设计原则。👏

Vue 还原生支持服务端渲染,因此可以进一步提高性能。

  • 优点:开箱即用,性能非常快;可根据特定指南进行优化;支持服务端渲染。
  • 缺点:无。

React 的文档和社区支持

React 拥有详尽的文档和非常活跃的社区。以下是一些最活跃的社区:

Vue 的文档和社区支持

诚然,Vue 社区比 React 社区小,但仍有许多爱好者:

Vue 的文档一直备受赞誉,可能是此类项目中最好的文档。它非常清晰、简洁、易懂,而且布局精美。(这也是我成为 Vue 开发人员的一个关键因素)。

Vue vs React:总结

经过全面比较,我们可以得出这样的结论:React 和 Vue 都是开发现代web应用的绝佳选择,它们提供了大量的灵活性和强大的工具来完成工作。

不过,Vue 在性能、灵活性和文档方面更胜一筹,而 React 则在采用率、第三方工具和社区支持方面更胜一筹。

React Vue
灵活性 高(但主要通过第三方插件) 高(主要是原生扩展)
开发 容易上手,有很多第三方插件。 容易上手,有很多原生模块,但第三方插件不多。
工具 工具功能强大,但性能不佳。 工具功能强大,性能卓越。
性能 很好,可以进一步优化。 非常好,可以进一步优化。
文档和社区支持 详尽的文档和一个活跃的大型社区。 出色的文档和一个较小但活跃的社区。

受欢迎程度

就受欢迎程度而言,React 是迄今为止这两种框架中最受欢迎的,而 Vue 则落后于 Angular(本文不涉及 Angular)。

React 自 2013 年诞生以来,拥有一个庞大的开发者社区,他们不断使用并为该平台做出贡献。它还得到了 Meta(Facebook)的支持,并被用于创建一些世界上最流行的应用程序。

另一方面,Vue 比 React 更年轻,有时被描述为 Angular 和 React 的混合体。Vue 诞生于 2014 年,由于其易用性和对开发人员友好的特性,从那时起,Vue 就受到了越来越多的关注。Vue 还被用于创建流行的应用程序,这将在下一节中介绍。

使用 Vue 和 React 创建的知名应用程序

React 已被用于创建一些世界上最流行的网站和移动应用程序。其中包括 Facebook、Instagram、Airbnb、Dropbox 和 Twitter。

Vue 也被用于创建一些世界上最流行的应用程序。其中包括 9GAG、Alibaba、Xiaomi、GitLab 和 Wizz Air。

以下是一些有用的、非官方的 Vue 和 React 项目展示列表:

Vue vs React:何时使用?

好吧,我们在开始这一部分之前就知道没有”正确”答案,好吗?

  • 对于需要轻量级灵活框架的项目来说,Vue 是一个不错的选择。对于需要大量交互性的项目来说,Vue 也是不错的选择。
  • 对于需要高度可扩展性和可维护性的项目来说,React 是一个不错的选择。它也非常适合需要大量定制的项目。

以上就是在 Vue 和 React 之间做出选择的技术原因。不过,在决定使用哪种技术时,还有一些非技术性的原因(可以这么说),比如支持、社区甚至偏见。接下来,我们将仔细分析其中的一些原因。

10条FAQ

在本节中,我们将介绍有关 Vue 与 React 的十个实用注意事项。

Vue 和 React 之间的实际区别是什么?

Vue 和 React 的主要区别在于,React 是一个用于构建用户界面的 JavaScript 库,而 Vue 则是一个用于构建 Web 应用程序的 JavaScript/TypeScript 渐进式框架。”渐进”意味着其功能和范围可以随着项目的增长而轻松扩展。

除此之外,React 和 Vue 都采用基于组件的方法,允许开发人员将复杂的UI分解成较小的组件,以便在不同的项目中重用。Vue 和 React 的性能都很高,当然比 Angular 更强。

为什么 Vue 比 React 更快?

首先要说的是,React(它只是一个UI库)已经相当快了。然而,Vue 一般来说比 React 更快,因为 Vue 团队非常注重使其具有高性能和轻量级。考虑到我们可以用 Vue 做更多的事情,这已经是一项了不起的成就了。

Vue 之所以更快,还因为它采用了虚拟 DOM 实现,只在数据发生变化时才更新 DOM,而不是每次渲染页面时都更新。

为什么 React 比 Vue 更受欢迎?

至少在西方世界,React 比 Vue 更受欢迎。React 出现的时间更长,熟悉它的开发者社区也更大。

此外,React 是由 Facebook 创建的,这也是吸引许多开发人员的一个因素。相比之下,Vue 背后并没有大的技术公司(这取决于你的观点,也许是坏事,也许不是)。

尽管如此,事实上,在包括中国在内的一些亚洲国家,Vue 比其他任何框架都更受欢迎!

image.png

Vue 比 React 更好吗?

在回答这个问题时,我们不可能不引起网络开发者社区的关注,因此,我们可以妥协地说,React 和 Vue 都是很棒的工具。

React 因其简单性和庞大的社区而成为许多开发人员的首选,而 Vue 则提供了更多的内置功能,在某些用例中比 React 性能更好。

最后的答案可以归结为以下两点:

  • 如果我们了解 Vue,或者对 React 没有什么经验,那么 Vue 会更好
  • 如果我们了解 React,但没有使用过 Vue,那么 React 会更好(但 Vue 仍然优于 React)。

Vue 比 React 更简单吗?

是的。Vue 不仅比 React 更容易学习,而且因为 React 基本上是一个(非常好的)UI 库,而 Vue 实际上是一个框架,所以我们可以用它做更多的事情。

因此,Vue 的”性价比”(可以这么说)–基于你所花的学习时间和你之后能做的事情–是相当高的。

如果我们知道 React,我们能学习 Vue 吗(反之亦然)?

是的,我们可以。虽然这两种技术的开发方法不同,但基本原理是相同的。

无论学习 React 还是 Vue,我们都需要学习一种新的语言/扩展–学习 Vue 时需要学习 TypeScript(为了获得更好的开发体验),学习 React 时需要学习 JSX(出于同样的原因)。尽管存在诸多不同,但这两种框架都使用组件,并具有相似的 API,这使得它们之间的切换更加容易。

我们应该从 React 转向 Vue 吗?

如果我们的团队在使用其中任何一种产品时都已经非常出色,并且取得了丰硕成果,那么就坚持使用它。此外,如果担心第三方扩展和社区支持,那么使用 React 可能会更好。

现在,如果我们尚未启动项目,正在寻找更简单、更灵活的方法,那么 Vue 可能是更好的选择,因为 Vue 提供了更多开箱即用的功能,而且一般来说比 React 更快。

寻找具有 Vue 专业知识的开发人员比较困难,但教授 JavaScript 开发人员如何使用 Vue 则比较容易。

Vue 比 React 更适合我的职业生涯吗?

这要看情况。如果你正在寻找更多的工作机会,那就不一定了。毕竟,React 仍然更受欢迎,甚至可以说是标准(至少在西方)。而在包括中国在内的亚洲许多地方,情况恰恰相反。

如果你想专门从事 JavaScript 开发,那么这两个选项都是不错的选择,因为 Vue 的市场份额仍在不断扩大,尽管没有以前那么快。

Vue 可以与 React 一起使用吗?

不,不要这样做。Vue 和 React 是完全不同的工具,彼此不兼容。

那么,我们应该学习 Vue 还是 React?

还是要看情况。比方说,我们需要这样一个框架:

  • 开箱即能做很多事情
  • 可以通过官方插件进一步扩展,这些插件将遵循与核心软件包相同的实践和指导原则
  • 如果需要,可以与 TypeScript 一起使用
  • 易于学习
  • 在亚洲非常流行
  • 没有任何大公司支持

如果是这样的话,我们就应该学习 Vue

另一方面,我们可能需要一个库:

  • 使我们能够创建用户界面
  • 还可以使用官方和非官方插件进行扩展
  • 当使用 React Native 时,它甚至可以成为移动项目的基础
  • 在西方世界最为流行
  • 由 Meta 提供支持

如果是这样,我们就应该学习 React

总结

Vue 和 React 都是创建 web 应用程序的强大工具。React 因其庞大的社区和 Meta 的支持而更受欢迎,而 Vue 则因其简洁性和性能在过去几年中获得了越来越多的关注。

得到科技巨头的支持并非无关紧要!这基本上意味着资金和开发人员。对于 Vue 来说,独立是一个长期的挑战,因为它需要获得企业的采用和开源社区的支持,才能保持良好的状态。

总而言之,如果我们正在寻找一个可以帮助我们快速、轻松地创建用户界面的库,React 是一个不错的选择–这些界面以后可以成为使用 React Native 构建移动应用程序的基础。如果我们需要更强大、功能更丰富的东西,Vue 可能是更好的选择,因为它提供了更多开箱即用的功能,而且一般比 React 更快。

以上就是本文的全部内容,如果对你有所帮助,欢迎点赞、收藏、转发~

Vue3中的几个坑,你都见过吗? - 葡萄城技术团队 - 博客园

mikel阅读(295)

来源: Vue3中的几个坑,你都见过吗? – 葡萄城技术团队 – 博客园

Vue3 目前已经趋于稳定,不少代码库都已经开始使用它,很多项目未来也必然要迁移至Vue3。本文记录我在使用Vue3时遇到的一些问题,希望能为其他开发者提供帮助。

1. 使用reactive封装基础数据类型

传统开发模式中,数据声明很简单。但是在Vue中有多个响应式变量声明方式,整体的使用规则如下:

使用reactive来封装Object,Array,Map,Set数据类型;

使用ref封装String,Number,Boolean类型。

如果使用reactive来封装基础数据类型,会产生警告,同时封装的值不会成为响应式对象。

<script setup>
import { reactive } from "vue";
const count = reactive(0);
</script>

但是,可以使用ref来封装Object、Array等数据类型,内部会调用reactive。

2. 解构reactive对象

下面代码中,count封装成了reactive对象,点击按钮时,count会自增。

<template>
  Counter: {{ state.count }}
  <button @click="add">Increase</button>
 </template>


 <script>
 import { reactive } from "vue";
 export default {
  setup() {
   const state = reactive({ count: 0 });


   function add() {
    state.count++;
   }

   return {
    state,
    add,
   };
  },
 };
 </script>

如果需要使用ES6结构赋值对state进行结构,需要使用如下的代码:

<template>
  <div>Counter: {{ count }}</div>
  <button @click="add">Increase</button>
</template>

<script>
import { reactive } from "vue";
export default {
  setup() {
    const state = reactive({ count: 0 });

    function add() {
      state.count++;
    }

    return {
      ...state,
      add,
    };
  },
};
</script>

结构复制完成之后,点击按钮,效果如下:

代码看起来比较相似,而且根据以前的表现,逻辑是可以正常执行的。但事实上,Vue的响应式追踪通过属性获取,这意味着我们不能去解构响应式对象,会导致引用连接丢失。这是响应式代理的限制之一。

3. 使用.value造成的困惑

Ref接受一个值并返回一个响应式对象,该值只有在内部对象.value属性下可用。

const count = ref(0)

 console.log(count) // { value: 0 }
 console.log(count.value) // 0

 count.value++
 console.log(count.value) // 1

但是ref如果应用在template中,不需要对ref进行解包,也就是不需要使用.vue。

<script setup>
import { ref } from 'vue'

const count = ref(0)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">
    {{ count }} // 不需要调用.value
  </button>
</template>

需要注意的是,解包只作用于一级属性,下边的代码会返回[object Object]

<script setup>
import { ref } from 'vue'
const object = { foo: ref(1) }
</script>
<template>
  {{ object.foo + 1 }}  // [object Object]
</template>

正确使用.value需要时间,初学者偶尔会忘记它。在使用时,要注意只在合适的场景下使用它。

4. Emitted事件

从Vue发布以来,子组件可以通过emits与父组件通信,只需要添加一个自定义的监听器来监听事件即可。

this.$emit('my-event')
<my-component @my-event="doSomething" />

Vue3中,需要使用编译器宏defineEmits来声明emits。

const emit = defineEmits(['my-event'])
 emit('my-event')
 </script>

在setup语法糖下,defineEmits和defineProps会被自动引入。其它情况下,需要主动引入。

<script setup>
const props = defineProps({
  foo: String
})

const emit = defineEmits(['change', 'delete'])
// setup code
</script>

最后,由于Vue3中,事件必须声明,因此再需要使用.native修饰符,该修饰符已被移除。

5.声明组件选项

setup不支持如下组件选项声明:

  • name
  • inheritAttrs
  • customOptions

如果需要继续使用这些属性,可以声明多个script脚本,如下所示:

<script>
  export default {
    name: 'CustomName',
    inheritAttrs: false,
    customOptions: {}
  }
</script>

<script setup>
  // script setup logic
</script>

6.使用Reactivity Transform

Reactivity Transform是Vue3中一个预览属性,有一定的争议性,默认是禁用的。它主要用来简化组件的声明方式。这个想法是利用编译时转换来自动解包ref,从而避免使用.value。从Vue3.3中已经删除该功能,作为一个扩展包提供。由于它不是Vue的核心部分,且目前风险还是比较多,建议先不要在此方面投入太多事件。感兴趣可以参考文章:Reactivity Transform

7. 定义异步组件

异步组件以前是通过将它们包含在方法中来声明的。

const asyncModal = () => import('./Modal.vue')

Vue3中需要使用defineAsyncComponent来声明异步组件。

import { defineAsyncComponent } from 'vue'
 const asyncModal = defineAsyncComponent(() 
=> import('./Modal.vue'))

8. template中使用不必要的包装元素

<!-- Layout.vue -->
<template>
  <div>
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  </div>
</template>

Vue3中支持多个根元素,不再需要使用外层div元素包裹。

<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

9. 生命周期函数

所有组件生命周期函数都通过添加on前缀或完全更名实现,下图详细列出了具体的变化:

10. 产品文档

官方对文档已经做了更新,补充更新了API,并包含很多有价值的注释、指南和最佳实践。即使你现在使用的是Vue2,通过阅读新的文档也会学到一些新知识。

总结

每个框架都有学习曲线,Vue3相对Vue2更加陡峭,在框架切换之间也会有一定的学习成本。但Vue3组合式API相对Vue2选项式API确实更加简洁易用。如果您在使用过程中有什么疑问,也欢迎留言交流。

本文翻译自文章:

https://fadamakis.com/10-mistakes-to-avoid-when-starting-with-vue-3-1d1ced8552ae

扩展链接:

Spring Boot框架下实现Excel服务端导入导出

项目实战:在线报价采购系统(React +SpreadJS+Echarts)

React + Springboot + Quartz,从0实现Excel报表自动化

如何使用Vite创建Vue3的uniapp项目 - CanotStop - 博客园

mikel阅读(310)

来源: 如何使用Vite创建Vue3的uniapp项目 – CanotStop – 博客园

项目结构

my-vue3-project
├─ .env //默认环境变量
├─ .env.development //开发环境变量
├─ .eslintrc-auto-import.json //(autoimport变量,eslint配置)由auto-import插件生成
├─ .eslintrc.js //eslint配置文件
├─ .gitignore
├─ auto-imports.d.ts //(autoimport变量,ts声明文件)由auto-import插件生成
├─ index.html
├─ jsconfig.json
├─ package-lock.json
├─ package.json
├─ src
│ ├─ App.vue
│ ├─ components
│ ├─ main.js
│ ├─ manifest.json //uniapp项目配置文件
│ ├─ pages
│ │ └─ index
│ │ └─ IndexView.vue
│ ├─ pages.json //页面配置文件
│ ├─ services // 请求后端服务目录
│ │ ├─ api.js // 后端api
│ │ └─ http.js //请求
│ ├─ shime-uni.d.ts
│ ├─ static //静态文件目录
│ │ └─ logo.png
│ ├─ store //pinia全局状态库
│ │ └─ useUserStore.js
│ ├─ uni.scss
│ └─ utils //公共的工具方法
└─ vite.config.js

创建历程

项目创建

npx degit dcloudio/uni-preset-vue#vite my-vue3-project
  • Vue3/Vite 版要求 node 版本^14.18.0 || >=16.0.0
  • 如果使用 HBuilderX(3.6.7 以下版本)运行 Vue3/Vite 创建的最新的 cli 工程,需要在 HBuilderX 运行配置最底部设置 node 路径 为自己本机高版本 node 路径(注意需要重启 HBuilderX 才可以生效)
  • HBuilderX Mac 版本菜单栏左上角 HBuilderX->偏好设置->运行配置->node 路径
  • HBuilderX Windows 版本菜单栏 工具->设置->运行配置->node 路径

项目依赖安装

Eslint

Eslint 的相关配置可参考文章:Web 项目如何配置 Eslint
注意:在配置完 Eslint 之后,在项目中使用 uni 的时候会报 uni 未被定义的错,需在.eslintrc.js 中加上以下代码

globals: {
uni: true;
}

vite.config.js 中 eslintPlugin 配置

import eslintPlugin from ‘vite-plugin-eslint’
export default defineConfig({
plugins: [
eslintPlugin({
cache: true,
include: [‘src/**/*.js’, ‘src/**/*.vue’, ‘src/*.js’, ‘src/*.vue’, ‘src/*.nvue’],
failOnError: false // eslint报错不影响运行
}),
]

Pinia

安装

注意:在这个项目中安装的 vue 版本是:3.2.47,pinia:3.1 及以上版本需要依赖 vue:3.3 及以上版本才能运行成功。

@REM npm 安装
npm i pinia@2.0
@REM node 安装
yarn add pinia@2.0

安装依赖时出现如下报错可尝试通过参考文章解决:npm 安装依赖时出现 Peer Dependencies 冲突报错

While resolving: uni-preset-vue@0.0.0
Found: vue@3.2.47
node_modules/vue
peer vue@”^3.2.25″ from @vitejs/plugin-vue@4.3.4
node_modules/@vitejs/plugin-vue
Conflicting peer dependency: vue@3.3.4
node_modules/vue
peer vue@”>= 2.5 < 2.7″ from @vue/composition-api@1.7.2
node_modules/@vue/composition-api
peerOptional @vue/composition-api@”^1.4.0″ from pinia@2.0.34
node_modules/pinia
pinia@”2.0.34″ from the root project
Fix the upstream dependency conflict, or retry
this command with –force or –legacy-peer-deps
to accept an incorrect (and potentially broken) dependency resolution.

Luch-Request

uniapp 原生的 uni.request 使用比较麻烦,它并非使用 Promise 的形式也不支持请求拦截和相应拦截的配置,而 luch-request 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截

  • 支持全局挂载
  • 支持多个全局配置实例
  • 支持自定义验证器
  • 支持文件上传/下载
  • 支持 task 操作
  • 支持自定义参数
  • 支持多拦截器
  • 对参数的处理比 uni.request 更强

安装

npm install luch-request -S

Sass 支持

安装

npm i sass sass-loader -D

unplugin-auto-import

unplugin-auto-import 是为 Vite、Webpack、Rollup 和 esbuild 按需自动导入 API,同时支持 TypeScript。
使用它在 vue3 项目中使用预设导入的 api 就不需要 import,可以通过预设自动导入模块,增强开发体验

安装

npm i -D unplugin-auto-import

在 Vite.config.js 中加入如下配置

import AutoImport from “unplugin-auto-import/vite”;
export default defineConfig({
plugins: [
AutoImport({
// 需要自动引入的文件
include: [
/\.[j]sx?$/,
/\.vue$/,
/\.vue\?vue/,
/\.nvue$/,
/\.nvue\?nvue/,
/\.md$/,
],
// 全局自动引入api预设
imports: [
// 插件预设支持导入的api
“vue”,
// ‘vue-router’,
“pinia”,
“uni-app”,
// 自定义导入的api
],
// eslint配置
eslintrc: {
enabled: true, // Default `false`
filepath: “./.eslintrc-auto-import.json”, // Default `./.eslintrc-auto-import.json`
globalsPropValue: true, // Default `true`, (true | false | ‘readonly’ | ‘readable’ | ‘writable’ | ‘writeable’)
},
dts: “./auto-imports.d.ts”,
// dts:false
}),
],
});

生成 eslint 配置文件并使用

通过执行命令npm run dev:h5 运行项目,运行成功时项目根目录会生成auto-imports.d.ts.eslintrc-auto-import.json两个文件,然后在.eslintrc.js 文件中的 extends 属性中,引入该文件

extends: [
‘standard’,
‘plugin:vue/vue3-essential’,
‘./.eslintrc-auto-import.json’
]

注意:引入后需重新运行项目才能生效

添加默认和开发环境变量文件

在项目根目录添加.env 和.env.development 文件,以配置环境变量
详细配置教程可参照官网:Vite 环境变量和模式

配置 UI 库 uni-ui

安装

npm i @dcloudio/uni-ui

配置

vite.config.js

注意 cli 项目默认是不编译 node_modules 下的组件的,导致条件编译等功能失效 ,导致组件异常 需要在 vite.config.js 增加 @dcloudio/uni-ui 包的编译即可正常

transpileDependencies: [“@dcloudio/uni-ui”];

pages.json

正常来说这样子引入的话,使用组件时,需要在页面处 import 才可以使用,然而可以通过 npm+easycom 的形式来全局引入组件。在 pages.json 中加入如下代码,即可在使用组件而不需在页面处 import。

“easycom”: {
“autoscan”: true,
“custom”: {
“^uni-(.*)”: “@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue”
}
}

项目到这里就结束了,这里提供该项目的 github 地址,方便拉取直接使用

这个项目中 master 分支中使用的 Eslint 风格为 Standard,而 prettier 分支使用的风格为 Prettier

https://github.com/luxigaola/my-uniapp-project

  1. 内容来自 uniapp 官网,详情可查看使用 vue-cli 查看目录 ↩︎
  2. pinia 官网 ↩︎
  3. luch-request 官网 ↩︎
  4. sass 官网 ↩︎
  5. unplugin-auto-import 官网 ↩︎
  6. uni-ui Github 地址 ↩︎

10款Visual Studio实用插件 - 追逐时光者 - 博客园

mikel阅读(363)

来源: 10款Visual Studio实用插件 – 追逐时光者 – 博客园

10款Visual Studio实用插件 

前言

俗话说的好工欲善其事必先利其器,安装一些Visual Studio实用插件对自己日常的开发和工作效率能够大大的提升,避免996从选一款好的IDE实用插件开始。以下是我认为比较实用的Visual Studio插件希望对大家有用,大家有更好的插件推荐可在文末留言🤞。

Visual Studio插件搜索

扩展=>管理扩展:

Visual Studio插件市场

https://marketplace.visualstudio.com/👉

ReSharper(付费)

ReSharper 是一个用于 Visual Studio 的强大插件,它为.NET开发者提供了许多功能,以提高编码效率、代码质量和开发体验。旨在帮助.NET开发者编写高质量、高效的代码,并提供了许多辅助工具来改进开发流程和减少常见的编码错误。(注意电脑内存小的同学慎用,比较占用内存)

插件市场地址:https://marketplace.visualstudio.com/items?itemName=JetBrains.ReSharper👉

GitHub Copilot(付费)

GitHub Copilot 是一款AI辅助工具,帮助开发者更快速、智能地编写高质量代码。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=GitHub.copilotvs👉

CodeMaid(免费)

CodeMaid 是 Visual Studio 的开源扩展,用于清理和简化 C#、C++、F#、VB、PHP、PowerShell、R、JSON、XAML、XML、ASP、HTML、CSS、LESS、SCSS、JavaScript 和 TypeScript 编码。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=SteveCadwallader.CodeMaidVS2022👉

CSharpier(免费)

CSharpier 是一个用于 C# 代码的代码格式化工具。它是一个基于 Roslyn 的工具,它会解析您的 C# 代码,然后根据特定的规则重新格式化它,使其符合 CSharpier 的代码风格。这个工具的设计目的是使代码风格保持一致,从而提高代码的可读性和可维护性。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=csharpier.CSharpier#report-abuse👉

格式之前:

格式之后:

Visual Studio Theme Pack(免费)

Visual Studio流行主题集。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=idex.vsthemepack👉

Indent Guides(免费)

显示代码缩进线,有助于保持代码的结构清晰。页宽标记有三种样式:实线、点线面和虚线,有粗细之分,颜色也可自定义。默认为灰色虚线,如图所示。每个缩进级别可以有不同的样式和颜色。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=SteveDowerMSFT.IndentGuides2022👉

Markdown Editor(免费)

功能齐全的 Markdown 编辑器,具有实时预览和语法高亮功能。支持 GitHub 版本的 Markdown。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=MadsKristensen.MarkdownEditor👉

HTML Snippet Pack(免费)

它提供了一组预定义的 HTML 代码段(snippets),以帮助开发者更快速地编写 HTML 代码。这些代码段是预先定义的代码模板,可以通过简单的代码缩写触发,然后自动生成相应的 HTML 代码块,从而提高编写 HTML 的效率和准确性。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=MadsKristensen.HTMLSnippetPack👉

Ozcode(免费)

Ozcode 是一个用于 Visual Studio 的插件拓展,旨在优化和简化 C# 调试过程。它提供了一系列功能,可以帮助开发人员更快速地检测和解决代码中的错误,从而提高调试效率和开发生产力。这个插件拓展使调试变得更加直观和高效,有助于加速软件开发周期。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=CodeValueLtd.OzCode👉

Live Share(免费)

它的主要功能是支持实时协作开发,并让开发人员能够在他们最喜欢的开发工具中进行协作。

插件市场地址:https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsls-vs👉

webapi开发框架实践 - 星仔007 - 博客园

mikel阅读(307)

来源: webapi开发框架实践 – 星仔007 – 博客园

项目链接以及目录结构

liuzhixin405/efcore-template (github.com)

这是一个纯webapi的开发框架。

1、支持的orm有efcore6、dapper,可以灵活切换数据库。

复制代码
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Elfie.Model;
using Microsoft.EntityFrameworkCore;
using project.Context;
using project.Repositories;
using project.Services;
using RepositoryComponent.DbFactories;

namespace project.Extensions
{
    public static partial class TheExtensions
    {
        public static void AddDatabase(this WebApplicationBuilder builder)
        {
            ///sqlserver   
            if (builder.Configuration["DbType"]?.ToLower() == "sqlserver")
            {
                builder.Services.AddDbContext<ReadProductDbContext>(options => options.UseSqlServer(builder.Configuration["ConnectionStrings:SqlServer:ReadConnection"]), ServiceLifetime.Scoped);
                builder.Services.AddDbContext<WriteProductDbContext>(options => options.UseSqlServer(builder.Configuration["ConnectionStrings:SqlServer:WriteConnection"]), ServiceLifetime.Scoped);

            }
            ///mysql
            else if (builder.Configuration["DbType"]?.ToLower() == "mysql")
            {
                builder.Services.AddDbContext<ReadProductDbContext>(options => options.UseMySQL(builder.Configuration["ConnectionStrings:MySql:ReadConnection"]), ServiceLifetime.Scoped);
                builder.Services.AddDbContext<WriteProductDbContext>(options => options.UseMySQL(builder.Configuration["ConnectionStrings:MySql:WriteConnection"]), ServiceLifetime.Scoped);

            }
            else
            {
                //throw new ArgumentNullException("δ����ȷ��ע�����ݿ�");
                builder.Services.AddDbContext<ReadProductDbContext>(options => options.UseInMemoryDatabase("test_inmemory_db"), ServiceLifetime.Scoped);
                builder.Services.AddDbContext<WriteProductDbContext>(options => options.UseInMemoryDatabase("test_inmemory_db"), ServiceLifetime.Scoped);

            }

            builder.Services.AddScoped<Func<ReadProductDbContext>>(provider => () => provider.GetService<ReadProductDbContext>() ?? throw new ArgumentNullException("ReadProductDbContext is not inject to program"));
            builder.Services.AddScoped<Func<WriteProductDbContext>>(provider => () => provider.GetService<WriteProductDbContext>() ?? throw new ArgumentNullException("WriteProductDbContext is not inject to program"));

            builder.Services.AddScoped<DbFactory<WriteProductDbContext>>();
            builder.Services.AddScoped<DbFactory<ReadProductDbContext>>();

            builder.Services.AddTransient<IReadProductRepository, ProductReadRepository>();
            builder.Services.AddTransient<IWriteProductRepository, ProductWriteRepository>();
            builder.Services.AddTransient<IProductService, ProductService>();

            builder.Services.AddTransient<ICustomerService, CustomerService>();
        }
    }
}
复制代码

2、至于消息中间件有rabbitmq、kafka,也是通过配置文件来指定哪一个实现。

复制代码
using MessageMiddleware.Factory;
using MessageMiddleware.RabbitMQ;

namespace project.Extensions
{
    public static partial class TheExtensions
    {
        public static void AddMq(this WebApplicationBuilder builder)
        {
            var rabbitMqSetting = new RabbitMQSetting
            {
                ConnectionString = builder.Configuration["MqSetting:RabbitMq:ConnectionString"].Split(';'),
                Password = builder.Configuration["MqSetting:RabbitMq:PassWord"],
                Port = int.Parse(builder.Configuration["MqSetting:RabbitMq:Port"]),
                SslEnabled = bool.Parse(builder.Configuration["MqSetting:RabbitMq:SslEnabled"]),
                UserName = builder.Configuration["MqSetting:RabbitMq:UserName"],
            };
            var kafkaSetting = new MessageMiddleware.Kafka.Producers.ProducerOptions
            {
                BootstrapServers = builder.Configuration["MqSetting:Kafka:BootstrapServers"],
                SaslUsername = builder.Configuration["MqSetting:Kafka:SaslUserName"],
                SaslPassword = builder.Configuration["MqSetting:Kafka:SaslPassWord"],
                Key = builder.Configuration["MqSetting:Kafka:Key"]
            };
            var mqConfig = new MQConfig
            {
                ConsumerLog = bool.Parse(builder.Configuration["MqSetting:ConsumerLog"]),
                PublishLog = bool.Parse(builder.Configuration["MqSetting:PublishLog"]),
                Rabbit = rabbitMqSetting,
                Use = int.Parse(builder.Configuration["MqSetting:Use"]),
                Kafka = kafkaSetting
            };
            builder.Services.AddSingleton<MQConfig>(sp => mqConfig);
            builder.Services.AddMQ(mqConfig);
        }
    }
}
复制代码

3、该项目还集成了mongodb和elasticsearch,在project项目中没有写实现案例,实现起来也很简单。

4、下面是分布式雪花id的实现,先注入代码,使用的时候直接使用distributedid即可。

复制代码
 builder.Services.AddDistributedLock(x =>
 {
     x.LockType = LockType.InMemory;
     x.RedisEndPoints = new string[] { builder.Configuration["DistributedRedis:ConnectionString"] ?? throw new Exception("$未能获取distributedredis连接字符串")};
 }).AddCache(new CacheOptions
 {
     CacheType = CacheTypes.Redis,
     RedisConnectionString = builder.Configuration["DistributedRedis:ConnectionString"] ?? throw new Exception("$未能获取distributedredis连接字符串")
 }).AddDistributedId(new DistributedIdOptions
 {
     Distributed = true
 });
复制代码
1
newProduct.Id = _distributedId.NewLongId().ToString();

5、缓存使用的是分布式缓存和内存缓存,其中分布式缓存有一般实现和指定序列化格式的实现。

复制代码
using System.Text;
using System.Text.Json.Serialization;
using MessagePack;
using StackExchange.Redis.Extensions.Core;
using StackExchange.Redis.Extensions.Core.Abstractions;
using StackExchange.Redis.Extensions.Core.Configuration;
using StackExchange.Redis.Extensions.Core.Implementations;

namespace project.Utility.Helper
{
    public class CacheHelper
    {
        private static IRedisClientFactory _factory_with_msgpack;
        private static IRedisDatabase _redis_with_msgpack => _factory_with_msgpack.GetDefaultRedisDatabase();

        private static IRedisClientFactory _factory;
        private static IRedisDatabase _redis => _factory.GetDefaultRedisDatabase();
        public static void Init(IConfiguration configuration)
        {
            var config = configuration.GetSection("Redis").Get<RedisConfiguration>();
            _factory = new RedisClientFactory(new[] { config }, null, new RedisSerializer());
            _factory_with_msgpack = new RedisClientFactory(new[] { config }, null, new RedisMessagepackSerializer());
        }
        static CacheHelper() { }

        public static T Get<T>(string key)
        {
            return _redis.GetAsync<T>(key).GetAwaiter().GetResult();
        }
        public static async Task<T> GetAsync<T>(string key)
        {
            return await _redis.GetAsync<T>(key);
        }
        public static async Task<T> GetAsync_With_Msgpack<T>(string key)
        {
            return await _redis_with_msgpack.GetAsync<T>(key);
        }

        public static string Get(string key)
        {
            return _redis.GetAsync<string>(key).GetAwaiter().GetResult();
        }

        public static bool Set(string key, object value, TimeSpan expiresIn)
        {
            return _redis.AddAsync(key, value, expiresIn).GetAwaiter().GetResult();
        }
        public static async Task<bool> SetAsync(string key, object value, TimeSpan expiresIn)
        {
            return await _redis.AddAsync(key, value, expiresIn);
        }

        public static async Task<bool> SetAsync_With_Msgpack(string key, object value, TimeSpan expiresIn)
        {
            return await _redis_with_msgpack.AddAsync(key, value, expiresIn);
        }

        /// <summary>
        /// 以秒为单位,返回给定 key 的剩余生存时间
        /// </summary>

        public static long GetExpirin(string key)
        {
            var timespan = _redis.Database.KeyTimeToLive(key);
            if (timespan == null) { return 0; }
            return (long)timespan.Value.TotalSeconds;
        }
        public static bool KeyExpire(string key, TimeSpan expiresIn)
        {
            return _redis.Database.KeyExpire(key, expiresIn);
        }
        public static async Task<bool> RemoveKeyAsync(string key)
        {
            return await _redis.Database.KeyDeleteAsync(key);
        }
        public static long RemoveKey(string key)
        {
            var result = _redis.Database.KeyDelete(key);
            return result ? 1 : 0;
        }
    }


    public class RedisSerializer : ISerializer
    {
        public T? Deserialize<T>(byte[] serializedObject)
        {
            var data = Encoding.UTF8.GetString(serializedObject);
            return System.Text.Json.JsonSerializer.Deserialize<T>(data);
        }

        public byte[] Serialize<T>(T? item)
        {
            var data = System.Text.Json.JsonSerializer.Serialize(item);
            return Encoding.UTF8.GetBytes(data);
        }
    }

    public class RedisMessagepackSerializer : ISerializer
    {
        private MessagePackSerializerOptions _options;
        public RedisMessagepackSerializer()
        {
            _options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
        }
        public T? Deserialize<T>(byte[] serializedObject)
        {
            return MessagePackSerializer.Deserialize<T>(serializedObject, _options);
        }

        public byte[] Serialize<T>(T? item)
        {
            return MessagePackSerializer.Serialize(item, _options);
        }
    }
}
复制代码

6、单元测试、集成测试没有写。

更细节的需要自己看代码,这应该是一个基本的开发具备的功能。

该项目下载下来可以直接运行。