前言

之前涉足小程序,简短的记录了下开发过程中遇到的点点滴滴:

  • 微信小程序 | 开发罕用事例(一)
  • 微信小程序 | 开发罕用事例(二)

而今再次负责小程序,时隔许久,真是一片懵逼,多亏了之前的简短记录,这里将会一直记录欠缺开发过程中遇到的一系列的小问题。

总是要一直致力,买车到当初,各种无奈,仿佛国庆回来整个人都不好了,得连忙调整了,不然幻想始终只是幻想了。

加油~

小事例汇总

对于不相熟前端的 Android 而言,前端是真的烦,说不清因为哪儿个属性就抵触了。绝对比拟好的一点是在线调试,调整参数款式,间接拷贝。什么时候 Android 也能有这样的神器就好了,哇咔咔,期待我 Android 越来越好~

1. 微信小程序如何构建 npm?

之前始终都是 Android 为主,忽然在某个官网看到须要通过 npm 形式构建,登时有点懵逼,这里记录下步骤,不便下次间接分分钟搞定~

Step 1:进入小程序根目录执行 npm 初始化

  • npm init

胜利后会生成 package.json 文件。

Step 2:随后执行对应的 npm 装置依赖

例如这里须要应用有赞组件库 vant,所以对应的 npm 命令如下:

  • npm i @vant/weapp -S --production

这两步对应的示意图如下:

Step 3:在小程序开发工具中抉择构建 npm。

这里须要留神肯定在我的项目本地设置中关上 npm:

胜利后会生成 miniprogram_npm 目录,外面变蕴含咱们通过 npm 下载的 vant 代码了,如下:

2. 如何降级 npm 对应依赖包?

某天逛官网时挺懵逼的,看到人版本都晋升几个了,无从下手,这里放上降级形式,其实和之前一毛一样,如下降级 vant 事例图:

其实还是把官网提供的 npm 装置形式拷贝运行一次。

3. 如何点击 image 进入客服会话?

先附上效果图:

因为微信小程序 Api 中注明只有 button 才具备一些凋谢性能,而独自的 image 则无奈实现点击跳转客服音讯会话性能。前端个人感觉就是一个个元素通过不同的属性款式无所不包,那么我能不能通过 button 包裹 image 间接实现这个成果呢?一起来看~

<view class="model">  <button open-type="contact">    <image mode="aspectFit" src="/images/img_07.png" />  </button>  <!-- ... --></view>

款式文件如下:

.model {  display: flex;  justify-content: space-between;  margin-top: 30rpx;}.model button {  height: 180rpx;  width: 49%;  background-color: transparent !important;  margin: 0;  padding: 0 !important;}.model button::after {  border: 0px solid rgba(0, 0, 0, 0.2) !important;}.content .model button image {  width: 100%;}

4. 如何关上/预览云平台 PDF?

先来看下粗略的效果图:

大略是有那么点意思:

  • 反对关上/预览在线 PDF;
  • 反对显示 PDF 原有名称;
  • 反对分享、珍藏。

其实还是下载本地,而后关上,高大上忽悠就是反对预览在线 PDF,????

先来看下我本地模仿的根底数据:

newsList: [{        newID: 0,        title: '最新流动',        content: '游艇xx流动',        pdfUrl: urlUtils.getDownloadPDFUrl('/pdf/xxn.pdf'),        createTime: '2020 年 4 月 1 日'      },      {        newID: 1,        title: '产业政策',        content: '海南省xxx告诉',        pdfUrl: urlUtils.getDownloadPDFUrl('/pdf/xx.pdf'),        createTime: '2019 年 12 月 30 日'      },      {        newID: 2,        title: '最新内容',        content: '游艇xx名单',        pdfUrl: urlUtils.getDownloadPDFUrl('/pdf/xx.pdf'),        createTime: '2020 年 4 月 1 日'      }    ],

随后附上要害代码:

