前言

那啥,对于小程序整顿了几篇笔记,多多少少对集体而言有点作用,上面附上对应的文章链接:

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

心愿多多少少能够帮忙到像我一样的前端小白。

这年头,挣钱不易,小作坊生存不易!

且行且珍惜吧。

1、List item 和 button 抵触怎么玩?

这个事件是这样的,因为韩总死乞白赖的非要列表新增转发 PDF 性能,因为微信小程序限度只有 button 才具备凋谢的一些权限,所以间接采纳 button 包裹 image 的计划,如下:

<view class="news">   <block wx:for="{{ newsList }}" wx:for-index="index" wx:key="news">    <view class="news-item" bindtap="onNewsItemClick" data-newsID="{{ item.newID }}">      <text class="content">{{ item.content }}</text>      <view class="item_new_bottom">        <text class="createTime">{{ item.createTime }}</text>        <button open-type="share" bindtap="onShareAppMessage" hover-stop-propagation="true"          data-shareid="{{ item.newID }}">          <image src="/images/ic_share.svg" mode="aspectFit"></image>        </button>      </view>    </view>    <van-divider wx:if="{{ index != newsList.length -1 }}" />  </block></view>

成果如下:

有个比拟难堪的问题是,当点击分享图标时,对应的 item 事件也会执行,查阅了官网手册后。

将 button 事件类型调整为:catchtap 即可。

针对这两种形式,这里简略了解下。

  • 应用 catchtap 形式暖男,且只对你一个人暖,也就是说事件不会再次向上传递,自我生产;
  • bindtap 形式则是渣男,挨个宠幸。

2、如何分享页面并携带参数?

这个需要是真恶心,先来看下效果图:

简略说下步骤:

  • button 设置 open-type 为 share;
  • onShareAppMessage() 中设置 title、path 以及 imageUrl;
  • onLoad 中接管到解析即可。

上面附上要害 js 代码:

/*** 生命周期函数--监听页面加载*/onLoad: function (options) {  let sharePDFId = parseInt(options.sharePDFId);  if (sharePDFId >= 0) {    var newFilePath = wx.env.USER_DATA_PATH + '/' + this.data.newsList[sharePDFId].content + '.pdf';    let downloadPDFUrl = this.data.newsList[sharePDFId].pdfUrl;    handleLoadPDF(newFilePath, downloadPDFUrl);  }},/** * 用户点击右上角分享 */onShareAppMessage: function (res) {  let that = this;  let sharePDFId = parseInt(res.target.dataset.shareid);  return {    title: that.data.newsList[sharePDFId].content + '.pdf',    path: '/pages/index/index?sharePDFId=' + sharePDFId,    imageUrl: urlUtils.getComposeUrl('/images/img_share_pdf.png')  }},

3、如何实现列表点击 item title 变色,markers 同时变色?

先来看个成果吧,可能我得形容不是那么精确:

思路都是一样的:

  • 通晓以后 item 点击地位;
  • 更新 markers 中对应的 marker。

给出局部页面代码:

<view class="port_desc">  <map id="map" bindmarkertap="onMarkersClick" setting="{{ setting }}" show-location markers="{{ markers }}"/>  <scroll-view scroll-y>    <block wx:for="{{ portList }}" wx:key="port">      <view class="item_port" bindtap="onPortItemClick" data-portid="{{ item.portId }}" data-index="{{ index }}">            </block>  </scroll-view></view>

对应的 js 文件:

