
运行到小程序模拟机->微信开发者工具,见到微信IDE启动了但不进入项目的原因之一,你不是该小程序的开发者
运行到小程序模拟机->微信开发者工具,见到微信IDE启动了但不进入项目的原因之一,你不是该小程序的开发者
运行到小程序模拟机->微信开发者工具,见到微信IDE启动了但不进入项目的原因之一,你不是该小程序的开发者

公告:腾讯云套餐调整周知
【一】uniCloud腾讯云包月套餐将于2021年1月21日后新增【免费版】和【特惠基础版1】套餐,原【基础版1】的套餐将不再开放购买。若您已经开通【基础版1】包年包月套餐,仍可继续使用该服务空间。如若对该服务空间进行升配,且到期时账号下无免费服务空间,则会为您降配至新的【免费版】。
【二】自2021年3月12日后,在uniCloud腾讯云按量计费环境内,如果当日有资源使用,且产生的计费金额不足0.01元,将补齐按照0.01元收取。
详见:https://uniapp.dcloud.net.cn/uniCloud/price?id=%e8%85%be%e8%ae%af%e4%ba%91
【一】uniCloud腾讯云包月套餐将于2021年1月21日后新增【免费版】和【特惠基础版1】套餐,原【基础版1】的套餐将不再开放购买。若您已经开通【基础版1】包年包月套餐,仍可继续使用该服务空间。如若对该服务空间进行升配,且到期时账号下无免费服务空间,则会为您降配至新的【免费版】。
【二】自2021年3月12日后,在uniCloud腾讯云按量计费环境内,如果当日有资源使用,且产生的计费金额不足0.01元,将补齐按照0.01元收取。
详见:https://uniapp.dcloud.net.cn/uniCloud/price?id=%e8%85%be%e8%ae%af%e4%ba%91
收起阅读 »
无法监听下载进度文件总大小的临时解决办法[希望官方能修复这个BUG]
反正也不知道从哪个版本开始就发现更新wgt包时无法获取下载文件总大小了。
大概从3.0版或2.9几版开始就不能用了,刚开始以为BUG会修复,
结果等到了3.0.7都没有修复这个BUG。
以前是直接下载文件如:
http://xxxx.com/sss.wgt
用下载API就可以获取文件总大小,后来出现BUG后,这个就不行了。
现在可以通过主动输出文件来获取,但只适合一个两个的文件,如果直接要下载图片,这样做是行不通的。
临时解决如下:
PHP后端,输出要更新的wgt包:
final function appdown(){
header('Content-Type: application/octet-stream');
$files=$_SERVER['DOCUMENT_ROOT'].'/appdown/app.wgt';
$filesize = filesize($files); //获得文件大小
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding: binary');
header('Content-Encoding: none');
header('Content-type: application/force-download');
header('Content-length: '.$filesize);//此处是重点
header('Content-Disposition: attachment; filename="jingliang.wgt"');
readfile("$files");
}
H5+用plus.downloader.createDownload来监听下载进度
uniapp有bug,无法监听下载进度事件,也可用plus.downloader.createDownload来操作下载
另外还有个BUG就是,plus.downloader.createDownload下载监听时的进度与实际下载进度不相符,例如实际下载10秒就完成了,但是监听进度要20秒才会完成反应太慢了,这在之前版本上好像是没有这种太明显的慢的现象的【刚开始怀疑这个可能是进度条30毫秒才走1步造成的,后来发现状态3的监听基本是跟不上下载的速度的,这在以前是没有这个情况的】。
但是尽管这种办法能获取文件大小,也是没有用的,因为只要它下载完成就会调起自动安装,此时进度条还需要N秒才能走完,下载进度监听根本不到100%。。。
还是等官方修复这个BUG吧,之前都可以直接获取下载文件的大小。
反正也不知道从哪个版本开始就发现更新wgt包时无法获取下载文件总大小了。
大概从3.0版或2.9几版开始就不能用了,刚开始以为BUG会修复,
结果等到了3.0.7都没有修复这个BUG。
以前是直接下载文件如:
http://xxxx.com/sss.wgt
用下载API就可以获取文件总大小,后来出现BUG后,这个就不行了。
现在可以通过主动输出文件来获取,但只适合一个两个的文件,如果直接要下载图片,这样做是行不通的。
临时解决如下:
PHP后端,输出要更新的wgt包:
final function appdown(){
header('Content-Type: application/octet-stream');
$files=$_SERVER['DOCUMENT_ROOT'].'/appdown/app.wgt';
$filesize = filesize($files); //获得文件大小
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding: binary');
header('Content-Encoding: none');
header('Content-type: application/force-download');
header('Content-length: '.$filesize);//此处是重点
header('Content-Disposition: attachment; filename="jingliang.wgt"');
readfile("$files");
}
H5+用plus.downloader.createDownload来监听下载进度
uniapp有bug,无法监听下载进度事件,也可用plus.downloader.createDownload来操作下载
另外还有个BUG就是,plus.downloader.createDownload下载监听时的进度与实际下载进度不相符,例如实际下载10秒就完成了,但是监听进度要20秒才会完成反应太慢了,这在之前版本上好像是没有这种太明显的慢的现象的【刚开始怀疑这个可能是进度条30毫秒才走1步造成的,后来发现状态3的监听基本是跟不上下载的速度的,这在以前是没有这个情况的】。
但是尽管这种办法能获取文件大小,也是没有用的,因为只要它下载完成就会调起自动安装,此时进度条还需要N秒才能走完,下载进度监听根本不到100%。。。
还是等官方修复这个BUG吧,之前都可以直接获取下载文件的大小。
收起阅读 »
【建议】uni-app创建新项目自动增加.gitignore文件
把这段放进去:
/unpackage/
.DS_Store
*/.DS_Store
不然偶尔忘记,直接把/unpackage/里一堆没用的东西也同步
把这段放进去:
/unpackage/
.DS_Store
*/.DS_Store
不然偶尔忘记,直接把/unpackage/里一堆没用的东西也同步

2021年全新UI界面1:1仿皮皮虾APP段子 - 影视+直播+小视频+赚钱+采集
官方网站:http://www.suxiangw.com/duanzi.html
购买QQ:1424445608
电话:15622289461
演示APP下载:http://www.nihaopi.com/
演示后台网址:http://www.nihaopi.com/admin.php
速翔段子APP系统源码自主研发的社交软件产品,UI界面1:1仿皮皮虾APP,支持视频、图文、文字、影视、直播、小视频等,有点赞、送神评、收藏、插眼、保存、分享、点踩、评论等等众多功能等您体验!