/** * 加载 PDF 文档 */onLoadItemPDF: function(event) {  wx.showLoading({    title: '文件缓冲中...',  })  var itemId = parseInt(event.currentTarget.dataset.newsid);  var saveTempFilePath = wx.env.USER_DATA_PATH + '/temp.pdf';  var newFilePath = wx.env.USER_DATA_PATH + '/' + this.data.newsList[itemId].content + '.pdf';  wx.downloadFile({    url: this.data.newsList[itemId].pdfUrl,    filePath: saveTempFilePath,    success: function(res) {      if (res.statusCode == 200) {        var fileSystemManager = wx.getFileSystemManager();        fileSystemManager.rename({          oldPath: saveTempFilePath,          newPath: newFilePath,          success: function(res) {            wx.openDocument({              filePath: newFilePath,              fileType: 'pdf',              showMenu: 'true',              success: function(res) {                console.log("----> 打开文档胜利 ");                wx.hideLoading()              },              fail: function(res) {                console.log("----> 打开文档失败 ");                console.log(res);                wx.hideLoading()                wx.showToast({                  title: '文档关上失败,请稍后再试!',                  icon: 'none'                })              }            })          },          fail: function(res) {            console.log("----> 重命名文档失败 " + res);            wx.hideLoading()            wx.showToast({              title: '重命名文档失败,请稍后再试!',              icon: 'none'            })          }        });      }    },    fail: function(res) {      console.log(res);      wx.hideLoading()      wx.showToast({        title: '文档关上失败,请稍后再试!',        icon: 'none'      })    }  })},

代码较为简单,这里就不一一细说了。仔细的小伙伴察看到这里在下载实现后应用了重命名,次要是为了防止关上 PDF 时题目为长期字符,如下所示:

这段代码其实还不是狠欠缺,最起码提醒这块,能够独自封装一层,这里就偷个懒了先。

哦,对,还有一点,云平台 PDF 地址记得拷贝下载地址哈!

5. 革新 vant-tabs 实现放大/放大 tab 切换

先来看个成果吧,Android 那边现成的 TabLayout 及其方便快捷,到了这边,哎。

怪我,不懂前端。

没啥说的,基于 vant-tabs 革新即可,上面间接附上残缺代码。

<van-tabs active="{{ active }}" animated swipeable nav-class="nav-class" tab-class="tab-class" tab-active-class="tab-active-class">  <van-tab title="游艇产业介绍">    123  </van-tab>  <van-tab title="游艇产业政策">    123  </van-tab>  <!-- ... --></van-tabs>

款式文件如下:

