前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >改头换面:迁移既有项目到微信小程序

改头换面:迁移既有项目到微信小程序

作者头像
江米小枣
发布2020-06-15 15:10:00
7200
发布2020-06-15 15:10:00
举报
文章被收录于专栏:云前端云前端

小程序基础请参考之前的文章: 一个简单的微信小程序DEMO

在既有的某html5移动端项目基础上,考虑到其形态和体量很适合转化为微信小程序,遂花费了不长的时间撸起袖子试试看,并将期间遇到的踩坑心得记录在此

目录

  • 复用的mock
  • 素材图片处理
  • 样式的转化
  • 小程序中几种不同的跳转
  • 小失所望的兼容性
  • 差强人意的小程序“组件”
  • 在小程序中实现表格

1. 复用的mock

之前的项目中使用express模拟前后端通信数据(mock),对其稍加改造,就可以在保留对原项目的支持的同时,满足小程序的测试了

1.1 识别请求来源为小程序

代码语言:javascript
复制
//小程序中的每次请求
wx.request({
     url: `http://127.0.0.1:3201${url}`,
     data: assign(
       data,
       {
         _from_weapp: 1, //添加特殊标记,以作区分
         code: _globalData['wx_code'],
         openid: wx.getStorageSync('openid')
       }
     ),
     
     ...
});
代码语言:javascript
复制
//mock中的过滤器
app.all('/api/*', function(req, res, next) {     //判断来源是不是小程序
   const IS_WEAPP = req.method == 'GET'
       ? req.query._from_weapp == 1
       : req.body._from_weapp == 1;
       
       ...    
});

1.2 登录态和权限管理

  • 服务器端通过用户唯一标识openid识别用户
  • 小程序通过api获得code,传递给服务器换取并缓存openid
  • 每次请求都携带openid
  • 登出或超时后服务器在响应中返回状态码401触发重新登录

1.3 跨域ajax设置

代码语言:javascript
复制
app.all('/api/*', function(req, res, next) {  
   res.header("Access-Control-Allow-Origin", "*");
   res.header("Access-Control-Allow-Credentials", true);
   res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");  
   res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  
   res.header("Content-Type", "application/json;charset=utf-8");  
   next();  
});
  • 要允许小程序跨域访问,服务器端应做必要的设置
  • 最主要的响应头Access-Control-Allow-Origin,在实际测试时不能为通配符 *,应该写为小程序实际发起请求的域名,也就是https://servicewechat.com

2. 素材图片处理

和之前的经验相比,小程序中的素材图片需要考虑以下几点

  • 微信小程序限制总体积,一些资源宜改为远端读取
  • 样式表中直接引用的图片要求绝对路径,对于更改域名等调试操作不便

因此,基本的运用原则就是:最小化使用素材图片,并且除了系统 tabBar 等处用到的图标等需要把图片文件打包到发布结构中,其他素材图片尽量 base64 转码后放入 wxss

