专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

感受Vue3的魔法力量

  近半年有幸参与了一个创新项目,由于没有任何历史包袱,所以选择了Vue3技术栈,总体来说感受如下:
  setup语法糖scriptsetuplangts摆脱了书写声明式的代码,用起来很流畅,提升不少效率
  可以通过CompositionAPI(组合式API)封装可复用逻辑,将UI和逻辑分离,提高复用性,view层代码展示更清晰
  和Vue3更搭配的状态管理库Pinia,少去了很多配置,使用起来更便捷
  构建工具Vite,基于ESM和Rollup,省去本地开发时的编译步骤,但是build打包时还是会编译(考虑到兼容性)
  必备VSCode插件Volar,支持Vue3内置API的TS类型推断,但是不兼容Vue2,如果需要在Vue2和Vue3项目中切换,比较麻烦
  当然也遇到一些问题,最典型的就是响应式相关的问题响应式篇
  本篇主要借助watch函数,理解ref、reactive等响应式数据状态,有兴趣的同学可以查看Vue3源代码部分加深理解,
  watch数据源可以是ref(包括计算属性)、响应式对象、getter函数、或多个数据源组成的数组import{ref,reactive,watch,nextTick}fromvue定义4种响应式数据状态1、ref值为基本类型constsimplePersonref(张三)2、ref值为引用类型,等价于:person。valuereactive({name:张三})constpersonref({name:张三})3、ref值包含嵌套的引用类型,等价于:complexPerson。valuereactive({name:张三,info:{age:18}})constcomplexPersonref({name:张三,info:{age:18}})4、reactiveconstreactivePersonreactive({name:张三,info:{age:18}})改变属性,观察以下不同情景下的监听结果nextTick((){simplePerson。value李四person。value。name李四complexPerson。value。info。age20reactivePerson。info。age22})情景一:数据源为RefImplwatch(simplePerson,(newVal){console。log(newVal)输出:李四})情景二:数据源为张三watch(simplePerson。value,(newVal){console。log(newVal)非法数据源,监听不到且控制台告警})情景三:数据源为RefImpl,但是。value才是响应式对象,所以要加deepwatch(person,(newVal){console。log(newVal)输出:{name:李四}},{deep:true必须设置,否则监听不到内部变化})情景四:数据源为响应式对象watch(person。value,(newVal){console。log(newVal)输出:{name:李四}})情景五:数据源为张三watch(person。value。name,(newVal){console。log(newVal)非法数据源,监听不到且控制台告警})情景六:数据源为getter函数,返回基本类型watch(()person。value。name,(newVal){console。log(newVal)输出:李四})情景七:数据源为响应式对象(在Vue3中状态都是默认深层响应式的)watch(complexPerson。value。info,(newVal,oldVal){console。log(newVal)输出:Proxy{age:20}console。log(newValoldVal)输出:true})情景八:数据源为getter函数,返回响应式对象watch(()complexPerson。value。info,(newVal){console。log(newVal)除非设置deep:true或info属性被整体替换,否则监听不到})情景九:数据源为响应式对象watch(reactivePerson,(newVal){console。log(newVal)不设置deep:true也可以监听到})
  总结:
  1。在Vue3中状态都是默认深层响应式的(情景七),嵌套的引用类型在取值(get)时一定是返回Proxy响应式对象
  2。watch数据源为响应式对象时(情景四、七、九),会隐式的创建一个深层侦听器,不需要再显示设置deep:true
  3。情景三和情景八两种情况下,必须显示设置deep:true,强制转换为深层侦听器
  4。情景五和情景七对比下,虽然写法完全相同,但是如果属性值为基本类型时是监听不到的,尤其是ts类型声明为any时,ide也不会提示告警,导致排查问题比较费力
  5。所以精确的ts类型声明很重要,否则经常会出现莫名其妙的watch不生效的问题
  6。ref值为基本类型时通过getset拦截实现响应式;ref值为引用类型时通过将。value属性转换为reactive响应式对象实现;
  7。deep会影响性能,而reactive会隐式的设置deep:true,所以只有明确状态数据结构比较简单且数据量不大时使用reactive,其他一律使用refProps篇设置默认值typeProps{placeholder?:stringmodelValue:stringmultiple?:boolean}constpropswithDefaults(definePropsProps(),{placeholder:请选择,multiple:false,})双向绑定(多个值)
  自定义组件FieldSelector。vuetypeProps{businessTableUuid:stringbusinessTableFieldUuid?:string}constpropsdefinePropsProps()constemitsdefineEmits(〔update:businessTableUuid,update:businessTableFieldUuid,〕)constbusinessTableUuidref()constbusinessTableFieldUuidref()props。businessTableUuid、props。businessTableFieldUuid转为本地状态,此处省略表切换consttableChange(businessTableUuid:string){emits(update:businessTableUuid,businessTableUuid)emits(update:businessTableFieldUuid,)businessTableFieldUuid。value}字段切换constfieldChange(businessTableFieldUuid:string){emits(update:businessTableFieldUuid,businessTableFieldUuid)}
  使用组件templateFieldSelectorvmodel:businesstableuuidstringFilter。businessTableUuidvmodel:businesstablefielduuidstringFilter。businessTableFieldUuidtemplate单向数据流
  1。大部分情况下应该遵循【单向数据流】原则,禁止子组件直接修改props,否则复杂应用下的数据流将变得混乱,极易出现bug且难排查
  2。直接修改props会有告警,但是如果props是引用类型,修改props内部值将不会有告警提示,因此应该有团队约定(第5条除外)
  3。如果props为引用类型,赋值到子组件状态时,需要解除引用(第5条除外)
  4。复杂的逻辑,可以将状态以及修改状态的方法,封装成自定义hooks或者提升到store内部,避免props的层层传递与修改
  5。一些父子组件本就紧密耦合的场景下,可以允许修改props内部的值,可以减少很多复杂度和工作量(需要团队约定固定场景)逻辑UI解耦篇
  利用Vue3的Composition组合式API,将某种逻辑涉及到的状态,以及修改状态的方法封装成一个自定义hook,将组件中的逻辑解耦,这样即使UI有不同的形态或者调整,只要逻辑不变,就可以复用逻辑。下面是本项目中涉及的一个真实案例逻辑树组件,UI有2种形态且可以相互转化。
  hooks部分的代码:useDynamicTree。tsimport{ref}fromvueimport{nanoid}fromnanoidexporttypeTreeNode{id?:stringpid:stringnodeUuid?:stringpartentUuid?:stringnodeType:stringnodeValue?:anylogicValue?:anychildren:TreeNode〔〕level?:number}exportconstuseDynamicTree(root?:TreeNode){consttreerefTreeNode〔〕(root?〔root〕:〔〕)constlevelref(0)添加节点constadd(node:TreeNode,pid:stringroot):boolean{添加根节点if(pid){tree。value〔node〕returntrue}level。value0constpNodefind(tree。value,pid)if(!pNode)returnfalse嵌套关系不能超过3层if(pNode。levelpNode。level2)returnfalseif(!node。id){node。idnanoid()}if(pNode。nodeTypeoperator){pNode。children。push(node)}else{如果父节点不是关系节点,则构建新的关系节点constcurrentJSON。parse(JSON。stringify(pNode))current。pidpidcurrent。idnanoid()Object。assign(pNode,{nodeType:operator,nodeValue:and,重置回显信息logicValue:undefined,nodeUuid:undefined,parentUuid:undefined,children:〔current,node〕,})}returntrue}删除节点constremove(id:string){constnodefind(tree。value,id)if(!node)return根节点处理if(node。pid){tree。value〔〕return}constpNodefind(tree。value,node。pid)if(!pNode)returnconstindexpNode。children。findIndex((item)item。idid)if(index1)returnpNode。children。splice(index,1)if(pNode。children。length1){如果只剩下一个节点,则替换父节点(关系节点)const〔one〕pNode。childrenObject。assign(pNode,{。。。one,},{pid:pNode。pid,},)if(pNode。pid){pNode。idroot}}}切换逻辑关系:且或consttoggleOperator(id:string){constnodefind(tree。value,id)if(!node)returnif(node。nodeType!operator)returnnode。nodeValuenode。nodeValueand?or:and}查找节点constfind(node:TreeNode〔〕,id:string):TreeNodeundefined{console。log(node,id)for(leti0;inode。length;i){if(node〔i〕。idid){Object。assign(node〔i〕,{level:level。value,})returnnode〔i〕}if(node〔i〕。children?。length0){level。value1constresultfind(node〔i〕。children,id)if(result){returnresult}level。value1}}returnundefined}提供遍历节点方法,支持回调constdfs(node:TreeNode〔〕,callback:(node:TreeNode)void){for(leti0;inode。length;i){callback(node〔i〕)if(node〔i〕。children?。length0){dfs(node〔i〕。children,callback)}}}return{tree,add,remove,toggleOperator,dfs,}}
  在不同组件中使用(UI1UI2组件为递归组件,内部实现不再展开)组件1templateUI1:logiclogic:onaddhandleAdd:onremovehandleRemove:toggleoperatortoggleOperatorUI1template组件2templateUI2:logiclogic:onaddhandleAdd:onremovehandleRemove:toggleoperatortoggleOperatorUI2templatePinia状态管理篇
  将复杂逻辑的状态以及修改状态的方法提升到store内部管理,可以避免props的层层传递,减少props复杂度,状态管理更清晰
  定义一个store(非声明式):User。tsimport{computed,reactive}fromvueimport{defineStore}frompiniatypeUserInfo{userName:stringrealName:stringheadImg:stringorganizationFullName:string}exportconstuseUserStoredefineStore(user,(){constuserInforeactiveUserInfo({userName:,realName:,headImg:,organizationFullName:})constfullNamecomputed((){return{userInfo。userName}〔{userInfo。realName}〕})constsetUserInfo(info:UserInfo){Object。assgin(userInfo,{。。。info})}return{userInfo,fullName,setUserInfo}})
  在组件中使用templateelspaceelavatar:size60:srcuserInfo。headImg?userInfo。headImg:avatarelavatarp你好,{{userInfo。realName}},欢迎回来pstylefontsize:14px{{userInfo。organizationFullName}}elspacetemplate
  作者:京东科技牛至伟
  内容来源:京东云开发者社区

