前言微信小程序登录基本上是每个小程序必备的功能,但是随着业务越来越复杂,需要考虑的情况也越来越多,因此登录功能的健壮性和高效性值得关注。根据以往的经验,我们会实现一个更优雅的登录方案。基本登录流程获取微信登录凭证,通过wx.login获取。该API将返回一个时间敏感的代码并将该代码发送到服务器。这一步是通过你和后端。定义的接口发送服务器根据前端发送的代码获取用户身份信息。当然这一步不是前端的逻辑。服务端处理完后,会将用户信息和sessinId发送给前端,然后前端存储需要的信息。下一次请求可以携带sessinId来表示身份。以下是官方微信流程图逻辑封装。对于上面的登录流程,我会封装如下方法供业务层调用方法名函数getLoginCode获取微信登录凭证。staticLogin静默登录singleLogin登录请求封装checkLogin判断是否登录getPhoneNum获取微信授权手机号我习惯在promise请求中使用await-to方法,比较优雅的解决异步如何写asyncawait不用try-catchblocksinJavascriptgetLoginCode,一个简单的promise封装getcodeexportconstgetLoginCode=()=>{returnnewPromise((resolve,reject)=>{wx.login({success(res){if(res.code){resolve(res.code)}else{reject(res)}},fail(err){reject(err)}})})}静默登录封装,获取用户信息并存储exportconststaticLogin=async()=>{//如果已经登录,直接返回登录信息if(checkLogin()){returngetLoginInfo()}const[loginErr,loginRes]=await_to(singleLogin());如果(loginErr){抛出新错误(loginErr);}//存储用户信息,这个要看我自己的情况,我只是设置了一个方法setLoginInfo({...loginRes,})returnloginRes;}登录请求封装,这里我使用的是单例模式,返回一个promise,这个是为了多次调用singleLogin时,比如快速切换页面,快速点击多次登录区域,没有返回数据时,会等待而不是触发多次请求letloginInstance=nullexportconstsingleLogin=()=>{if(loginInstance){returnloginInstance}//loginReq:封装请求,包括请求后端和getLoginCodecheckLogin,检查是否登录,这个要看你存放在哪里,视情况而定)=>{const[codeErr,codeRes]=await_to(getLoginCode())if(codeErr){console.log(codeErr);抛出新的错误(codeErr);}//解密:请求后端const[phoneErr,phoneRes]=await_to(decrypt({iv,encryptedData,代码:codeRes.code}))if(phoneErr){console.log(phoneErr);抛出新的错误(phoneErr);}constphoneNumber=phoneRes.result.phoneNumbersetLoginInfo({phoneNumber,})returnphoneNumber}业务层在业务层我会在下面几个地方调用请求前根据options判断是否登录,并处理exportconstREQUEST=async(requestObj)=>{//isLogin当前接口请求是否需要登录if(requestObj.isLogin&&!checkLogin()){const[loginErr,loginRes]=await_to(staticLogin());if(loginErr){Toast('登录失败')thrownewError(loginErr);}}...}登录按钮,这个主要用于在登录失败的情况下,让用户主动点击登录弹窗等组件,调用staticLogin获取用户授权手机号按钮即可//index.html//用户主动触发授权手机号