Page({  /**   * 页面的初始数据   */  data: {     mCurPosititon: 0,      markers: [{      iconPath: "/images/icon_prot.png",      id: 0,      latitude: 19.731021,      longitude: 109.205006,      width: 30,      height: 36    }, {      iconPath: "/images/icon_prot.png",      id: 1,      latitude: 20.022159,      longitude: 110.283528,      width: 30,      height: 36    }],   },   /**   * 生命周期函数--监听页面显示   */  onShow: function () {    this.refreshMarkers(0);  },  /**   * 港口 item 点击 - 地图 markers 平移   */  onPortItemClick: function (event) {    let that = this;    let currentId = event.currentTarget.dataset.portid;    let portBean = that.data.portList[currentId];    // 平移 markers 到地图核心    this.mapContext.moveToLocation({      longitude: portBean.longitude,      latitude: portBean.latitude,      success(res) {        console.log('---> 平移胜利 ', res);      },      fail(err) {        console.log('---> 平移失败 ', err);      }    });    that.refreshMarkers(1);    that.setData({      mCurPosititon: event.currentTarget.dataset.index,    });    that.refreshMarkers(0);  },   /**   * 刷新以后选中的 Markers 点   */  refreshMarkers: function (type) {    let that = this;    var tempMarkers = that.data.markers;    tempMarkers[that.data.mCurPosititon].iconPath = type == 0 ? '/images/icon_prot_sel.png' : '/images/icon_prot.png';    that.setData({      markers: tempMarkers,    });  }})

有时候想想,这货色真的是相通的。遇到问题,静下心来,缓缓梳理,别慌。

4、wxml 中的三元运算符应用

这个比拟 easy,间接放上代码:

<text class="title" style="color:{{ mCurPosititon == index ? 'red' : 'black' }}">{{ item.title }}</text>

5、map 如何自定义气泡窗口,反对动静切换,并且反对点击?

先来看个效果图,高深莫测:

这块内容绝对 easy,间接放上代码咯。

首先是 js 要害代码:

/** * 页面的初始数据 */data: {   portName: '',  markerId: 0,   markers: [{    id: 0, iconPath: "/images/icon_prot.png",    latitude: 19.731021, longitude: 109.205006,    width: 30, height: 36, customCallout: {      anchorX: 0,      anchorY: 0,      display: "ALWAYS"    }  }, {    id: 1, iconPath: "/images/icon_prot.png",    latitude: 20.022159, longitude: 110.283528,    width: 30, height: 36, customCallout: {      anchorX: 0,      anchorY: 0,      display: "ALWAYS"    }  }, ],  portList: [{    portId: 0, markerId: 0, title: '洋浦港',    desc: '洋浦港....',    avatar: 'https:/xxxx9e.jpg',    latitude: 19.731021, longitude: 109.205006,  }, {    portId: 1, markerId: 1, title: '海口港',    desc: '海口港xxx',    avatar: 'https://xxxae.jpeg',    latitude: 20.022159, longitude: 110.283528,  }, ]},/** * 生命周期函数--监听页面显示 */onShow: function () {  let that = this;   // 初始化数据  let portBean = that.data.portList[0];  that.setData({    portName: portBean.title,    markerId: portBean.markerId  });},/** * 港口 item 点击 - 地图 markers 平移 */onPortItemClick: function (event) {  let that = this;  let currentId = event.currentTarget.dataset.portid;  let portBean = that.data.portList[currentId];  // 平移 markers 到地图核心  this.mapContext.moveToLocation({    longitude: portBean.longitude,    latitude: portBean.latitude,    success(res) {      console.log('---> 平移胜利 ', res);    },    fail(err) {      console.log('---> 平移失败 ', err);    }  });  that.refreshMarkers(1);  that.setData({    mCurPosititon: event.currentTarget.dataset.index,  });  that.refreshMarkers(0);  // 更新气泡数据  that.setData({    portName: portBean.title,    markerId: portBean.markerId  });},/** * Markers 点击查看详情 */bindcallouttap: function (event) {  let markerId = parseInt(event.detail.markerId); // 其实这就是 id,为了实现对应的详情切换  wx.navigateTo({    url: '/pages/portDetail/portDetail?portId=' + markerId  })},/** * 刷新以后选中的 Markers 点 */refreshMarkers: function (type) {  let that = this;  var tempMarkers = that.data.markers;  tempMarkers[that.data.mCurPosititon].iconPath = type == 0 ? '/images/icon_prot_sel.png' : '/images/icon_prot.png';  that.setData({    markers: tempMarkers,  });} 

而后就是对应的 wxml 要害代码:

<map bindcallouttap="bindcallouttap" id="map" setting="{{ setting }}" show-location markers="{{ markers }}">  <cover-view slot="callout">    <cover-view marker-id="{{ markerId }}">      <cover-view class="map_custiom_callout">        <cover-view class="portName">{{ portName }}</cover-view>      </cover-view>    </cover-view>  </cover-view></map><scroll-view scroll-y>  <block wx:for="{{ portList }}" wx:key="port">    <view class="item_port" bindtap="onPortItemClick" data-portid="{{ item.portId }}" data-index="{{ index }}">      <!-- ... -->  </block></scroll-view>

这块从一开始本人就进入了一个误区。其实很多事件都是循循渐进,太过于急功近利,反而有点得失相当了。无论身处何地,放弃本身沉着,条理剖析。

6、对于那些烦人的相对路径解决

置信大家都遇到过如下状况,比方我定义一个 urlUtils 工具类,那么在对应应用的 js 中就须要通过如下形式援用:

  • const urlUtils = require('../../utils/urlUtils.js')

看到后面的 ../ 就说烦不烦?

征询大佬,大佬提供了一种应用绝对路径计划,如下:

Step 1: app.js 新增 require 办法:

require: function ($url) { return require($url) },

Step 2: 替换原有很 low 的形式。

//获取利用实例const app = getApp();const urlUtils = app.require('utils/urlUtils.js');

ummm,爽多了。哈哈哈。

对了,记得敞开「上传时进行代码爱护」

7、如何实现点击图片弹出并播放视频?

还是老规矩,放个效果图,稍等,等我录制,????

附上对应 wxml 内容:

<video id="videoID" bindfullscreenchange="bindFullScreenChange"     direction="0" controls="true" src="{{ videoLink }}"        show-fullscreen-btn="{{ false }}"></video>

这里还独自给了一个款式:

video {  display: none;}

而后就是对应的 js:

/** * 视频进入和退出全屏时触发,event.detail = {fullScreen, direction},direction 有效值为 vertical 或 horizontal */bindFullScreenChange: function (event) {  this.videoContext.pause();  this.setData({    videoLink: null,  });},function handleVideoPlay(that, videoUrl) {  that.setData({    videoLink: videoUrl  });  that.videoContext.requestFullScreen();  setTimeout(function () {    that.videoContext.play();  }, 600);}

这里特意说一下,这里依照官网设置 true/false,在真机上有效,须要用 {{ }} 去包裹每个 Boolean 值即可。

这点官网文档体验性不太好。

8、搜寻后果高亮显示

成果如下所示:

一起来看看这万恶的资本主义:

一时怒怼一时爽,爽完还得去撸码,谁让咱是底层低微的打工人呢?

最后的想法是,依照 Android 之前间接替换标签加款式的计划,后果小程序间接把替换的标签展现进去了。

度娘了一波,失去的计划简直差不多,最终都是拆分 title,而后去匹配搜寻的 key,并设置对应的高亮 CSS,有的大佬间接一把梭,手撸自定义组件,尔等间接拜服拜服,告辞~

好啦,俏皮话不多说,先附上 wxml 文件,已省略其余无关代码片段:

<view class="container">  <van-search       bind:search="onSearchClick"       clearable input-align="center"       value="{{ searchKey }}"       shape="round" focus      placeholder="请输出搜寻关键词" />   <block       wx:if="{{ exhResultList.length }}"       wx:for='{{ exhResultList }}'       wx:for-index="index" wx:key="exh">    <view       class="tab_item"       catchtap="onActionItemClick"       data-itemid="{{ item.exh_id }}">       <view class="tab_info">          <!-- 要害是这块 -->        <view class="title">          <!-- 循环遍历匹配搜寻关键字,并设置高亮 CSS -->          <text             wx:for="{{ item.exh_name }}"             class="{{item == searchKey ? 'searchHigh' : '' }}">{{ item }}</text>        </view>       </view>    </view>    <van-divider wx:if="{{ index != exhResultList.length -1 }}" />  </block> </view>

随后简略附上对应高亮的 CSS,其实就是个设置字体色彩:

.searchHigh {  color: red;}

最初的 js 要害代码:

data: {   searchKey:'', },      onSearchClick: function (event) {  var that = this;   // 搜寻关键字记得去除前后空格  that.setData({    exhResultList: [],    searchKey : that.trim(event.detail)  });  // ...},/** * 去除前后空格 * @param {} s  */trim: function (s) {  return s.replace(/(^\s*)|(\s*$)/g, "");},

9、文字盘绕图片成果

成果如下:

要害就是 float:left 间接附上 wxml 代码:

<view class="header">  <image src="{{ mHeaderImage }}" mode="aspectFit"></image>  <label>    疏忽泛滥文字内容...  </label></view>

对应 CSS:

.header {}.header image {  float: left;  width: 180rpx;  height: 180rpx;}.header label {  font-size: 24rpx;}

10、记录个列表展现形式实现

简略举个成果,到时候大家触类旁通即可。实现原理一样,业务需要则比较复杂咯。

次要用到了 vant 提供的 Layout 组件,它将一行气氛 24 列栅格,临时称为栅格布局吧。

间接丢代码咯:

<view class="hot_line_class">  <van-row>    <block wx:for="{{ mHotAuthorList }}" wx:key="*this">      <van-col span="6">         <view class="item_hot_line">          <image class="avatar" src="{{ item.avatar }}" mode="aspectFit"></image>          <text class="name">{{ item.jobName }}</text>          <text class="mobile">{{ item.name }}</text>        </view>      </van-col>    </block>  </van-row></view>

span="6" 这里代表一行 4 列,24 / 6 = 4。剩下诸如此类。

还有个比拟要害的中央是千万记得给 item 设置宽度 100%,不然当列表内容为奇数时,最初一位显示比拟奇怪,别问我咋晓得的。

后记

总感觉每个小例子尽量配一个演示成果,不便间接上手,用最快捷的形式证实是否和预期统一,转过头来看,是减少了不少麻烦。一分耕耘一分收获,心愿能够帮忙到和我一样的前端小白白。

暴力解法也好,最优解也好,首先我感觉是先解进去,随后逐渐优化。一段看似简洁高效的代码,背地谁人能知作者心血。

没必要力求最优,挨个击破也未尝不是一种好形式。

ummm,96 年的都被叫叔叔了,应该是前端老白白了(手动滑稽~)。

一起致力呀,万一一不小心和我鸡老大肩并肩了呢~

参考资料

  • 微信官网文档