微信小程序 Notes | 开发常用事例
Posted HLQ_Struggle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信小程序 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、如何分享页面并携带参数?
这个需求是真恶心,先来看下效果图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0dbPW4U6-1607304985403)(https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/af80ce2169564e93aa6c1c504eb54ded~tplv-k3u1fbpfcp-watermark.image)]
简单说下步骤:
- 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 年的都被叫叔叔了,应该是前端老白白了(手动滑稽~)。
一起努力呀,万一一不小心和我鸡老大肩并肩了呢~
参考资料
CSDN 社区图书馆,开张营业! 深读计划,写书评领图书福利~以上是关于微信小程序 Notes | 开发常用事例的主要内容,如果未能解决你的问题,请参考以下文章
微信小程序 Notes | 常用开发事例基于云平台导出 Excel