代码语言:javascript
复制
/*在wxcc中的引用*/
.figure {
 width: 27rpx;
 height: 25rpx;
 display: inline-block;
 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAZCAYAAADAHFVeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABd0RVh0Q3JlYXRpb24gVGltZQAyMDE3LjUuMjKXkY//AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAgVJREFUSImtldGRokAQhj+te9cQyED22alamAlgyWDZDAxhjeC8CGQjWBKA5YF7381AM8AIvIdpcJxDC8WpskBo/q+b+buZ4K2yqANgBYRADmTaqMaPG7qOx2N3PvVAKfANJHLpN1CVRT2/F+auDiagLVABoTYqAp6AQIDhQ2AitAUOwAtSmTbqG4geBWwr2wB7Ef0BtlKpCwR4HwWT/XgG3sUI0QVgDozau19Y14E1BtqopizqCMgEiMS8AusxsIkIf2mjJv7NsqgzgQB8aKPSWwG91pf+8lclx/U9IH9NgZ2c9zmtTSAfCwKYaqN2WCemPfczbDs8rs9E9MUXlEQi+fvQPjsAmT+avD4bBewcWBZ1Anxieyzyh68YKMfuYyRJ4MWkcr/RRm3g3I2TnuDtFeAc69AAWGmjMudehm2TAzBrNWK97DTOpr48/AYs6Jn2zoTZ4UwYB7TWRs1dja/yb6fxXyPfWOFCYhZYR4dtrGhsJLEk1svdWWV3VPgBNMAf7NzsYkUjwr7y/GJlQyv0YkNOE6czkKMR91Y2tEIv9lKLdAlerczJus3u1goT7L4FQDAI5gH3QKqNqq7EtsCZXHqL9TIbDBORCLvZM6w5cm1U7sXMOVU0a0Ew8DX2iK3k12b+w2lvnuW4B9JYL6v22ZthHjjBfppCrPUb7Bc/b93ojqt/8akRua+fVJwAAAAASUVORK5CYII=');
 background-position: 0 50%;
 background-repeat: no-repeat;
 background-size: contain;
 margin-right: 12rpx;
}
代码语言:javascript
复制
//转码的脚本
const base64Img = require('base64-img');
const imgs = Array.from(process.argv).slice(2);console.log(imgs.map(imgPath=>{
   let rst = imgPath + '\n-------------------\n';
   rst += base64Img.base64Sync(imgPath);
   rst += '\n\n';
   return rst;
}).join('\n'));

3. 样式的转化

由于之前的项目以较合理的方式运用了 rem 尺寸,稍加改造就可以方便的转化到小程序要求的 rpx

代码语言:javascript
复制
/*既有项目中的LESS预处理*/@remUIWidth: 720; /*之前的设计图尺寸*/.px2rem(@px, @name: font-size){
   @{name}: unit(@px, px);
   @{name}: unit(@px / (@remUIWidth / 20), rem);
}....logout {
   .px2rem(130px, margin-left);
}
代码语言:javascript
复制
/*编译结果*/
.logout {
 margin-left: 130px;
 margin-left: 3.61111111rem;
}

改为小程序的 rpx 格式,并依旧用 Less 预处理:

代码语言:javascript
复制
@WEAPP-WIDTH: 750;
@ui-width: 720;.px2rpx(@px, @name: font-size){
 @{name}: unit(@px, px);
 @{name}: unit( floor(@px * @WEAPP-WIDTH / @ui-width), rpx);
}....logout {
   .px2rpx(130px, margin-left);
}
代码语言:javascript
复制
/*编译结果*/
.logout {
 margin-left: 130px;
 margin-left: 135rpx;
}

4. 小程序中几种不同的跳转

小程序现在并不允许外链,但即使是应用内的跳转,却也分出了好几种不同的方式,即便不爽还是必须了解的:

  • wx.navigateTo() 保留当前页面,跳转到应用内的某个非 tabBar 的页面
  • wx.redirectTo() 关闭当前页面,跳转到应用内的某个非 tabBar 的页面
  • wx.switchTab() 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
  • wx.navigateBack() 关闭当前页面,返回上一页面或多级页面
  • wx.reLaunch() 关闭所有页面,打开到应用内的某个页面

<navigator /> 组件中有一个 open-type 属性,分别对应以上类型:

  • navigate 对应 wx.navigateTo 的功能
  • redirect 对应 wx.redirectTo 的功能
  • switchTab 对应 wx.switchTab 的功能
  • reLaunch 对应 wx.reLaunch 的功能
  • navigateBack 对应 wx.navigateBack 的功能

5. 小失所望的兼容性

小程序虽然已经出台多时,但在很多方面都在不断改变和完善,es6和css的语法方面,可以通过“开启 ES6 转 ES5 ”和“开启 上传代码时样式文件自动补全”来解决,但一些所谓新API,还是要手动判断处理:

旧版本微信客户端不支持 showLoading() / hideLoading()

代码语言:javascript
复制
const hide_loading = () => {
 if (wx.hideLoading) {
   wx.hideLoading()
 } else {
   wx.hideToast()
 }
};

旧版本微信客户端不支持 reLaunch,分情况用不同方法代替