官方网站:http://www.suxiangw.com/duanzi.html
购买QQ:1424445608
电话:15622289461
演示APP下载:http://www.nihaopi.com/
演示后台网址:http://www.nihaopi.com/admin.php
速翔段子APP系统源码自主研发的社交软件产品,UI界面1:1仿皮皮虾APP,支持视频、图文、文字、影视、直播、小视频等,有点赞、送神评、收藏、插眼、保存、分享、点踩、评论等等众多功能等您体验!
收起阅读 »
链家程序员怒删公司 9TB 数据,被判 7 年!
1月6日,北京市第一中级人民法院公布前链家员工破坏计算机信息系统罪一案的刑事裁定书,被告人因不满工作调整,删公司9TB数据。
北京市海淀区人民法院判决认定:
2018年6月4日14时许,被告人韩冰在位于本市海淀区上地三街福道大厦三层的链家网(北京)科技有限公司(以下简称链家公司),利用其担任链家公司数据库管理员并掌握公司财务系统root权限的便利,登录公司财务系统服务器删除了财务数据及相关应用程序,致使公司财务系统无法登录。链家公司为恢复数据及重新构建财务系统共计花费人民币18万元。2018年7月31日,被告人韩冰被公安机关抓获归案。
北京市海淀区人民法院认为,被告人韩冰违反国家规定,对计算机信息系统中存储的数据和应用程序进行删除,造成计算机信息系统不能正常运行,后果特别严重,其行为已构成破坏计算机信息系统罪,依法应予惩处。依照《中华人民共和国刑法》第二百八十六条第一款、第二款之规定,判决:被告人韩冰犯破坏计算机信息系统罪,判处有期徒刑七年。
以下为刑事裁定书原文:
========================================
北京市第一中级人民法院
刑 事 裁 定 书
(2020)京01刑终490号
原公诉机关北京市海淀区人民检察院。
上诉人(原审被告人)韩冰,男,40岁(1980年11月25日出生),汉族,出生地北京市,大学文化,案发前系链家网(北京)科技有限公司数据库管理员,住北京市朝阳区。因涉嫌犯破坏计算机信息系统罪,于2018年7月31日被羁押,同年8月15日被逮捕。现羁押于北京市海淀区看守所。
指定辩护人王璐,北京市邦盛律师事务所律师。
指定辩护人王禹婷,北京市邦盛律师事务所律师。
北京市海淀区人民法院审理北京市海淀区人民检察院指控被告人韩冰犯破坏计算机信息系统罪一案,于2020年11月4日作出(2019)京0108刑初398号刑事判决。原审被告人韩冰不服,提出上诉。本院依法组成合议庭,经过阅卷,讯问上诉人,听取辩护人的意见,核实有关证据,认为本案的事实清楚,决定不开庭审理。现已审理终结。
北京市海淀区人民法院判决认定:
2018年6月4日14时许,被告人韩冰在位于本市海淀区上地三街福道大厦三层的链家网(北京)科技有限公司(以下简称链家公司),利用其担任链家公司数据库管理员并掌握公司财务系统root权限的便利,登录公司财务系统服务器删除了财务数据及相关应用程序,致使公司财务系统无法登录。链家公司为恢复数据及重新构建财务系统共计花费人民币18万元。2018年7月31日,被告人韩冰被公安机关抓获归案。
上述事实,有经一审庭审举证、质证并予以确认的被告人韩冰的供述,证人周某等人的证言,司法鉴定意见书,技术服务合同,银行电子回单,发票,情况说明,MAC地址行为日志,链家公司检索主机名详单,劳动合同,电子邮件,会议纪要,微信群聊天记录,员工信息,扣押笔录,受案登记表,到案经过等证据证实。
北京市海淀区人民法院认为,被告人韩冰违反国家规定,对计算机信息系统中存储的数据和应用程序进行删除,造成计算机信息系统不能正常运行,后果特别严重,其行为已构成破坏计算机信息系统罪,依法应予惩处。依照《中华人民共和国刑法》第二百八十六条第一款、第二款之规定,判决:被告人韩冰犯破坏计算机信息系统罪,判处有期徒刑七年。
上诉人韩冰的主要上诉理由为:监控录像等证据证明其没有实施犯罪。其不是可以进入被害单位内网且有Yggdrasil主机名的唯一用户。证明其电脑中存在sherd及rm命令的证据之间存在矛盾。在其电脑中检索到的关于Mac地址EA:36:33:43:78:88的记录与其无关,有可能是该MAC地址的设备访问其电脑留下的。被害单位刻意制造维修费用,且没有证据证明被害单位损失,故其不认可被害人的损失数额。
上诉人韩冰的辩护人的主要辩护意见为:本案事实不清、证据不足,不能排除合理怀疑,应疑罪从无。电子数据鉴定意见的起始基准时间晚于案发一个多月,不能确定在此期间电子数据有无修改。现有证据不能证实韩冰实施删除行为的准确时间以及韩冰实施了使用命令攻击删除行为。不能排除系有漏洞和程序问题导致外介质因素入侵。是否造成系统全部瘫痪的事实不清、证据不足,删除数据大小不明确。18万元损失的认定证据不足,没有第三方机构评估、鉴定等证据。韩冰具有主观恶性不大,未造成严重社会影响等从轻情节。
二审审理期间,上诉人韩冰及其辩护人均未向法庭提交新的证据。
经二审审理查明的事实与一审相同。一审判决所据证据,经审查,证据的收集及质证符合法定程序,能够证明认定的事实,本院予以确认。
对于上诉人韩冰及其辩护人所提本案存在多重合理怀疑,应当认定韩冰无罪的上诉理由及辩护意见,经查:国家信息中心电子数据司法鉴定中心司法鉴定意见书证明,2018年6月4日14时至15时期间,IP地址为10.33.35.160的终端用户远程以root身份登录链家公司服务器并通过执行rm、shred命令删除数据文件、擦除操作日志等,而该IP地址于6月4日14时17分被分配给MAC地址为EA-36-33-43-78-88、主机名为Yggdrasil的设备使用。该IP地址为链家公司福道大厦3楼交换机所覆盖网络区域,而韩冰具有root权限且于案发当日在上述IP地址的网络覆盖区域内上班。经司法鉴定确认,韩冰电脑的主机名为Yggdrasil,与登录服务器执行删除、擦除命令的电脑主机名一致;韩冰电脑的MAC地址虽不是EA-36-33-43-78-88,但其电脑中安装有用于更改MAC地址的软件WiFiSpoof,且在其电脑的相关文件中检索到多条与上述MAC地址相关的记录。综合案发后韩冰的表现,以及对具有类似权限人员所用电脑的鉴定结论等情况,能够确定韩冰实施了删除链家公司财务系统服务器程序数据的行为。上诉人韩冰及其辩护人所提的相关辩解及辩护意见,无事实及法律依据,本院不予采纳。
对于上诉人韩冰所提监控录像证明其没有实施犯罪的上诉理由,经查:视频服务器和涉案四台服务器均未与标准时间校准,无法判断监控时间与服务器时间的时间差,无法以视频时间和服务器时间排除韩冰作案的可能。故对韩冰的该项上诉理由,本院不予采纳。
对于上诉人韩冰及其辩护人所提认定被害单位损失的证据不足的上诉理由及辩护意见,经查:链家公司情况说明等证据证明,财务系统数据修复系专业性强、时效性高的技术类工作,链家公司在被删除系统后紧急聘请第三方公司进行财务数据恢复工作,不属于刻意制造费用。技术服务合同、服务报价单、银行电子回单、发票等证据证明,链家公司基于财务系统受损而支付修复费用18万元。一审据此认定被害单位损失,证据确实充分。故韩冰及其辩护人的相关意见,缺乏事实及法律依据,本院均不予采纳。
本院认为,上诉人韩冰违反国家规定,对计算机信息系统中存储的数据和应用程序进行删除,造成计算机信息系统不能正常运行,其行为已构成破坏计算机信息系统罪,且后果特别严重,依法应予惩处。 一审法院根据韩冰犯罪的事实、犯罪的性质、情节及对于社会的危害程度所作出的判决,事实清楚,证据确实、充分,定罪及适用法律正确,量刑适当,审判程序合法,应予维持。据此,依照《中华人民共和国刑事诉讼法》第二百三十六条第一款第(一)项之规定,裁定如下:
驳回上诉,维持原判。
本裁定为终审裁定。
审 判 长 关 芳
审 判 员 鲍 艳
审 判 员 孙 燕
二〇二〇年十二月二十九日
法官助理 韩 峰
书 记 员 孟丹丹
========================================
此前,北京市海淀区人民法院在韩冰的一审刑事判决书中已指控被告人韩冰犯破坏信息系统罪,原审被告人韩冰不服,曾提出上诉。
参考链接:https://wenshu.court.gov.cn/website/wenshu/181107ANFZ0BXSK4/index.html?docId=ca312e28689b498a8ac1aca8009ac7fc
删库一时爽,但毁了自己的职业生涯,断送了自己的前程真心不值。
最后希望我们的程序员对于任何涉嫌违法的事件,都要保持一颗敬畏的心。
此文章转载自极客日报,如有不当联系删除。原文链接
1月6日,北京市第一中级人民法院公布前链家员工破坏计算机信息系统罪一案的刑事裁定书,被告人因不满工作调整,删公司9TB数据。
北京市海淀区人民法院判决认定:
2018年6月4日14时许,被告人韩冰在位于本市海淀区上地三街福道大厦三层的链家网(北京)科技有限公司(以下简称链家公司),利用其担任链家公司数据库管理员并掌握公司财务系统root权限的便利,登录公司财务系统服务器删除了财务数据及相关应用程序,致使公司财务系统无法登录。链家公司为恢复数据及重新构建财务系统共计花费人民币18万元。2018年7月31日,被告人韩冰被公安机关抓获归案。
北京市海淀区人民法院认为,被告人韩冰违反国家规定,对计算机信息系统中存储的数据和应用程序进行删除,造成计算机信息系统不能正常运行,后果特别严重,其行为已构成破坏计算机信息系统罪,依法应予惩处。依照《中华人民共和国刑法》第二百八十六条第一款、第二款之规定,判决:被告人韩冰犯破坏计算机信息系统罪,判处有期徒刑七年。
以下为刑事裁定书原文:
========================================
北京市第一中级人民法院
刑 事 裁 定 书
(2020)京01刑终490号
原公诉机关北京市海淀区人民检察院。
上诉人(原审被告人)韩冰,男,40岁(1980年11月25日出生),汉族,出生地北京市,大学文化,案发前系链家网(北京)科技有限公司数据库管理员,住北京市朝阳区。因涉嫌犯破坏计算机信息系统罪,于2018年7月31日被羁押,同年8月15日被逮捕。现羁押于北京市海淀区看守所。
指定辩护人王璐,北京市邦盛律师事务所律师。
指定辩护人王禹婷,北京市邦盛律师事务所律师。
北京市海淀区人民法院审理北京市海淀区人民检察院指控被告人韩冰犯破坏计算机信息系统罪一案,于2020年11月4日作出(2019)京0108刑初398号刑事判决。原审被告人韩冰不服,提出上诉。本院依法组成合议庭,经过阅卷,讯问上诉人,听取辩护人的意见,核实有关证据,认为本案的事实清楚,决定不开庭审理。现已审理终结。
北京市海淀区人民法院判决认定:
2018年6月4日14时许,被告人韩冰在位于本市海淀区上地三街福道大厦三层的链家网(北京)科技有限公司(以下简称链家公司),利用其担任链家公司数据库管理员并掌握公司财务系统root权限的便利,登录公司财务系统服务器删除了财务数据及相关应用程序,致使公司财务系统无法登录。链家公司为恢复数据及重新构建财务系统共计花费人民币18万元。2018年7月31日,被告人韩冰被公安机关抓获归案。
上述事实,有经一审庭审举证、质证并予以确认的被告人韩冰的供述,证人周某等人的证言,司法鉴定意见书,技术服务合同,银行电子回单,发票,情况说明,MAC地址行为日志,链家公司检索主机名详单,劳动合同,电子邮件,会议纪要,微信群聊天记录,员工信息,扣押笔录,受案登记表,到案经过等证据证实。
北京市海淀区人民法院认为,被告人韩冰违反国家规定,对计算机信息系统中存储的数据和应用程序进行删除,造成计算机信息系统不能正常运行,后果特别严重,其行为已构成破坏计算机信息系统罪,依法应予惩处。依照《中华人民共和国刑法》第二百八十六条第一款、第二款之规定,判决:被告人韩冰犯破坏计算机信息系统罪,判处有期徒刑七年。
上诉人韩冰的主要上诉理由为:监控录像等证据证明其没有实施犯罪。其不是可以进入被害单位内网且有Yggdrasil主机名的唯一用户。证明其电脑中存在sherd及rm命令的证据之间存在矛盾。在其电脑中检索到的关于Mac地址EA:36:33:43:78:88的记录与其无关,有可能是该MAC地址的设备访问其电脑留下的。被害单位刻意制造维修费用,且没有证据证明被害单位损失,故其不认可被害人的损失数额。
上诉人韩冰的辩护人的主要辩护意见为:本案事实不清、证据不足,不能排除合理怀疑,应疑罪从无。电子数据鉴定意见的起始基准时间晚于案发一个多月,不能确定在此期间电子数据有无修改。现有证据不能证实韩冰实施删除行为的准确时间以及韩冰实施了使用命令攻击删除行为。不能排除系有漏洞和程序问题导致外介质因素入侵。是否造成系统全部瘫痪的事实不清、证据不足,删除数据大小不明确。18万元损失的认定证据不足,没有第三方机构评估、鉴定等证据。韩冰具有主观恶性不大,未造成严重社会影响等从轻情节。
二审审理期间,上诉人韩冰及其辩护人均未向法庭提交新的证据。
经二审审理查明的事实与一审相同。一审判决所据证据,经审查,证据的收集及质证符合法定程序,能够证明认定的事实,本院予以确认。
对于上诉人韩冰及其辩护人所提本案存在多重合理怀疑,应当认定韩冰无罪的上诉理由及辩护意见,经查:国家信息中心电子数据司法鉴定中心司法鉴定意见书证明,2018年6月4日14时至15时期间,IP地址为10.33.35.160的终端用户远程以root身份登录链家公司服务器并通过执行rm、shred命令删除数据文件、擦除操作日志等,而该IP地址于6月4日14时17分被分配给MAC地址为EA-36-33-43-78-88、主机名为Yggdrasil的设备使用。该IP地址为链家公司福道大厦3楼交换机所覆盖网络区域,而韩冰具有root权限且于案发当日在上述IP地址的网络覆盖区域内上班。经司法鉴定确认,韩冰电脑的主机名为Yggdrasil,与登录服务器执行删除、擦除命令的电脑主机名一致;韩冰电脑的MAC地址虽不是EA-36-33-43-78-88,但其电脑中安装有用于更改MAC地址的软件WiFiSpoof,且在其电脑的相关文件中检索到多条与上述MAC地址相关的记录。综合案发后韩冰的表现,以及对具有类似权限人员所用电脑的鉴定结论等情况,能够确定韩冰实施了删除链家公司财务系统服务器程序数据的行为。上诉人韩冰及其辩护人所提的相关辩解及辩护意见,无事实及法律依据,本院不予采纳。
对于上诉人韩冰所提监控录像证明其没有实施犯罪的上诉理由,经查:视频服务器和涉案四台服务器均未与标准时间校准,无法判断监控时间与服务器时间的时间差,无法以视频时间和服务器时间排除韩冰作案的可能。故对韩冰的该项上诉理由,本院不予采纳。
对于上诉人韩冰及其辩护人所提认定被害单位损失的证据不足的上诉理由及辩护意见,经查:链家公司情况说明等证据证明,财务系统数据修复系专业性强、时效性高的技术类工作,链家公司在被删除系统后紧急聘请第三方公司进行财务数据恢复工作,不属于刻意制造费用。技术服务合同、服务报价单、银行电子回单、发票等证据证明,链家公司基于财务系统受损而支付修复费用18万元。一审据此认定被害单位损失,证据确实充分。故韩冰及其辩护人的相关意见,缺乏事实及法律依据,本院均不予采纳。
本院认为,上诉人韩冰违反国家规定,对计算机信息系统中存储的数据和应用程序进行删除,造成计算机信息系统不能正常运行,其行为已构成破坏计算机信息系统罪,且后果特别严重,依法应予惩处。 一审法院根据韩冰犯罪的事实、犯罪的性质、情节及对于社会的危害程度所作出的判决,事实清楚,证据确实、充分,定罪及适用法律正确,量刑适当,审判程序合法,应予维持。据此,依照《中华人民共和国刑事诉讼法》第二百三十六条第一款第(一)项之规定,裁定如下:
驳回上诉,维持原判。
本裁定为终审裁定。
审 判 长 关 芳
审 判 员 鲍 艳
审 判 员 孙 燕
二〇二〇年十二月二十九日
法官助理 韩 峰
书 记 员 孟丹丹
========================================
此前,北京市海淀区人民法院在韩冰的一审刑事判决书中已指控被告人韩冰犯破坏信息系统罪,原审被告人韩冰不服,曾提出上诉。
参考链接:https://wenshu.court.gov.cn/website/wenshu/181107ANFZ0BXSK4/index.html?docId=ca312e28689b498a8ac1aca8009ac7fc
删库一时爽,但毁了自己的职业生涯,断送了自己的前程真心不值。
最后希望我们的程序员对于任何涉嫌违法的事件,都要保持一颗敬畏的心。
此文章转载自极客日报,如有不当联系删除。原文链接
收起阅读 »
分包内有页面中计算属性包含正则表达式,其他页面空白页,报错语法错误
分包内有页面中计算属性包含正则表达式,其他页面空白页,报错语法错误
分包内有页面中计算属性包含正则表达式,其他页面空白页,报错语法错误