.van-ellipsis {  margin: 6rpx 0rpx 6rpx 14rpx;}.tab-class {  display: contents !important;  padding: 0 12px !important;  color: var(--tab-text-color, #646566) !important;  font-size: var(--tab-font-size, 14px) !important;  line-height: var(--tabs-line-height, 112rpx) !important;}.tab-active-class {  font-weight: var(--font-weight-bold, 800);  font-size: var(--tab-font-size, 16px) !important;  color: var(--tab-active-text-color, #323233);  line-height: 105rpx !important;}.nav-class {  height: auto !important;  background-color: #f5f5f5;}

除了第一个款式比拟非凡,剩下都是依照官网提供的自定义款式而来,这里简略截图阐明下,便于日后查看:

6. 如何实现 tabs 内容高度充斥屏幕?

要在 tabs 中嵌套一个地图,按情理来讲设置宽高 100% 就应该是充斥屏幕了,后果是这个惨样子:

上面还是空余了很大的空间,忽然想到之前 PHP 应用过的 vh,据说是动静屏幕大小,调整后如下:

map {  width: 100%;  height: 94.5vh;}

这样就能充斥整个屏幕咯。小伙伴能够想想为什么不设置 100vh?

7. 如何实现 text 最多显示两行,超出 ... 显示?

款式如下:

.item_action_title {   display: -webkit-box;    -webkit-box-orient: vertical;  -webkit-line-clamp: 2;  overflow: hidden;  text-overflow: ellipsis;  text-overflow: -o-ellipsis-lastline;   }

8. 如何在 map 上增加对应浮层?

先来看下最终的成果:

这里 diss 下微信小程序官网神逻辑,明明我在模拟器一通操作猛如虎,为何运行真机不显示?逗我玩呢?为什么不间接在模拟器上禁止呢?好玩吗?

先说几点注意事项吧:

  • map 组件是由客户端创立的原生组件,它的层级是最高的 (也就是说不反对在 map 上应用惯例形式增加内容)
  • cover-view 只反对嵌套 cover-view、cover-image,可在 cover-view 中应用 button。组件属性的长度单位默认为 px,2.4.0 起反对传入单位(rpx/px);
  • cover-image 直到现在(2020-10-23)不反对 mode,图片缩放模式。

首先来看下我这里简略模仿的数据格式:

portList: [{      title: '会所 - 001',      desc: '会所介绍',      avatar: 'http://www.china-rendezvous.com/Index/Tpl/Public/images/index/banner.jpg'    }, {      title: '会所 - 002',      desc: '会所介绍',      avatar: 'http://www.china-rendezvous.com/Index/Tpl/Public/images/index/banner.jpg'    }, {      title: '会所 - 003',      desc: '会所介绍',      avatar: 'http://www.china-rendezvous.com/Index/Tpl/Public/images/index/banner.jpg'    }, ]

随后附上 map 要害代码:

<map setting="{{ setting }}">  <cover-view class="port_class">    <block wx:for="{{ portList }}" wx:key="port">      <cover-view class="item_port">        <cover-view class="item_port_content">          <cover-view class="title">{{ item.title }}</cover-view>          <cover-view class="desc">{{ item.desc }}</cover-view>        </cover-view>        <cover-image src="{{ item.avatar }}" />      </cover-view>      <cover-view class="divider_line" wx:if="{{ index < portList.length - 1 }}" />    </block>  </cover-view></map>

对应 js:

// 地图根本配置setting: {  skew: 0, // 歪斜角度  rotate: 0, // 旋转叫丢  scale: 8, // 缩放级别,取值范畴为3-20      showLocation: true, // 显示带有方向的以后定位点  showScale: true, // 显示比例尺  subKey: '', // 个性化地图应用的key  layerStyle: 1, // 个性化地图配置的 style,不反对动静批改  longitude: 109.76685421005249,  latitude: 19.207716690636587,  enableZoom: true, // 是否反对缩放      enableScroll: true, // 是否反对拖动      enableRotate: true, // 是否反对旋转      showCompass: true, // 显示指南针      enable3D: false, // 展现3D楼块  enableOverlooking: true, // 开启仰视      enableSatellite: false, // 是否开启卫星图      enableTraffic: true, // 是否开启实时路况      markers: [{    iconPath: "/images/img_position_flag.png",    id: 0,    latitude: 20.045611,    longitude: 110.181885,    width: 30,    height: 30  }, ],},

最初的 css 款式文件:

map {  width: 100%;  height: 94.5vh;}.port_class {  display: flex;  flex-direction: column;  margin: 30rpx;  background: #fff;  border-radius: 8rpx;  position: absolute;  bottom: 0;  left: 0;  right: 0;  max-height: 45vh;}.port_class .item_port {  display: flex;  flex-direction: rows;  padding: 30rpx;  justify-content: space-between;}.port_class .item_port .item_port_content {  display: flex;  flex-direction: column;  flex: 1;}.port_class .item_port .item_port_content .title {  font-size: 30rpx;  font-weight: bold;}.port_class .item_port .item_port_content .desc {  font-size: 26rpx;  color: gray;  margin-top: 22rpx;  display: -webkit-box;  -webkit-box-orient: vertical;  -webkit-line-clamp: 2;  overflow: hidden;  text-overflow: ellipsis;  text-overflow: -o-ellipsis-lastline;}.port_class .item_port cover-image {  height: 120rpx;  width: 120rpx;  margin-left: 30rpx;}.port_class .divider_line {  background-color: #f5f5f5;  width: 100%;  height: 3rpx;}

9. 如何实现 map 平移 markers?

记得增加权限,详情查看文末异样汇总。

来看下效果图:

这里附上要害 js 代码:

/** * 生命周期函数--监听页面首次渲染实现 */onReady: function() {  this.mapContext = wx.createMapContext('map');},/** * 港口 item 点击 - 地图 markers 平移 */onPortItemClick: function(event) {  let that = this;  let currentId = event.currentTarget.dataset.portid;   // 获取 markers 指标经纬度  let destination = {    longitude: that.data.portList[currentId].longitude,    latitude: that.data.portList[currentId].latitude  };  // 平移 markers  this.mapContext.translateMarker({    markerId: 0,    destination: destination,    autoRotate: true,    rotate: 0,    duration: 1000,    success(res) {      console.log('---> 平移胜利 ', res)    },    fail(err) {      console.log('---> 平移失败 ', err)    }  });}

哦,对了,html 文件如下:

<map id="map" setting="{{ setting }}" />

10. 如何平移 markers 到地图核心?

记得增加权限,详情查看文末异样汇总。

先来看下效果图:

html 文件如下:

<map id="map" setting="{{ setting }}" show-location />

要害 js 代码如下:

/** * 港口 item 点击 - 地图 markers 平移 */onPortItemClick: function(event) {  let that = this;  let currentId = event.currentTarget.dataset.portid;  // 平移 markers 到地图核心  this.mapContext.moveToLocation({    longitude: that.data.portList[currentId].longitude,    latitude: that.data.portList[currentId].latitude,    success(res) {      console.log('---> 平移胜利 ', res)    },    fail(err) {      console.log('---> 平移失败 ', err)    }  });}

11. 对于题目设置动态/动静

一般而言,对于某些固定的页面,我会间接在页面对应的 json 文件指定:

"navigationBarTitleText": "详情",

而某些动静,则通过如下形式进行动静设置:

// 设置题目wx.setNavigationBarTitle({  title: portBean.title,});

12. 对于获取用户公开信息

我这里用的是 vant-button 和 button 没啥区别,内容如下:

<van-button     wx:if="{{ avatarUrl }}"     open-type="getUserInfo"     bindgetuserinfo="bindGetUserInfo"     color="#1497da"     custom-class="login" round type="info">登录/注册</van-button>

对应的 js:

/** * 生命周期函数--监听页面加载 */onLoad: function(options) {   wx.getSetting({    success: function(res) {      if (res.authSetting['scope.userInfo']) {        wx.getUserInfo({          success: function(res) {            console.log(res);           }        })      }    }  })},/** * 获取用户信息 */bindGetUserInfo: function(res) {   console.log(res); },

获取到的数据:

首次会弹个框,如下:

13. 如何在地图上绘制覆盖物?

先来看下成果:

再来看一波官网 Api:

附上 wxml 代码:

<map id="map" setting="{{ setting }}" scale="15" show-location polygons="{{polygons}}" />

以及对应的 js 文件:

首先咱们定义一个寄存坐标点的 list:

const mTempWaterPolygonsList = [{  points: [{      longitude: 110.2100,      latitude: 20.0449    },    {      longitude: 110.2100,      latitude: 20.0651    },    {      longitude: 110.3100,      latitude: 20.0653    },    {      longitude: 110.3101,      latitude: 20.0104    },  ],  strokeColor: "#333",  strokeWidth: 3,  fillColor: "#80333333"}, {  points: [{      longitude: 110.4036,      latitude: 19.1908    },    {      longitude: 110.4300,      latitude: 19.1759    },    {      longitude: 110.3457,      latitude: 19.0230    },    {      longitude: 110.3401,      latitude: 19.0246    },  ],  strokeColor: "#333",  strokeWidth: 3,  fillColor: "#80333333"}, ];

初始化 map 根本设置:

data: {  // 地图根本配置  setting: {    skew: 0, // 歪斜角度    rotate: 0, // 旋转角度    scale: 11, // 缩放级别,取值范畴为3-20        showLocation: true, // 显示带有方向的以后定位点    showScale: true, // 显示比例尺    subKey: '', // 个性化地图应用的key    layerStyle: 1, // 个性化地图配置的 style,不反对动静批改     longitude: 110.260025,    latitude: 20.046425,    enableZoom: true, // 是否反对缩放        enableScroll: true, // 是否反对拖动        enableRotate: true, // 是否反对旋转        showCompass: true, // 显示指南针        enable3D: false, // 展现3D楼块    enableOverlooking: true, // 开启仰视        enableSatellite: false, // 是否开启卫星图        enableTraffic: false, // 是否开启实时路况      },   // 默认绘制第一个覆盖物  polygons: [{    ...mTempWaterPolygonsList[0]  }, ],},

而对于点击绘制其它覆盖物时,只须要动静更新 polygons 即可,例如我这里的操作:

/** * item click * Step 1: 平移中心点到地图核心; * Step 2: 绘制点对应覆盖物 */onWaterItemClick: function(event) {  let that = this;  let currentId = event.currentTarget.dataset.waterid;  // Step 1: 平移中心点到地图核心;  this.mapContext.moveToLocation({    longitude: that.data.tempWaterList[currentId].centerLongitude,    latitude: that.data.tempWaterList[currentId].centerLatitude,    success(res) {      console.log('---> 平移胜利 ', res)    },    fail(err) {      console.log('---> 平移失败 ', err)    }  });  // Step 2: 绘制点对应覆盖物  let polygons = mTempWaterPolygonsList[currentId];  that.setData({    'polygons[0]': polygons,  });},

End

十多条整顿下来,也是一段小经验。

微薄之力,助力和我一样小白~

一起加油~

万一不小心优良了呢?

异样汇总

  • oveToMapLocation:fail require permission desc

官网阐明:获取用户地位信息时需填写用处阐明

在 app.json 中增加获取地位权限:

"permission": {  "scope.userLocation": {    "desc": "您的地位信息将用于小程序地图的成果展现"  }},

参考资料

  • 微信官网开发文档
  • Vant Weapp