高坪机场新开2条航线南充新闻网讯(南充日报社全媒体记者罗虹)3月20日,记者从南充高坪机场获悉,南充高坪机场发布夏航季航班计划,不仅新开南充北海南充海口2条航线,还将增补恢复部分航班,优化航班时刻。在珠海的东澳岛(下)其实也不是啥大不了的事2023年3月17日1332分1442分,整整1小时10分,从将军石林到格力东澳大酒店(南沙湾)这段沿着海岸线盘旋的山路上,只有一个人在烈日下徒步前不见古人,全球顶级迪拜七星酒店没有之一,最贵的皇家套房长期被中国人霸占近日,英国记者应酒店之邀,揭开世界顶级豪华酒店的神秘面纱。这套复式皇家套房可谓金碧辉煌。楼梯上铺着豹纹地毯,走在这样的房间里很容易忘记自己的身份。8,395平方英尺的皇家套房专为皇泰国最近怎么了?中国游客纷纷逃离避雷,泰国不再是第一选择泰国作为东南亚最受欢迎的旅游胜地之一,每年吸引了数以百万计的国际游客前来游玩。然而,旅游安全问题一直是游客们十分重视的问题,尤其是最近全球疫情的影响和安全局势的不稳定,使得许多游客突发!就在刚刚,又一女官员被查,涉嫌严重违纪违法有句话说的好,权力是把双刃剑运用得好可以造福于民如果滥用则会滋生腐败,贻害无穷,展现的淋漓尽致,贪官腐败严重损害了人民的利益,正因为如此国家才会大力打击官场腐败的现象,必须加强对权江西金溪县政协学习贯彻全国两会精神注重四个结合全国两会召开后,江西省金溪县政协把深入学习贯彻全国两会精神作为当前和今后一个时期的首要政治任务,通过四个结合,切实把全国两会精神融入到谋划工作推进落实全过程,以高水平履职助力高质量中信银行哨兵反欺诈系统保护被诈资金超亿元近年来,中信银行践行金融为民理念,持续构建电信诈骗防范体系,深层次筑牢金融反诈防线,打击电信网络诈骗切实保护消费者权益,有力保障了客户资金安全。联防反诈警银协作成果显著针对反诈的难狂飙又至!陈戌源落马40天足协再地震,专案组发力两大高官疑落马陈戌源上月初被查后,中国足协内部一直风平浪静,让人以为这波反腐风潮已经过去了。但最近两天,足协又开始了新一轮地震,诸多媒体人暗示,竞赛部部长黄松已出事,纪律委员会主任王小平也被怀疑金子总会发光,敬道参与赌球,中国足球上演狂飙头条创作挑战赛金敬道金敬道版高启强演的一点也不比张颂文版高企强差,甚至是有过之而不及。2023年注定是中国足球壮士断腕整治的元年,国足主帅李铁,足协主席陈戍源,足协秘书长刘奕,俱乐ChatGPT评中国境内一生中必玩的十大景点,大家觉得客观么?以下是中国境内一生中必玩的十大景点长城作为中国的标志性建筑之一,长城是一个跨度多个朝代的伟大工程,值得一游。故宫位于北京市中心的故宫,是明清两朝的皇宫,有着丰富的历史和文化遗产。兵全国中成药集采即将启动,专家吸引有实力有研发能力的企业进入集采(人民日报健康客户端记者徐诗瑜)据全国中成药联合采购办公室发布的关于召开中成药联盟采购企业沟通会的通知,为推进全国中成药联盟采购工作,于3月23日召开企业沟通会,介绍全国中成药联盟
许昌实施扩大内需战略推动经济高质量发展高质量发展是全面建设社会主义现代化国家的首要任务,要坚持以推动高质量发展为主题,把实施扩大内需战略同深化供给侧结构性改革有机结合起来,增强国内大循环内生动力和可靠性,提升国际循环质我的世界22w44a你敢信么?末影龙刷怪蛋,无限熔岩加入mcMinecraft本周快照22w44a一个注定载入史册的快照版本,末影龙刷怪蛋加入到了我的世界中,mc玩家看到眼睛都直了!一加入了末影龙凋灵BOSS级刷怪蛋!(爷青结)Minecr收费的配音软件千篇一律,好用的配音软件独领风骚,懂我意思吧?相信大家在挑选配音软件时,都会遇到一个问题,那就是不知道选哪个好,好像这个不错,用着用着又收费或者不好用,又要换下一个,找软件是个比较浪费时间的,而又心累的过程,还有就是容易被忽悠击败小米和OPPO,蝉联中端机性能第一名,双11仅需1599元起手游厂商们想要获取更大的利益,就不能让手游的门槛太高,如果这个手游需要极强的性能才能带得动,那么注定玩这个游戏的玩家少,而这就是目前手游的现状,对手机性能的要求其实并不高,因此手机美媒华为开始和美企说再见了大家都知道,三年前华为手机业务之所以一蹶不振,有三方面的原因,分别是谷歌停止向华为提供GMS服务台积电不能为海思代工生产麒麟芯片和美企无法继续向华为提供5G射频等元器件。要知道,没1500元左右性能最强的五款手机流畅体验比肩旗舰,当下换机首选随着科技产品的迭代和新鲜资讯的吸收,低性能的手机已经无法满足日常所需,而在有限的预算里,处理器的提升往往是巨大的,目前1500这个价位段里,虽然大部分都是中低端处理器,但依旧有很多资本主义的马老师,也是马老师文蔡垒磊马老师收购twitter的事情大家都清楚,前段时间的欲拒还迎,在今天看来,都成了一种谈判策略。那么马老师收了twitter后的第一件事是什么?开人,开很多很多的人。twit马斯克全球性野心马斯克为何要拿出440亿美元购买社交网络推特?从经济角度看,推特的营业额与另一家社交网络脸书比微不足道,它比后者少25倍。当马斯克宣布要买下推特时,普遍很震惊。为什么全球首富要掌控白皮书北斗系统是中国首个实现全球组网运行的航天系统新华社北京11月4日电(记者温竞华胡喆)国务院新闻办公室4日发布的新时代的中国北斗白皮书说,北斗系统星间星地一体组网,是中国首个实现全球组网运行的航天系统,显著提升了中国航天科研生(国际)埃及举办第五届金字塔国际跳伞节当日,第五届金字塔国际跳伞节在埃及首都开罗附近的吉萨金字塔景区开幕,吸引了来自世界各地的100余名专业跳伞运动员参加。11月2日,在埃及吉萨金字塔景区,人们拍摄运动员跳伞表演。新华来中国旅游的外国游客中北欧人很少,是什么原因?近年来,中国的国际实力不断提高,中国在国际上的地位在全世界也是有目共睹的。许多发达的国家都想来中国参观中国的名胜古迹,了解中国的文化习俗,尤其是西方欧美国家,他们纷纷来到中国。这些
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网