代码语言:javascript
复制
if (wx.reLaunch)
   wx.reLaunch({
     url: rst.route
   })
else
   wx.switchTab({
     url: rst.route,
   })

某些ios客户端中,程序甫一启动时,立即调用 reLaunch() 会报错,需要延时处理

代码语言:javascript
复制
if (res.statusCode == 401) {
 setTimeout(function() {
   if (wx.reLaunch)
     wx.reLaunch({
       url: '/pages/login/login'
     });
   else
     wx.redirectTo({
       url: '/pages/login/login'
     })
 }, 500);
 return;
}

兼容处理 <navigator /> 组件的 reLaunch 跳转

该例因为是不同参数的本页跳转,在旧版客户端中尝试了几种旧有属性值都无法实现,故特殊处理:

代码语言:javascript
复制
<navigator wx:if="{{ tabs.current !== tab.key }}"
   url="{{ tabs.links[idx] }}"
   data-url="{{ tabs.links[idx] }}"
   open-type="{{ tabs.openType }}"
   catchtap="onTabClick">{{ tab.label }}</navigator>
代码语言:javascript
复制
const openType = wx.reLaunch ? 'reLaunch' : 'navigate';...//在 onLoad(opts) 中
this.setData({
   tabs: {
       openType,
       current: opts.key,
       tabs: result.tabs,
       links: result.tabs.map(
           tab =>`/pages/path?time=${opts.time}&key=${tab.key}`
       )
   },
   ...
});...onTabClick(evt) {
   if (openType === 'reLaunch') return;
   const {url} = evt.currentTarget.dataset;
   const [m, time, key] = url.match(/time\=(.*?)\&key\=(.*?)$/);
   this.onLoad({time, key});
}

其他一般的兼容处理方法见官方文档: https://mp.weixin.qq.com/debug/wxadoc/dev/framework/compatibility.html

6. 差强人意的小程序“组件”

小程序当前并不支持原生的“组件”概念,只能用 js / wxml / wxss 中可用的模块化方法变通替代实现

对于较简单的可复用组件,如果没有较复杂的逻辑,只考虑模版和样式即可:

代码语言:javascript
复制
<!-- tabs.wxml -->
<template name="tabs">
 <view class="top-tabs">
   <block wx:for="{{ tabs.tabs }}" wx:for-item="tab" wx:for-index="idx" wx:key="key">
     ...
   </block>
 </view>
</template><!-- rank.wxml -->
<import src="tabs.wxml" />
...
<template is="tabs" data="{{ tabs }}" />
代码语言:javascript
复制
/* tabs.wxss */
.scope {
 overflow: hidden;
}
.top-tabs {
 ...
}/* rank.wxss */
@import './tabs.wxss';
...

7. 在小程序中实现表格

小程序提供的组件中并不包含tabletheadtr等,但是用css属性和<view />组件旧可以完美模拟一个文首展示的表格

代码语言:javascript
复制
/*table by <view>*/
.table {
   border-collapse:collapse;
   border-spacing:0;
   width:100%;
   display: table;
}
.table .thead {
 display: table-header-group;
}
.table .tbody {
 display: table-row-group;
}
.table .tr {
 display: table-row;
}
.table .th,
.table .td {
 display: table-cell;
}

* 原创文章转载请注明出处

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 1. 复用的mock
    • 1.1 识别请求来源为小程序
      • 1.2 登录态和权限管理
        • 1.3 跨域ajax设置
        • 2. 素材图片处理
        • 3. 样式的转化
        • 4. 小程序中几种不同的跳转
        • 5. 小失所望的兼容性
          • 旧版本微信客户端不支持 showLoading() / hideLoading()
            • 旧版本微信客户端不支持 reLaunch,分情况用不同方法代替
              • 某些ios客户端中,程序甫一启动时,立即调用 reLaunch() 会报错,需要延时处理
                • 兼容处理 <navigator /> 组件的 reLaunch 跳转
                • 6. 差强人意的小程序“组件”
                • 7. 在小程序中实现表格
                相关产品与服务
                图片处理
                图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档