动态插槽名问题讨论和 HACK 方案
前言
要在 uni-app 中使用动态 slot 名字,会比较麻烦,因为:在 MP-WEIXIN、APP-PLUS 都会有坑。
H5 和 小程序端
我们先说比较常用的 H5 和 MP-WEIXIN 好了:
定义:
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 -->
<slot :name="`tab:${item.key}`"></slot>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<slot name="tab:{{item.key}}"></slot>
<!-- #endif -->
使用 slot:
<view>
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 -->
<template v-for="item in list" :slot="`tab:${item.id}`">
<post-list :key="item.id" />
</template>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<template v-for="item in lits" slot="tab:professional:{{item.id}}">
<post-list :key="item.id" />
</template>
<!-- #endif -->
</view>
参考链接:https://ask.dcloud.net.cn/question/82506
APP 端
如果还要兼容 APP 端(vue 文件),则情况会变得稍微复杂一点,以上两种情况都不适用,先说结论:
- 不支持拿 data 的数据用于拼接动态 slot 名字
- 在 v-for 中要根据当前项的字段来拼接 slot 名字,则要将 key 指向
item
本身 - 如果不想 key 指向 item,则只能拿 v-for 的 index 来拼接 slot 名字
解决方案
**
也即,如果是上面的例子,需要改写为如下::
<swiper-item v-for="(item, index) in tabs" :key="item.id" class="swiper-item">
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 || APP-PLUS -->
<slot :name="`tab:${index}`"></slot>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<slot name="tab:{{index}}"></slot>
<!-- #endif -->
</swiper-item>
使用的时候:
<tab-swiper
ref="tabSwiper"
:tabs="list"
:current.sync="current"
:swiper-current.sync="swiperCurrent"
>
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifndef H5 || APP-PLUS -->
<template v-for="(item, index) in list" :slot="`tab:${index}`">
<post-list :key="item.id" :stagger="index % 2 !== 0" />
</template>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<template v-for="(item, index) in list" slot="tab:{{item.id}}">
<post-list :key="item.id" :stagger="index % 2 !== 0" />
</template>
<!-- #endif -->
</tab-swiper>
排查问题
下面开始排查问题,首先我们用以下代码测试用 data 的数据来作为 slot 名字:
<template>
<view>
testing dynamic slot
<slot :name="key"></slot>
<view :class="key">
test key value
</view>
</view>
</template>
<script>
export default {
data() {
return {
key: 'slot-1',
}
},
}
</script>
然后使用命令行或者 HBuilderx 编译 APP 端代码后,我们在 dist/dev/app-plus/app-view.js
搜索 testing dynamic slot
,然后可以看到以下代码:
可以看到,即便同样使用了 key 作为属性,但它们编译后的代码是不一样的,slot 节点直接使用 _vm._key
,而 view 节点变成了 _vm._$(2,'c')
,由此也推断出 uni-app 内部并没有对 slot 的 name
属性做额外处理,其实如果打印 _vm.key
的值, 会发现是空的:
所以结论一:不支持拿 data 的数据用于拼接动态 slot 名字。**
但直接拿 data 数据来拼接 slot 名字的情况比较少,更多时候是在 v-for 循环内部,所以我们再拿以下代码做测试:
<template>
<view>
testing dynamic slot
<view v-for="item in list" :key="item.id">
{{ item.name }}
<slot :name="`tab:${item.id}`"></slot>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{
id: 'a',
name: 'item-a',
},
{
id: 'b',
name: 'item-b',
},
{
id: 'c',
name: 'item-c',
},
],
}
},
}
</script>
以上代码在 APP 端依然是不正常的,我们看看编译后的代码:
代码看上去好像挺正常的是吧,但有一点很奇怪:为什么 key 直接指向了 item
?
果不其然,打印 item
发现这里的 item
并不是 v-for 中的那个 item
对象 ,而是用于指定 key
的值:
所以 item.id
依然是空的,实际上这里的 item
=== 外部的 item.id
。
既然如此,我们似乎得到两个解决方案:
- 将 v-for 的 key 直接指向 item 本身,使
item.id
能正常访问 - 拼接 slot 名字时不使用
item.id
而是使用item
结论是,方案一可行;方案二不可行。
至于为什么方案二不可行,我认为是 uni-app 的问题,因为打印出来的值是正确的。
结论二:在 v-for 中要根据当前项的字段来拼接 slot 名字,则要将 key 指向 item
本身。
但将对象类型作为 VNode 的 key 似乎并不好,所以提出最后一个解决方案,那就是通过 index 拼接 slot 名字:
<template>
<view>
testing dynamic slot
<view v-for="(item, index) in list" :key="item.id">
{{ item.name }}
<slot :name="`tab:${index}`"></slot>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{
id: 'a',
name: 'item-a',
},
{
id: 'b',
name: 'item-b',
},
{
id: 'c',
name: 'item-c',
},
],
}
},
}
</script>
以上代码能在 APP 端正常运行。
结论三:如果不想 key 指向 item,则只能拿 v-for 的 index 来拼接 slot 名字。
但毕竟是 HACK,终究原因是 uni-app 目前仍没有在 APP 端支持定义动态 slot ,可见相关的讨论:
- https://ask.dcloud.net.cn/question/95109
- 如何评价uni-app? - 蘑菇王的回答 - 知乎 https://www.zhihu.com/question/309490398/answer/1181409781
所以 uni-app 官方什么时候支持动态 slot 名字呢?
前言
要在 uni-app 中使用动态 slot 名字,会比较麻烦,因为:在 MP-WEIXIN、APP-PLUS 都会有坑。
H5 和 小程序端
我们先说比较常用的 H5 和 MP-WEIXIN 好了:
定义:
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 -->
<slot :name="`tab:${item.key}`"></slot>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<slot name="tab:{{item.key}}"></slot>
<!-- #endif -->
使用 slot:
<view>
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 -->
<template v-for="item in list" :slot="`tab:${item.id}`">
<post-list :key="item.id" />
</template>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<template v-for="item in lits" slot="tab:professional:{{item.id}}">
<post-list :key="item.id" />
</template>
<!-- #endif -->
</view>
参考链接:https://ask.dcloud.net.cn/question/82506
APP 端
如果还要兼容 APP 端(vue 文件),则情况会变得稍微复杂一点,以上两种情况都不适用,先说结论:
- 不支持拿 data 的数据用于拼接动态 slot 名字
- 在 v-for 中要根据当前项的字段来拼接 slot 名字,则要将 key 指向
item
本身 - 如果不想 key 指向 item,则只能拿 v-for 的 index 来拼接 slot 名字
解决方案
**
也即,如果是上面的例子,需要改写为如下::
<swiper-item v-for="(item, index) in tabs" :key="item.id" class="swiper-item">
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifdef H5 || APP-PLUS -->
<slot :name="`tab:${index}`"></slot>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<slot name="tab:{{index}}"></slot>
<!-- #endif -->
</swiper-item>
使用的时候:
<tab-swiper
ref="tabSwiper"
:tabs="list"
:current.sync="current"
:swiper-current.sync="swiperCurrent"
>
<!-- HACK: uni-app 处理动态 slot 名字不兼容,需要使用不同的语法 -->
<!-- #ifndef H5 || APP-PLUS -->
<template v-for="(item, index) in list" :slot="`tab:${index}`">
<post-list :key="item.id" :stagger="index % 2 !== 0" />
</template>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
<template v-for="(item, index) in list" slot="tab:{{item.id}}">
<post-list :key="item.id" :stagger="index % 2 !== 0" />
</template>
<!-- #endif -->
</tab-swiper>
排查问题
下面开始排查问题,首先我们用以下代码测试用 data 的数据来作为 slot 名字:
<template>
<view>
testing dynamic slot
<slot :name="key"></slot>
<view :class="key">
test key value
</view>
</view>
</template>
<script>
export default {
data() {
return {
key: 'slot-1',
}
},
}
</script>
然后使用命令行或者 HBuilderx 编译 APP 端代码后,我们在 dist/dev/app-plus/app-view.js
搜索 testing dynamic slot
,然后可以看到以下代码:
可以看到,即便同样使用了 key 作为属性,但它们编译后的代码是不一样的,slot 节点直接使用 _vm._key
,而 view 节点变成了 _vm._$(2,'c')
,由此也推断出 uni-app 内部并没有对 slot 的 name
属性做额外处理,其实如果打印 _vm.key
的值, 会发现是空的:
所以结论一:不支持拿 data 的数据用于拼接动态 slot 名字。**
但直接拿 data 数据来拼接 slot 名字的情况比较少,更多时候是在 v-for 循环内部,所以我们再拿以下代码做测试:
<template>
<view>
testing dynamic slot
<view v-for="item in list" :key="item.id">
{{ item.name }}
<slot :name="`tab:${item.id}`"></slot>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{
id: 'a',
name: 'item-a',
},
{
id: 'b',
name: 'item-b',
},
{
id: 'c',
name: 'item-c',
},
],
}
},
}
</script>
以上代码在 APP 端依然是不正常的,我们看看编译后的代码:
代码看上去好像挺正常的是吧,但有一点很奇怪:为什么 key 直接指向了 item
?
果不其然,打印 item
发现这里的 item
并不是 v-for 中的那个 item
对象 ,而是用于指定 key
的值:
所以 item.id
依然是空的,实际上这里的 item
=== 外部的 item.id
。
既然如此,我们似乎得到两个解决方案:
- 将 v-for 的 key 直接指向 item 本身,使
item.id
能正常访问 - 拼接 slot 名字时不使用
item.id
而是使用item
结论是,方案一可行;方案二不可行。
至于为什么方案二不可行,我认为是 uni-app 的问题,因为打印出来的值是正确的。
结论二:在 v-for 中要根据当前项的字段来拼接 slot 名字,则要将 key 指向 item
本身。
但将对象类型作为 VNode 的 key 似乎并不好,所以提出最后一个解决方案,那就是通过 index 拼接 slot 名字:
<template>
<view>
testing dynamic slot
<view v-for="(item, index) in list" :key="item.id">
{{ item.name }}
<slot :name="`tab:${index}`"></slot>
</view>
</view>
</template>
<script>
export default {
data() {
return {
list: [
{
id: 'a',
name: 'item-a',
},
{
id: 'b',
name: 'item-b',
},
{
id: 'c',
name: 'item-c',
},
],
}
},
}
</script>
以上代码能在 APP 端正常运行。
结论三:如果不想 key 指向 item,则只能拿 v-for 的 index 来拼接 slot 名字。
但毕竟是 HACK,终究原因是 uni-app 目前仍没有在 APP 端支持定义动态 slot ,可见相关的讨论:
- https://ask.dcloud.net.cn/question/95109
- 如何评价uni-app? - 蘑菇王的回答 - 知乎 https://www.zhihu.com/question/309490398/answer/1181409781
所以 uni-app 官方什么时候支持动态 slot 名字呢?
收起阅读 »
获取本机所有安装程序的包名和应用名(含解决JSBObject方案)
因为项目需要启动本机第三方应用,但由于管控软件已经启用,无法再随意安装程序获取本机所有安装程序的包名和应用名,于是就想到使用Nativejs或Java原生获取,下面是网上我查找到的获取包名和应用名的方法,我进行了整合
//Java实现代码
//获取PackageManager
PackageManager packageManager = context.getPackageManager();
//获取所有已安装程序的包信息
List <PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
// 遍历所有安装程序的包信息和应用程序名
ApplicationInfo applicationInfo = null;
if (packageInfos != null) {
for (int i = 0; i < packageInfos.size(); i++) {
String packName = packageInfos.get(i).packageName;
applicationInfo = packageManager.getApplicationInfo(packName, 0);
String appName=(String)((applicationInfo != null) ? packageManager.getApplicationLabel(applicationInfo) : "???");
Log.e(TAG, "PackageName:" + packName+",ApplicationName:"+appName);
}
}
那么如何转换为NJS代码呢了,我认真拜读了DCloud_App_Array老大写的入门教程https://ask.dcloud.net.cn/article/88,Nativejs示例https://ask.dcloud.net.cn/article/114和在插件市场的Nativejs的代码(重点是DCloud_App_Array写的),还有最推荐实践项目就是HbuilderX自带的Hello 5+的HTML5Plus规范演示,它基本演示绝大部分应用。但是对于简单的不需要类相互调用的还好实现,但遇到上面相互调用首先想到的是plus.android.importClass,然后通过类的.来调用,这点和https://ask.dcloud.net.cn/question/65208非常类似,但Java对象毕竟是非JS对象,所以经常出现JSBObject的问题,无法获取真实内容,该文章作者在回复中提到了invoke解决的,但没有实际代码,我和后面回复中一样急切需要解决方案,不过还好通过自己测试还是实现,同时对Nativejsy调用原生能力的认识也真正算是入门了,现在只要有java代码,而且Nativejs能实现的,就可以完成Java转NJS了。为了给自己留下记录,同时也帮助还在NativeJS迷茫路上的人们一点方向。
先看我实现上面功能的NJS代码,看你是否理解:
const main = plus.android.runtimeMainActivity();
let pManager = plus.android.invoke(main, 'getPackageManager');
let pInfo = plus.android.invoke(pManager, 'getInstalledPackages', 0);
let total = plus.android.invoke(pInfo, 'size');
let packName = '';
let appName = '';
let obj = null;
// 遍历获取包名和应用名称
for (let i = 0; i < total; i++) {
// 获取包名
packName = plus.android.getAttribute(plus.android.invoke(pInfo, 'get', i), 'packageName');
// 获取包名对应的应用名
obj = plus.android.invoke(pManager, 'getApplicationInfo', packName, 0);
appName = plus.android.invoke(pManager, 'getApplicationLabel', obj);
console.log(packName, appName);
}
我现在归纳总结Java转NJS代码几个要点:
1、plus.android.runtimeMainActivity(),起初我认识它就是普通Activity,其实它是Context,它是Html5+运行期环境主组件,用于处理与用户交互的各种事件,也是应用程序全局环境android.app.Activity的实现对象,是唯一的,生命周期是应用程序生命周期,可以完成所有有关程序的操作,至于Context重要可以百度.
2、plus.android.getAttribute和plus.android.setAttribute,获取或设置类或对象的属性,不再建议使用.来操作了,对于属性就建议使用它两个都可以完成了,毕竟android中java类还是比较复杂的,一个不好就访问了非静态常量,它两者则不存在这样问吧
3、plus.android.invoke调用类或对象的方法,支持静态或非静态,同样不建议使用.来操作了,原因同上。无论是importClass获取类对象(ClassObject)还是newObject获取的实例对象(InstanceObject)使用这种方法调用方法则没问题
4、遇到上面这种不断调用类的方法获取下一步操作的对象,甚至是能完.连续调用的,一定要使用我上面介绍的一个对象和三个函数来转换,其它都会非常容易出现失败的。同时要牢记为了思路清晰, 连续调用可分解为一个一个invoke调用,返回的对象就用let申明即可 ,这里有个 最大误区就是以为要和Java一样,先导入类再定义返回的对象,我开始也是在这里迷茫的,JS中不存在让它种写法啊,就是使用构造函数传递返回值相当于this来获取,结果经常返回null或JSBObject 后来想明白了,在JS中只有对象概念,才不管你是A类的对象还是B类的对象,只要是对象就是由属性和方法组成,上面转换代码你引入类就是多此一举了。
5、plus.android.importClass和plus.android.newObject什么时候使用呢?Java代码中调用类的静态方法或new获得的对象的代码就需要使用它们了,前者使用importClass,后者使用newObject。
总结:如果你理解我的代码,也掌握我提的五个要点,尤其是前面四个要点,任何Java代码转NJS都不再算复杂了
最后,还要是提供NativeJS还在入门的同学们,看完入门教程后,重点可参考Hello 5+的HTML5Plus规范来学习,它的示例代码非常多,毕竟是官方的模板,写法和技巧都值得学习。
因为项目需要启动本机第三方应用,但由于管控软件已经启用,无法再随意安装程序获取本机所有安装程序的包名和应用名,于是就想到使用Nativejs或Java原生获取,下面是网上我查找到的获取包名和应用名的方法,我进行了整合
//Java实现代码
//获取PackageManager
PackageManager packageManager = context.getPackageManager();
//获取所有已安装程序的包信息
List <PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
// 遍历所有安装程序的包信息和应用程序名
ApplicationInfo applicationInfo = null;
if (packageInfos != null) {
for (int i = 0; i < packageInfos.size(); i++) {
String packName = packageInfos.get(i).packageName;
applicationInfo = packageManager.getApplicationInfo(packName, 0);
String appName=(String)((applicationInfo != null) ? packageManager.getApplicationLabel(applicationInfo) : "???");
Log.e(TAG, "PackageName:" + packName+",ApplicationName:"+appName);
}
}
那么如何转换为NJS代码呢了,我认真拜读了DCloud_App_Array老大写的入门教程https://ask.dcloud.net.cn/article/88,Nativejs示例https://ask.dcloud.net.cn/article/114和在插件市场的Nativejs的代码(重点是DCloud_App_Array写的),还有最推荐实践项目就是HbuilderX自带的Hello 5+的HTML5Plus规范演示,它基本演示绝大部分应用。但是对于简单的不需要类相互调用的还好实现,但遇到上面相互调用首先想到的是plus.android.importClass,然后通过类的.来调用,这点和https://ask.dcloud.net.cn/question/65208非常类似,但Java对象毕竟是非JS对象,所以经常出现JSBObject的问题,无法获取真实内容,该文章作者在回复中提到了invoke解决的,但没有实际代码,我和后面回复中一样急切需要解决方案,不过还好通过自己测试还是实现,同时对Nativejsy调用原生能力的认识也真正算是入门了,现在只要有java代码,而且Nativejs能实现的,就可以完成Java转NJS了。为了给自己留下记录,同时也帮助还在NativeJS迷茫路上的人们一点方向。
先看我实现上面功能的NJS代码,看你是否理解:
const main = plus.android.runtimeMainActivity();
let pManager = plus.android.invoke(main, 'getPackageManager');
let pInfo = plus.android.invoke(pManager, 'getInstalledPackages', 0);
let total = plus.android.invoke(pInfo, 'size');
let packName = '';
let appName = '';
let obj = null;
// 遍历获取包名和应用名称
for (let i = 0; i < total; i++) {
// 获取包名
packName = plus.android.getAttribute(plus.android.invoke(pInfo, 'get', i), 'packageName');
// 获取包名对应的应用名
obj = plus.android.invoke(pManager, 'getApplicationInfo', packName, 0);
appName = plus.android.invoke(pManager, 'getApplicationLabel', obj);
console.log(packName, appName);
}
我现在归纳总结Java转NJS代码几个要点:
1、plus.android.runtimeMainActivity(),起初我认识它就是普通Activity,其实它是Context,它是Html5+运行期环境主组件,用于处理与用户交互的各种事件,也是应用程序全局环境android.app.Activity的实现对象,是唯一的,生命周期是应用程序生命周期,可以完成所有有关程序的操作,至于Context重要可以百度.
2、plus.android.getAttribute和plus.android.setAttribute,获取或设置类或对象的属性,不再建议使用.来操作了,对于属性就建议使用它两个都可以完成了,毕竟android中java类还是比较复杂的,一个不好就访问了非静态常量,它两者则不存在这样问吧
3、plus.android.invoke调用类或对象的方法,支持静态或非静态,同样不建议使用.来操作了,原因同上。无论是importClass获取类对象(ClassObject)还是newObject获取的实例对象(InstanceObject)使用这种方法调用方法则没问题
4、遇到上面这种不断调用类的方法获取下一步操作的对象,甚至是能完.连续调用的,一定要使用我上面介绍的一个对象和三个函数来转换,其它都会非常容易出现失败的。同时要牢记为了思路清晰, 连续调用可分解为一个一个invoke调用,返回的对象就用let申明即可 ,这里有个 最大误区就是以为要和Java一样,先导入类再定义返回的对象,我开始也是在这里迷茫的,JS中不存在让它种写法啊,就是使用构造函数传递返回值相当于this来获取,结果经常返回null或JSBObject 后来想明白了,在JS中只有对象概念,才不管你是A类的对象还是B类的对象,只要是对象就是由属性和方法组成,上面转换代码你引入类就是多此一举了。
5、plus.android.importClass和plus.android.newObject什么时候使用呢?Java代码中调用类的静态方法或new获得的对象的代码就需要使用它们了,前者使用importClass,后者使用newObject。
总结:如果你理解我的代码,也掌握我提的五个要点,尤其是前面四个要点,任何Java代码转NJS都不再算复杂了
最后,还要是提供NativeJS还在入门的同学们,看完入门教程后,重点可参考Hello 5+的HTML5Plus规范来学习,它的示例代码非常多,毕竟是官方的模板,写法和技巧都值得学习。
收起阅读 »
vue3.0版聊天室|vue3+vant3.x仿微信聊天+朋友圈
项目介绍
随着vue3越来越稳定了,加上Vite工具的推出,2021年再一次让vue.js变得很受开发者青睐。今天给大家分享的是基于vue3.0+有赞vant3技术建构开发的仿微信app界面聊天实战案例。
vue3.x mobile版聊天室|vue3仿微信聊天实战开发
Vue3ChatRoom项目支持发送消息/emoj表情图、图片/视频预览、网址查看、长按菜单、红包/朋友圈
等功能。
Vue3+vant-ui实现下拉刷新、左滑菜单功能。
Vue3+Image组件实现朋友圈及图片查看功能
实现技术
- 编辑器:VScode
- MVVM框架:vue3.0
- 状态管理:vuex4.x
- 地址路由:vue-router@4
- UI组件库:vant3.x (有赞移动端vue3.0组件库)
- 弹层组件:v3popup(基于vue3自定义弹窗组件)
- iconfont图标:阿里字体图标库
- 自定义顶部headerBar+底部tabBar组件
项目结构
vue3弹层组件
v3popup基于vue3.0开发的自定义弹框组件,贯穿于整个项目应用。
由于之前有过一篇分享文章,这里就不过多的介绍了。
vue3.0系列之自定义全局弹框组件|vue3移动端弹层组件
vue.config.js基本配置
用来进行一些基础的项目开发配置,可自定义webpack设置路径别名。
const path = require('path')
module.exports = {
// 基本路径
// publicPath: '/',
// 输出文件目录
// outputDir: 'dist',
// assetsDir: '',
// 环境配置
devServer: {
// host: 'localhost',
// port: 8080,
// 是否开启https
https: false,
// 编译完是否打开网页
open: false,
// 代理配置
// proxy: {
// '^/api': {
// target: '<url>',
// ws: true,
// changeOrigin: true
// },
// '^/foo': {
// target: '<other_url>'
// }
// }
},
// webpack配置
chainWebpack: config => {
// 配置路径别名
config.resolve.alias
.set('@', path.join(__dirname, 'src'))
.set('@assets', path.join(__dirname, 'src/assets'))
.set('@components', path.join(__dirname, 'src/components'))
.set('@views', path.join(__dirname, 'src/views'))
}
}
vue3公共页面配置
在main.js中配置一些公共引入。
import { createApp } from 'vue'
import App from './App.vue'
// 引入vuex和路由配置
import store from './store'
import router from './router'
// 引入js
import '@assets/js/fontSize'
// 引入公共组件
import Plugins from './plugins'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(Plugins)
app.mount('#app')
vue3表单验证
vue3.0中通过getCurrentInstance来获得上下文,可用来操作router或store。
<script>
import { reactive, inject, getCurrentInstance } from 'vue'
export default {
components: {},
setup() {
const { ctx } = getCurrentInstance()
const v3popup = inject('v3popup')
const utils = inject('utils')
const formObj = reactive({})
// ...
const handleSubmit = () => {
if(!formObj.tel){
Snackbar('手机号不能为空!')
}else if(!utils.checkTel(formObj.tel)){
Snackbar('手机号格式不正确!')
}else if(!formObj.pwd){
Snackbar('密码不能为空!')
}else{
ctx.$store.commit('SET_TOKEN', utils.setToken());
ctx.$store.commit('SET_USER', formObj.tel);
// ...
}
}
return {
formObj,
handleSubmit
}
}
}
</script>
vue3.0中使用全局钩子路由来实现登录拦截。
router.beforeEach((to, from, next) => {
const token = store.state.token
// 判断当前路由地址是否需要登录权限
if(to.meta.requireAuth) {
if(token) {
next()
}else {
// 未登录授权
V3Popup({
content: '还未登录授权!', position: 'top', popupStyle: 'background:#fa5151;color:#fff;', time: 2,
onEnd: () => {
next({ path: '/login' })
}
})
}
}else {
next()
}
})
vue3聊天模块
底部聊天编辑器采用公共分离模块,使用图文混排模式,可插入文字+emoj表情。
使用的是div可编辑器属性实现,大家感兴趣可以自己去试一试这个功能。
ok,以上就是基于vue3.x开发聊天实战项目的介绍,希望大家能喜欢!
Electron+Vue.js仿微信桌面端聊天实例|electron-vue客户端开发
链接:https://juejin.cn/post/6915310758859374606/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
项目介绍
随着vue3越来越稳定了,加上Vite工具的推出,2021年再一次让vue.js变得很受开发者青睐。今天给大家分享的是基于vue3.0+有赞vant3技术建构开发的仿微信app界面聊天实战案例。
vue3.x mobile版聊天室|vue3仿微信聊天实战开发
Vue3ChatRoom项目支持发送消息/emoj表情图、图片/视频预览、网址查看、长按菜单、红包/朋友圈
等功能。
Vue3+vant-ui实现下拉刷新、左滑菜单功能。
Vue3+Image组件实现朋友圈及图片查看功能
实现技术
- 编辑器:VScode
- MVVM框架:vue3.0
- 状态管理:vuex4.x
- 地址路由:vue-router@4
- UI组件库:vant3.x (有赞移动端vue3.0组件库)
- 弹层组件:v3popup(基于vue3自定义弹窗组件)
- iconfont图标:阿里字体图标库
- 自定义顶部headerBar+底部tabBar组件
项目结构
vue3弹层组件
v3popup基于vue3.0开发的自定义弹框组件,贯穿于整个项目应用。
由于之前有过一篇分享文章,这里就不过多的介绍了。
vue3.0系列之自定义全局弹框组件|vue3移动端弹层组件
vue.config.js基本配置
用来进行一些基础的项目开发配置,可自定义webpack设置路径别名。
const path = require('path')
module.exports = {
// 基本路径
// publicPath: '/',
// 输出文件目录
// outputDir: 'dist',
// assetsDir: '',
// 环境配置
devServer: {
// host: 'localhost',
// port: 8080,
// 是否开启https
https: false,
// 编译完是否打开网页
open: false,
// 代理配置
// proxy: {
// '^/api': {
// target: '<url>',
// ws: true,
// changeOrigin: true
// },
// '^/foo': {
// target: '<other_url>'
// }
// }
},
// webpack配置
chainWebpack: config => {
// 配置路径别名
config.resolve.alias
.set('@', path.join(__dirname, 'src'))
.set('@assets', path.join(__dirname, 'src/assets'))
.set('@components', path.join(__dirname, 'src/components'))
.set('@views', path.join(__dirname, 'src/views'))
}
}
vue3公共页面配置
在main.js中配置一些公共引入。
import { createApp } from 'vue'
import App from './App.vue'
// 引入vuex和路由配置
import store from './store'
import router from './router'
// 引入js
import '@assets/js/fontSize'
// 引入公共组件
import Plugins from './plugins'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(Plugins)
app.mount('#app')
vue3表单验证
vue3.0中通过getCurrentInstance来获得上下文,可用来操作router或store。
<script>
import { reactive, inject, getCurrentInstance } from 'vue'
export default {
components: {},
setup() {
const { ctx } = getCurrentInstance()
const v3popup = inject('v3popup')
const utils = inject('utils')
const formObj = reactive({})
// ...
const handleSubmit = () => {
if(!formObj.tel){
Snackbar('手机号不能为空!')
}else if(!utils.checkTel(formObj.tel)){
Snackbar('手机号格式不正确!')
}else if(!formObj.pwd){
Snackbar('密码不能为空!')
}else{
ctx.$store.commit('SET_TOKEN', utils.setToken());
ctx.$store.commit('SET_USER', formObj.tel);
// ...
}
}
return {
formObj,
handleSubmit
}
}
}
</script>
vue3.0中使用全局钩子路由来实现登录拦截。
router.beforeEach((to, from, next) => {
const token = store.state.token
// 判断当前路由地址是否需要登录权限
if(to.meta.requireAuth) {
if(token) {
next()
}else {
// 未登录授权
V3Popup({
content: '还未登录授权!', position: 'top', popupStyle: 'background:#fa5151;color:#fff;', time: 2,
onEnd: () => {
next({ path: '/login' })
}
})
}
}else {
next()
}
})
vue3聊天模块
底部聊天编辑器采用公共分离模块,使用图文混排模式,可插入文字+emoj表情。
使用的是div可编辑器属性实现,大家感兴趣可以自己去试一试这个功能。
ok,以上就是基于vue3.x开发聊天实战项目的介绍,希望大家能喜欢!
Electron+Vue.js仿微信桌面端聊天实例|electron-vue客户端开发
链接:https://juejin.cn/post/6915310758859374606/
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。