介绍Svelte是最近发布的一个前端框架。不同于react的vdom,Svelte在构建时使用静态分析创建DOM更新代码,搭配官网一目了然的新手教程,直观的用户体验,上手很快。在业务实践中,开始挖坑,总结内容。练完就可以直接上production了。React项目中通常使用ts+scss+svlete模板来提高业务逻辑开发效率,并使用样式模块来避免css命名重叠。在react中,可能会这样写0?this.props.data.map((v,i)=>{v}):empty...在苗条直接单文件组件//index.svelte{#ifdata.length>0}empty{:else}{#eachdataasv,i}- {v}
{/each}{/if}注意:1.任何svelte组件import的名称都必须大写,否则编译器不会将其识别为svelte组件。2.Importts类型声明必须是importtype...也是为了更好地区分.exportlet/const变量作为类似props的语法。目前,语法检查并不完善,有时会出现警告。与React不同,循环dom不强制检查key属性svelte单文件组件中的css自然会支持将className编译成style模块,不用担心css重名,但未使用css会被忽略和警告,不会被打包。(这个就很奇怪了,如果父组件和子组件要互相覆盖对方的cssclassname,那就比较麻烦了,这时候纯css的思路就坏了,我们只能改js的思路,实现了通过props。)状态管理组件中的状态没什么好说的。只是临时变量的穿梭。本文只讨论store的用法。为了让svelte的状态管理有redux的味道,我在实践中使用了如下写法,不喜勿喷://store.tsimport{writable}from'svelte/store';//声明初始小状态initState={loading:false,read:0,}conststate=writable(initState);const{subscribe,set,update}=state;//可能用到的resetconstreset=()=>set(initState);//mounted方法会在组件中调用constmounted=async()=>{updateLoadStart();const{data,error}=awaitserver.getPageData();!error&&awaitupdateReaded(data);updateLoadEnd();}updateLoadStart=()=>whenonMountupdate((prevState)=>{return{...prevState,loading:true}})...可以像这样导入和使用组件:{$state.readed}中实践中可以大胆的拆分和命名比如类vue的Mountedmethodcomputedatamanagement的命名,比如rematch-likeselectloading.effects组合,具体看之前框架的习惯,请注意:目前没有devtool浏览器插件查看和修改状态,反正我安装了一个svelte插件没试过,说不定很快就会发布。目前只能通过{@debug$state}来观察状态变化和dom交互。看到https://css-tricks.com/lazy-l...一步一步教写一个图片懒加载的组件。真不错,解决了兼容性问题,就可以上线了。其次,我尝试了官方文档的motion/transition/animate,可以轻松实现一些常用的动画功能,比如动画折叠展开,轮播滚动等。这里就不贴代码了,跟着文档看基本不难。需要注意的地方:1、on:click的直接透传事件貌似只作用于组件的根元素,还是要在on:click={()=>dispatch('click')}中使用子元素向上emit2.html标签验证的方式其实认为href="javascript:"不是合法链接,必须在上一行注释3.样式写法习惯class=""style=""比react的className=""style={}更接近vue4.boundref记得在onDestory的时候销毁打包。官方rollup打包配置太简单,不兼容es5。在网上看到有其他同学把svelte重新编译成了es5,也很神奇。其实只要改一下官方的rollup配置就可以了。实践中,我可以愉快地将ts编译成es5。简单说一下几个重点,最后放出配置文件供大家参考,少走弯路和坑。1.打包资源加上hash...output:{...entryFileNames:"bundle.[hash].js"}向后兼容">1%,notdead"为了兼容连arrow都不支持的浏览器语法,选择一个,文件大小会翻倍,一个页面差不多200kgzip60k">5%,notdead"这个比100k+gzip30k+3小很多。使用“rollup-plugin-serve”替换官方手写的serve!production&&serve({contentBase:"dist",port:5000})sveltecssplushashcss:(css)=>{consthash=crypto.createHash("md5").update("bundle"+css.code).digest("hex");css.write("bundle."+hash.slice(0,8)+".css",!production);}当然如果想让postcssautofixer进一步处理,网上还有其他答案5.使用@rollup/plugin-html根据模板替换hash文件,生成manifesthtml({dest:"dist",fileName:"index.html",template:async({bundle})=>{letbundleFileNames=Object.keys(bundle);fs.writeFile('dist/asset-manifest.json',JSON.stringify(bundleFileNames.reduce((assetMap,fileName)=>{assetMap[fileName.replace(/\.\w+\./,'.')]=fileName;returnassetMap},{}),null,"\t"),"utf8");returnbundleFileNames.reduce((code,fileName)=>code.replace(fileName.replace(/\.\w+\./,'.'),fileName),awaitfs.readFile("public/index.html","utf8"));},})rolllup.config.js个人感觉感觉svelte体验中模板语法和unitcomponent组件的思想更接近Vue,但是没有完全遵循指令规范(比如循环判断),增加了简化但实用的动画和状态在管理和性能方面,它比React好一点点,小包体积有很大的优势。期待未来在工具链等开发体验上会有新的突破。框架比较?https://medium.com/@d_kzlv/yeah-holy-wars-i-like-that-1406eb291331发现大家对medium的看法不一样,随便看看