当前位置: 首页 > Web前端 > HTML

前端进阶——微信小程序基础

时间:2023-03-28 17:56:52 HTML

什么是小程序?小程序页面本质上是一个网页,使用混合技术进行native和web的混合开发。Hybrid技术使用webview进行渲染,使用jsbridge作为web和native数据交互的桥梁,使用的技术栈和网页开发使用的是一样的。不同的是,使用的是HTML、CSS、JS:不支持window、document等浏览器API,只能使用微信提供的API。微信小程序的发展历程微信小程序形态小程序更像是公众号开发的升级早期,微信通过SDK增强了开发者开发公众号网页的能力。很好地贯彻了“轻量级APP”开发标准。最初,微信小程序定义了一套“标准”。最初的框架没有组件,没有npm,与web生态严重脱节。小程序开通仅对开通三方业务和商户涌入小程序业务->平台应用如:支付宝小程序、百度、淘宝、360、快应用等类似结构和框架不是从技术角度考虑的,而是想尽可能利用微信小程序的优势,让开发者更快的放到自己的平台上。微信小程序框架目录结构包含各个页面文件夹后缀为wxml、wxss、js、json的文件分别是模板文件、样式文件、js脚本文件、json页面配置文件。目录最外层有全局app.js、app.json、app.wxss小程序类型应用技术选择技术方案渲染页面使用纯客户端原生技术渲染使用纯web技术渲染使用客户端原生技术对比混合开发(hybrid)渲染方案结合web技术开发门槛:web门槛低,像RN这样的原生框架支持体验:原生体验比web好很多,hybrid更接近原生体验版本更新比web有一定程度:web支持在线更新。如果小程序是原生开发的,需要封装到微信中进行审核控制和安全:web可以跳转或改变页面内容,存在一些不可控因素和安全隐患。确定小程序宿主环境的方案是微信等手机APP使用纯客户端原生技术编写小程序,所以每次都需要将小程序代码和手机APP代码一起发布。因此,这种解决方案是不可取的。Web支持有一份资源包放在云端,下载到本地,动态执行后即可呈现界面。但是纯Web技术在一些复杂的交互中可能会出现性能问题。因此,这种解决方案是不可取的。在Web技术中,UI渲染和脚本执行都是在单线程中执行的,这很容易导致一些逻辑任务抢占UI渲染资源。两者结合渲染小程序的混合技术采用了一种近似于web方式开发,可以实现在线更新代码扩展web的能力,比如输入框组件(input,textarea)有更好的控制键盘的能力并且体验更好,同时减少webview的渲染工作,使用客户端原生渲染内置的一些复杂组件可以提供更好的性能。双线程模型小程序的渲染层和逻辑层分为两个线程。管理视图层(WebView)->WebView用于渲染界面渲染相关的任务都在WebView线程中执行,通过逻辑层代码区控制渲染哪些界面。一个小程序中有多个接口,所以视图层有多个WebView线程。逻辑层(AppService)->JsCore线程运行js脚本,创建一个单独的线程执行js代码。这里的所有执行都与小程序的业务逻辑有关。代码负责逻辑处理、数据请求、接口调用等。JSBridge:上层开发与Native(系统层)的桥梁,让小程序可以通过API使用原生功能,部分组件为原生组件,从而获得良好的体验设计目的:出于控制和安全问题,防止开发者使用浏览器的window对象、跳转页面、操作DOM、动态执行脚本等开放接口。使用沙箱环境,提供纯javascript解释执行环境客户端系统,PC运行时使用javascript引擎执行js代码ios:使用ios提供的Js核心框架,在ios系统中执行js代码Android:使用腾讯提供的JsCorex5核心在Android系统中执行js代码:js逻辑代码在单独的线程中运行。WebView线程不能直接操作DOM。开发人员如何动态更改界面DOM?更新是通过简单的数据通信实现的。逻辑层和视图层之间的通信由native(微信客户端)提供中转,逻辑层发送的网络请求也通过native进行转发。图LR对象模拟DOM树-->比较两个虚拟DOM树的差异-->用差异更新真实的DOM树。在渲染层将wxml转化为对应的js对象。当逻辑层数据发生变化时,通过宿主环境提供的setData方法将数据从逻辑层传递给native,再转发给渲染层。比对后更新真正的dom内容。总结:这部分类似于mvvm框架,改造ast树,通过native创建虚拟dom,并使用setData方法更新数据,然后使用native做diff更新真实的dom树事件处理微信已经完成特殊处理,拦截所有事件抛给逻辑层交由js处理代码描述交互事件视图层用户交互触发事件原生拦截抛给逻辑层逻辑层接收回调处理事件。事件的派发处理包括事件捕获和冒泡:交互过程就像上述数据驱动的视图变化。原生拦截后抛给逻辑层,通过js响应事件。setData修改数据,虚拟dom变化,nativediff更新真实dom。跑机冷启动:用户第一次打开或小程序被微信主动销毁后再次打开(当手机系统在五秒内有超过2次内存报警时,小程序会主动销毁),此时小程序需要重新加载的时间热启动:加入打开某个小程序的用户,在一定时间内(目前为五分钟)再次打开小程序(小程序前后切换).重启注意小程序没有重启的概念。相比小程序原生的语法,现在小程序的框架可以实现前端工程化,在前端生态植入一些概念,比如状态管理,CLI工程化等,前端能力基本可以复用在小程序中,比如statemanagement,currymanagementcomponentstate,TS等增强框架指的是小程序引入npm后,更多开放能力带来的好处。以微信小程序为例,腾讯开源了omi框架,整体保留了小程序已有的语法,并在其之上进行了扩展增强,比如引入了computedhook,比如直接通过this。store.data.logs[0]='changed'修改状态,将微信小程序完全转为vue。转换框架可以是rax、taro、uniapp等多端框架,让开发者几乎不需要体验小程序原生语法,更大限度对接前端已有生态。只是最终构建的产品是小程序代码。这些框架实际上是通过1:1的转换乘积转换成相应的小程序代码。图LR开发者代码-->AST树-->新AST树-->小程序代码的编译期优势运行时性能损耗低目标代码少,开发者写的就是运行时得到的,编译时优化:比如框架会给开发者更多的语法支持和默认的性能优化处理,比如如避免多次setData,或长列表优化等缺点。语法限制高:需要完全匹配开发者在模板部分使用的所有语法,语法受限。由于1:1的编译转换,开发者还是要遵循小程序的开发规范,比如一个文件只能定义一个组件。与编译时相比,运行时最大的优势在于几乎可以不受语法约束地完成代码编写。优点:没有语法限制。建议通读文档的指南、框架、组件、API和工具。基本内容示例代码github地址:https://github.com/wechat-miniprogram/miniprogram-demo基本官方文档:https://developers。weixin.qq.com/miniprogram/dev/framework/基础核心图A【小程序冷启动】--启动-->B[前台]--切换到后台-->C[后台]--五秒后-->D[suspend]--30分钟后-->E[destroyapplet]C--切换到前台-->BD--切换到前台-->B更新机制启动时同步更新,定期检查版本小程序的长时间未更新使用异步更新在小程序开始打开时发现新版本,异步下载,下次冷启动时加载新版本开发者手动更新wx.getUpdateManager代码注入上-demandinjection:"lazyCodeLoading":"requiredComponents"打包时注入的配置路径:在开启“按需注入”特性的前提下,指定部分自定义组件不在小程序启动时注入,仅在小程序启动时注入实际上是渲染的。在需要渲染但注入完成前使用占位符组件显示分包加载原理声明分包后,打包分包配置路径,分包配置路径外的目录会被爆成app(主包)和app(mainpackage)也可以有自己的pages(就是最外层的pages字段)子包的根目录不能是另一个子包中的子目录。tabBar页面必须在app中独立分包(主包)。,App不一定是注册过的,所以getApp()不一定能获取到App对象基础库2.2.4版本启动getApp支持[allowDefault]参数,当App未定义时返回默认实现。当加载主包并注册App时,默认实现中定义的属性会被覆盖并合并到真正的App中来调试widget程序使用vconsole打开sourceMap配置项的实时日志:rewrite日志,使用wx.getRealtimeLogManager封装,在运行后台“开发->开发管理->运维中心->实时日志”查看errno:开发者抛出异常,为API的cberr判断状态码,展示兼容版本的比较constversion=wx.getSystemInfoSync().SKDVersionif(compareVersion(version,'1.1.0')>=0){wx.openBluetoothAdapter()}else{wx.showModal({title:'提示',content:'当前微信版本过低无法使用该功能,请升级到最新微信版本再试'})}判断是否API存在if(wx.openBluetoothAdapter){wx.openBluetoothAdater()}else{wx.showModal({title:'Prompt',content:'当前微信版本太低无法使用该功能,请升级到最新微信版本然后重试'})}wx.canIUse判断当前环境是否可以使用api,jsdk的api权限判断类似于wx.showModal({success:function(res){if(wx.canIUse('showModal.success.cancel')){console.log(res.cancel)}}})最低基础库版本运行后台设置最低基础库版本框架微信原生小程序框架官方文档小程序配置全局配置页面配置sitemap配置框架接口App:必须调用在app.js中只有一些全局生命周期可以调用一次getApp:App页面中外部获取数据的方式Pagedata生命周期中部分页面getCurrentPages:获取当前页面栈,可以获取当前页面信息,比如路由,也可以使用该方法实现跨页赋值//跨页赋值letpages=getCurrentPages()//当前页面栈letprePage=pages[pages.length-2]//上一页prevPage.setData({//直接复制到上一页})//跳转后自动刷新wx.switchTab({url:'../index/index',success:function(e){constpage=getCurrentPages().pop();//当前页if(page==undefined||page==null)return;page.onLoad();//或其他操作}})Router页面router有switchTabreLaunchredirectTonavigateTonavigateBack五个方法和wx对象的五个同名方法switchTabreLaunchredirectTonavigateBack功能是一样的;唯一不同的是,调用页面路由中的方法时,相对路径总是相对于this引用的页面或自定义组件Page({wxNavAction:function(){wx.navigateTo({url:'./new-page'})},routerNavAction:function(){this.pageRouter.navigateTo({url:'./new-page'})}})自定义组件Component:在微信开发工具中右键新建组件会自动创建自定义组件模板,整体包裹在一个Component对象中。Behavior:行为是组件之间代码共享的特性,类似于一些编程语言中的'mixin'或者'traits',它可以将行为模块的代码混合到组件代码中,一般是提取逻辑代码和一些属性//官方示例module.exports=Behavior({behaviors:[],properties:{myBehaviorProperty:{type:String}},data:{myBehaviorData:{}},attached:function(){},methods:{myBehaviorMethod:function(){}}})基本用法,先新建一个组件,然后使用组件自动将带的behaviors属性混入到behavior模块中,类似于vue的mixins//新建一个组件属性:{{myBehaviorProperty}}---{{myCompProperty}}数据:{{myBehaviorData}}---{{myCompData}}触发行为的自定义方法触发组件的自定义方法//组件级jsimpo来自'./testBehavior'C的rttestBehavioromponent({behaviors:[testBehavior],properties:{myCompProperty:{type:String,value:''}},data:{myCompData:'myCompData'},created:function(){控制台.log('[my-component]-created')},attached:function(){console.log('[my-component]-attached')},ready:function(){console.log('[my-component]-ready')},methods:{myCompMethod:function(){console.log('[my-component]-method')}}})//behavior.jsexportdefaultBehavior({behaviors:[],properties:{myBehaviorProperty:{type:String,value:'myBehaviorProperty'}},data:{myBehaviorData:'myBehaviorData'},created:function(){console.log('[my-behavior]-created')},attached:function(){控制台.log('[my-behavior]-attached')},ready:function(){console.log('[my-behavior]-ready')},methods:{myBehaviorMethod:function(){console.log('[我的行为]-方法')}}})面试会问为什么需要分包。目前小程序主包大小限制不超过2M,整体(含分包)不能超过20M。将小程序分包可以优化首次启动的下载时间,并且在多个团队共同开发时,可以更好的解耦页面通信——组件跨页面赋值的高层用法类似于vue中的ref,直接操作组件属性值letpages=getCurrentPages()//当前页面栈letprePage=pages[pages.length-2]//上一页prevPage.setData({//直接复制到上一页})usesbehaviorfor数据共享,使用wx.nativgateTo打开。这两个页面会建立一个数据通道,类似于父子组件,可以通过emit和on相互发送。打开的页面可以通过this.getOpenerEventChannel()方法获取一个EventChannel对象。wx.navigateTo的成功回调也包含一个EventChannel对象。这两个EventChannel对象可以使用emit和on方法相互通信发送和监听事件如何优化SEO小程序如何优化官方文档配置小程序在sitemap小程序中跳转的页面(url)可以直接打开手机号登录开发过程中,如果想通过奇微群发送公众号页面,奇微无法爬取页面信息,因为页面使用静默授权,爬取页面时会直接跳转到授权页面.因此无法获取页面信息。设置清晰的标题和页面缩略图。性能相关小程序启动流程官方文档小程序切换页面流程官方文档如何提升小程序性能启动时性能优化(懒加载模块)首屏渲染优化其他优化运行时性能优化合理使用setState渲染性能优化:不要必要时不监听滚动事件,使用不那么复杂的动画效果页面切换优化:避免onHide/onUnload中的耗时操作,提前发起数据请求资源加载优化:图片资源控制内存优化:分包、按需注入、内存分析,处理内存告警内存泄漏:如果页面实例是全局挂载的,或者还在其他地方使用,那么这个获取到的页面如果没有释放,很容易造成内存泄漏。当其他页面需要使用这个时,需要在页面卸载时手动释放内存。time)如果是vue或者react等框架,可以在webpack中加载自己写的babel插件。在转换ast的步骤中,可以自动插入埋点小程序。可以使用腾讯官方提供的埋点工具,也可以使用开发者工具自动插入定义分析设置埋点上报