- 【手把手喂饭】Behavior教程:如何给每个页面混入统一的分享-share?
1、创建一个 js文件,我放在了个根目录下的 utils 里面 ,你也可以放在 behavior文件夹下(官方示例)取名为 share.js [图片] share.js 代码如下: let title = '你的默认分享主题' let imageUrl= '你的默认分享图片地址' let path = 'pages/index/index' // 默认放了个首页 module.exports = Behavior({ methods: { onShareAppMessage() { return { title, path, imageUrl } }, onShareTimeline() { return { title, path, imageUrl } } } }) 有没有很简单?我自己的 还加入了 默认的分享链接,还能知道是谁分享的 (大家可忽略) let userInfo = getApp().globalData.userInfo path = 'pages/index/index?share=' + userInfo._id 具体使用 ,在页面中引入 share.js,再配置一下就好 [图片] import share from "../../utils/share" Page({ // options: { // pureDataPattern: /^_/ // 指定所有 _ 开头的数据字段为纯数据字段 // }, behaviors: [share], // 混合 data: { 喂饭完毕~
2023-02-03 - 微信小程序答题页 swiper分页 极简
因为最近要写个做题页面,要求左右滑动切换页面。题目数量三位数会导致swiper卡顿严重,找了下相关文章没有发现合适的,就自己写了下。 实现功能 1、可以加载大量数据 2、跳转任意index 3、实现代码简单,方便复用 [图片] 直接帖代码 // pages/swiper/swiper.js Page({ /** * 页面的初始数据 */ data: { dataList: [], //实际数据 list: [], //展示数据 currentIndex: 0, //真实的index current: 0, //swiper当前的index recordCurrent: 0, //swiper上次的index duration: 300 //动画时常 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { for (let i = 0; i < 1000; ++i) { this.data.dataList.push(i) } this.setData({ dataList: this.data.dataList }) this.upSwiper(0) }, animationfinish({ detail }) { // 用户滑动 if (detail.source == "touch") { // 滑动后的index this.upSwiper(this.data.currentIndex + detail.current - this.data.recordCurrent) } }, upSwiper(index) { // 防止越界 if (index < 0 || index >= this.data.dataList.length) { return } this.setData({ currentIndex: index }) // 更新数据 let list = [] for (let i = this.data.currentIndex - 1; i <= this.data.currentIndex + 1; ++i) { let item = this.data.dataList[i] if (typeof (item) !== "undefined") { list.push(item) } } let current = 0; // 只要不是第一个页面 current都是1 if (index != 0) { current = 1 } // 取消动画 this.setData({ duration: 0 }) // current 和 list要同时更新,不然数据会闪 this.setData({ current: current, recordCurrent: current, duration: 300, list }) }, tap(ev) { let index = ev.currentTarget.dataset.index this.upSwiper(index) } }) <!--pages/swiper/swiper.wxml--> <swiper id="swiper" current="{{current}}" duration="{{duration}}" bindanimationfinish="animationfinish"> <swiper-item wx:for="{{list}}" wx:for-item="ee"> <view wx:for="{{20}}">{{ee}}</view> </swiper-item> </swiper> <view class="but-z"><button catchtap="tap" data-index="{{0}}">0</button> <button catchtap="tap" data-index="{{5}}">5</button> <button catchtap="tap" data-index="{{dataList.length-1}}">{{dataList.length-1}}</button> </view> /* pages/swiper/swiper.wxss */ #swiper { width: 100vw; height: 100vh; } .but-z { position: fixed; bottom: 20px; height: 40px; width: 100vw; display: flex } button { background-color: red; width: 100rpx !important; text-align: center; }
2021-12-14 - 利用css圆锥渐变实现环形进度条
[图片] 锥形渐变的正式语法如下: conic-gradient( [ from <angle> ]? [ at <position> ]?, <angular-color-stop-list> ) 可以看出锥形渐变由3部分组成: 起始角度 中心位置 角渐变断点 其中起始角度和中心位置都是可以省略的 这里只用了角渐变断点 background-image: conic-gradient(green 80%,#fff 80% 100%); 主要实现就两步 1.利用conic-gradient画一个圆 [图片] 2.利用任意元素做个内圆遮挡 [图片] 最外层的背景色原来是白色的,这里为了便于识别改成了灰色,现在将灰色的背景还原为白色 [图片] 环形进度条完成,就这么简单 通过动态的设置green的值就可以改变进度条的值 补充:还可以实现渐变进度条效果 [图片] 代码片段: 利用css圆锥渐变实现环形进度条
2020-06-22 - 巧用伪元素(:after/before)放大手机端点击区域
问题场景 我们在使用手机的过程中,是不是遇到过一些特别让你累的交互,就如手机端的按钮或图标老是点击不到,要多点击几次才能命中! 如何解决 手机的屏幕普遍比较小且分辨率高,这就导致设计的时候不能过大且要保持美观,严格按钮设计图尺寸开发后在手机端又过小导致点击事件无法触发。 那么怎么解决呢?不按照设计图切图?增加内边距撑大容器?这些方案都有或多或少不合理的地方,我有妙计可骚一把! 解决方案:after/before 通过设置点击元素的:after或:before伪元素大小来放大点击元素的点击区域 示例代码如下: [代码]/* 放大点击区域功能类 */ .nice-focus{ position:relative; } .nice-focus::after{ content:''; position:absolute; width:80px; height:80px; top:50%; left:50%; margin-top:-40px; margin-left:-40px; } /*返回按钮*/ .back{ width:12px; heigh:24px; background-image: url(/static/img/icon-back.png); background-size: 100% auto; } [代码] [代码]<!-- 页面使用 --> <div class="back nice-focus">返回</div> [代码] 总结 很多看似不能解决问题,换个角度就可以轻松解决!此方法也同样适用于小程序开发。
2019-10-28 - 如何彻底解决小程序滚动穿透问题
背景 俗话说,产品有三宝:弹窗、浮层加引导,足以见弹窗在产品同学心目中的地位。对任意一个刚入门的前端同学来说,实现一个模态框基本都可以达到信手拈来的地步,但是,当模态框里边的内容滚动起来以后,就会出现各种各样的让人摸不着头脑的问题,其中,最出名的想必就是滚动穿透。 什么是滚动穿透? 滚动穿透的定义:指我们滑动顶层的弹窗,但效果上却滑动了底层的内容。 具体解决方案分析如下: 改变顶层:从穿透的思路考虑,如果顶层不会穿透过去,那么问题就解决了,所以我们尝试给蒙层加catchtouchmove,但是发现部分场景无效果,那么就不再赘述了。 改变底层:既然是顶层影响了底层,要是底层不会滚动,那就没这个问题了。 如何改变底层解决该问题呢? 不成熟方案: 底部页面最外层view设置position: fixed;页面不可滚动,但是这个时候会导致页面回到顶部。 滚动时监听滚动距离,弹窗时记录滚动位置,关闭弹窗后使用wx.pageScrollTo回滚到记录的位置。 成熟方案 使用page-meta组件,通过该组件我们可以操作Page的style样式,类似于h5里body设置overflow: hidden; 控制页面不可滚动。文档地址:https://developers.weixin.qq.com/miniprogram/dev/component/page-meta.html 使用wx.setPageStyle设置overflow: hidden, 也可以实现给Page组件设置样式。) page-meta组件: 通过该组件我们可以直接操作[代码]Page[代码]组件 ,我们给它的wxss样式overflow动态设置[代码]hidden[代码]or[代码]visible[代码]or[代码]auto[代码] 就可以控制整个页面是否可以滚动。 [图片] wx.setPageStyle方法: 调用这个api,动态设置它为hidden/auto,用于控制页面是否可滚动,主要用于页面组件内使用,比如封装好的弹窗组件,就不用单独写page-meta组件了。。 [代码]wx.setPageStyle({ style: { overflow: 'hidden' // ‘auto’ } }) [代码] 老规矩,结尾放代码片段: https://developers.weixin.qq.com/s/U6ItgQmP7upQ 拓展 支付宝小程序虽然存在page-meta组件,但是由于内核为69版本,给page设置overflow: hidden 也无法控制底部元素不可滚动,目前已联系支付宝的底层开发同学提供API控制页面disableScroll,目前正在封装Appx,近期开放。
08-06 - 微信小程序swiper高度动态适配(子元素高度不固定)
示例代码地址 https://github.com/s568774056/swipe.git 对于整页都是swiper的情况下。例如下面这张图: [图片] 则可以使用如下css [代码] [代码] [代码]swiper,swiper-item{[代码] [代码] [代码][代码]height[代码][代码]: [代码][代码]100[代码][代码]vh [代码][代码]!important[代码][代码];[代码][代码]}[代码] [代码] [代码] [代码]或者 [代码] [代码] [代码] [代码][代码] [代码][代码] swiper,swiper-item{ height: calc(100vh - 75rpx) !important; } [代码][代码] [代码] [代码] 对于swiper占据部分高度的情况下。 [图片] 使用如下代码 原理为在[代码]swiper-item[代码][代码][代码]的最上面和最下面插入空view,并利用wx api获取两个之间的高度差,然后设置给[代码]swiper[代码]。 细节方面需要自己调整下。为什么小程序不把这个组件做好呢?还得自己计算- -! <swiper class='hide' bindanimationfinish="swiperChange" style="height:{{swiper_height}};" current="{{isIndex}}"> <swiper-item wx:for="{{roomList}}" wx:for-item='room' wx:for-index="index"> <view id="start{{index}}" class='start-view'></view> <block wx:for="{{imgUrls}}" wx:for-item='path' wx:for-index="img-index"> <image mode="aspectFill" src="{{path}}" /> </block> <view id="end{{index}}" class='start-view'></view> </swiper-item> </swiper> [代码][代码][代码][代码] swiper { margin-top: 45rpx; } Page({ data: { roomList: ['Room1', 'Room2', 'Room3'], imgUrls: [ 'https://images.unsplash.com/photo-1551334787-21e6bd3ab135?w=640', 'https://images.unsplash.com/photo-1551214012-84f95e060dee?w=640', 'https://images.unsplash.com/photo-1551446591-142875a901a1?w=640' ], swiper_height: 0, isIndex:0 }, onLoad: function () { this.autoHeight(); }, changeNavBar: function (e) { this.setData({ isIndex: e.detail }); }, swiperChange: function (e) { this.setData({ isIndex: e.detail.current }); this.autoHeight(); }, autoHeight() { let { isIndex } = this.data; wx.createSelectorQuery() .select('#end' + isIndex).boundingClientRect() .select('#start' + isIndex).boundingClientRect().exec(rect => { let _space = rect[0].top - rect[1].top; _space = _space + 'px'; this.setData({ swiper_height: _space }); }) } }) 参考文章https://developers.weixin.qq.com/community/develop/doc/00008aaf4a473056d1c69a8b253c04
2019-09-04 - 【笔记】云开发用户记录存在更新,不存在新增
方案一 :如果这个表里只存userInfo的信息,将_id值设置为OPENID,直接使用set覆盖,最简单。注意:这种方式会覆盖掉以前的数据,如果有部分其他数据,如注册时间、最后登录时间请使用后面的方式。let userInfo = event.userInfo if (!userInfo) { console.log('无用户信息,更新失败') }else{ db.collection('user').doc(OPENID).set({ data: userInfo }).then(e => { console.log('用户数据更新成功', e) }) } 方案二:如果用户表中存了其他字段,需要实现存在更新,不存在插入,可以先查询,再判断处理。async function updateUser () { let chk = await db.collection('user').where({ _openid: OPENID }).get() if (chk.data.length) { // 存在记录,更新 await db.collection('user').where({ _openid: OPENID }).update(userInfo) } else { // 不存在,新增 await db.collection('user').add(userInfo) } } 方案三:将_id直接设置为openid,然后利用查不到指定_id会报错的特性,在catch里填写更新语句,这样可以少执行一次查询操作。let userInfo = event.userInfo userInfo.lastTime = db.serverDate() //添加最后更新时间 db.collection('user').doc(OPENID).update({ data: userInfo }).catch(err => { //用户不存在会抛出异常,在异常中处理新增 userInfo._id = OPENID //设置OPENID为_id userInfo.createTime = db.serverDate() //添加用户创建时间 db.collection('user').add({ data: userInfo }) })
2020-05-21