- 微信小程序如何配置银联云闪付支付
前言: 早在9月30号,微信派公众号就发布了腾讯微信支付与银联云闪付深化支付合作与互联互通的声明,原文地址 那么问题来了,微信小程序怎么配置支持云闪付支付呢? 简简单单就一步,就可以让小程序支持云闪付支付了 登录微信支付商户后台->「产品中心」->「开发配置」页面最底部找到「支付方式配置」,点击「开启」就可以了,无需开发,无需额外配置,只要用户手机安装了云闪付app,在小程序支付时,就可以选择云闪付付款。 [图片] 注意事项 1、当前只支持小程序使用云闪付付款,微信app需要更新到最新版 2、开通后默认商户号绑定的所有小程序均开启支持云闪付支付,如有部分小程序不想开通云闪付付款,可以指定小程序appid不开启云闪付支付 [图片] 3、支持服务商模式 4、配置成功后支持停用 5、原有接口无需改动 6、如用户使用云闪付付款,中途取消付款,是会返回在选择支付方式页面 7、支持云闪付优惠 以下为实际支付测试截图 [图片][图片] [图片] 配置了没有云闪付入口等常见问题请看下面地址 https://developers.weixin.qq.com/community/develop/article/doc/000ac04bca8558f9991df282651413
2021-12-29 - 你想要的微信小程序瀑布流组件库:me-waterfall
介绍 me-waterfall 是一个微信小程序瀑布流组件库,实现简单,侵入性小,贴近 web 端的效果。 线上体验 扫描下方的小程序二维码,体验使用效果: [图片] 安装 方式一:使用 npm 安装(推荐) [代码]npm install me-waterfall [代码] 方式二:下载源码 将源码下载到本地,然后将 [代码]lib[代码] 目录拷贝到自己的项目中。 使用方法 在页面的 [代码]json[代码] 文件或 [代码]app.json[代码] 中引入组件: [代码]{ "usingComponents": { "me-waterfall": "/path/to/me-waterfall/waterfall/index", "me-waterfall-item": "/path/to/me-waterfall/waterfall-item/index" } } [代码] 然后就可以在 [代码]wxml[代码] 中直接使用了: [代码]<me-waterfall> <me-waterfall-item wx:for="{{list}}" wx:key="{{index}}"> <image src="{{item.src}}" style="height:{{item.height}}px;width:100%"/> </me-waterfall-item> </me-waterfall> [代码] API waterfall 组件 props 参数 说明 类型 默认值 是否必须 width 容器宽度,传入后将优先使用此值,呈现速度更快 Number - 否 column 列数 Number 2 否 gap 列与列之间的间距 Number 15 否 methods reflow 重新排列元素,在某些情形下,你可能希望在完成某些操作后对瀑布流进行重新排列,此时可以调用此方法: [代码]const waterfallInstance = this.selectComponent("#waterfall"); waterfallInstance.reflow(); [代码] 外部样式类 参数 说明 类型 默认值 是否必须 custom-class 外部样式类 String - 否 waterfall-item 组件 外部样式类 参数 说明 类型 默认值 是否必须 custom-class 外部样式类 String - 否 关于性能 首先,够用; 其次,由于微信小程序中获取元素尺寸的 api 为回调形式,因此排列内部元素时需要延迟,即等到容器宽度取到之后再进行排列,这会使得瀑布流呈现速度减慢;如果改为传入 [代码]width[代码],呈现速度会更快。 捐赠 如果这个库有帮助,请 Star 这个仓库,让更多人发现它。 当然,也可以鼓励我一下: [图片] 开源协议 本项目基于 MIT 协议。
2022-07-25 - 小程序手写签名分享
/* wxss */ page { background-color: #EEEEEE; } /* 详细信息展示样式 */ .page { display: flex; flex-direction: column; justify-content: center; align-items: center; } .container { padding-bottom: 5rpx; } .panel { display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; box-sizing: border-box; width: 710rpx; margin-top: 15rpx; border-radius: 10rpx; background-color: #FFFFFF; } page { --canvas-hight:800px; } .wricont{ width:100%; height:var(--canvas-hight); align-items: center; display: flex; } .canvastyle{ height:100%; width:100%; background-color: #f5f5f5; } <!-- wxml --> <view class="container page"> <view class="panel"> <view class="wricont" style="{{viewData.style}}"> <canvas class="canvastyle" canvas-id="myCanvas" id='myCanvas' bindtouchstart="beg_t" bindtouchmove="move_t"></canvas> </view> <view style="display:flex;align-items:center;height: 50px;"> <button size="mini" type="warn" class="btn1" bindtap="clear">重写</button> <button size="mini" type="default" class="btn2" bindtap="save">确认</button> </view> </view> </view> // json { "usingComponents": {}, "navigationBarTitleText": "签名确认", "disableScroll":true } //js代码 var x = 0 var y = 0 var w = 0 var h = 0 let myStyle = ` --canvas-hight:1000px; ` Page({ data: { viewData: { style: myStyle }, ctx:'', image:[] }, onLoad(options) { var that = this const ctx = wx.createCanvasContext('myCanvas') //获取手机屏幕高度和宽度 wx.getSystemInfo({ success (res) { w = res.windowWidth-28 let h0 = res.windowHeight-110 h = res.windowHeight-120 console.log(w,h) //根据手机高自适应 var chageStyle = `--canvas-hight:`+h0+'px;' that.setData({'viewData.style': chageStyle}) //外线框颜色 ctx.setStrokeStyle('grey') ctx.fill('red') //画一哥矩形 ctx.rect(2, 2, w, h) // 设定虚线(【实线长,虚线长】,虚线偏移量) ctx.setLineDash([10, 10], 5); //矩形线宽 ctx.setLineWidth(2) //画布底色,不设定导出来图片背景默认黑色, ctx.setFillStyle('#f5f5f5') //画布底色大小, ctx.fillRect(2, 2, w, h) ctx.stroke() ctx.draw() that.setData({ ctx:ctx }) } }) }, beg_t(e) { //开始触摸位置, x = e.changedTouches[0].x y = e.changedTouches[0].y console.log(x,y); console.log(e); }, move_t(e) { //开始写 var ctx = this.data.ctx var x1 = e.changedTouches[0].x var y1 = e.changedTouches[0].y //指针移到开始触摸位置 ctx.moveTo(x, y) //线条黑色 ctx.setStrokeStyle('black') //线条宽度 ctx.setLineWidth(5) // 设定虚线(【实线长,虚线长】,虚线偏移量) ctx.setLineDash([10, 0], 5); //画点(x,y)到点(x1,y1) ctx.lineTo(x1, y1) ctx.stroke() // ctx.draw(true) 设定true后,保留前面的draw(),不会被清空。 ctx.draw(true) x = x1 y = y1 this.setData({ ctx:ctx }) console.log(x,y); }, clear:function(){ var that = this var ctx = this.data.ctx //线条颜色 ctx.setStrokeStyle('grey') ctx.rect(2, 2, w, h) // 设定虚线(【实线长,虚线长】,虚线偏移量) ctx.setLineDash([10, 10], 5); //线宽 ctx.setLineWidth(2) ctx.stroke() ctx.draw() that.setData({ ctx:ctx }) }, save:function(){ var that = this wx.canvasToTempFilePath({ x: 2, y: 2, width: w, height: h, destWidth: w, destHeight: h, canvasId: 'myCanvas', success(res) { console.log(res.tempFilePath) that.setData({ ["image[0]"]:res.tempFilePath, }) wx.previewImage({ current:that.data.image[0], urls:that.data.image }); } }) } })
2022-05-11 - 小程序实现列表拖拽排序
小程序列表拖拽排序 [图片] wxml [代码]<view class='listbox'> <view class='list kelong' hidden='{{!showkelong}}' style='top:{{kelong.top}}px'> <view class='index'>?</view> <image src='{{kelong.xt}}' class='xt'></image> <view class='info'> <view class="name">{{kelong.name}}</view> <view class='sub-name'>{{kelong.subname}}</view> </view> <image src='/images/sl_36.png' class='more'></image> </view> <view class='list' wx:for="{{optionList}}" wx:key=""> <view class='index'>{{index+1}}</view> <image src='{{item.xt}}' class='xt'></image> <view class='info'> <view class="name">{{item.name}}</view> <view class='sub-name'>{{item.subname}}</view> </view> <image src='/images/sl_36.png' class='more'></image> <view class='moreiconpl' data-index='{{index}}' catchtouchstart='dragStart' catchtouchmove='dragMove' catchtouchend='dragEnd'></view> </view> </view> [代码] wxss [代码].map-list .list { position: relative; height: 120rpx; } .map-list .list::after { content: ''; width: 660rpx; height: 2rpx; background-color: #eee; position: absolute; right: 0; bottom: 0; } .map-list .list .xt { display: block; width: 95rpx; height: 77rpx; position: absolute; left: 93rpx; top: 20rpx; } .map-list .list .more { display: block; width: 48rpx; height: 38rpx; position: absolute; right: 30rpx; top: 40rpx; } .map-list .list .info { display: block; width: 380rpx; height: 80rpx; position: absolute; left: 220rpx; top: 20rpx; font-size: 30rpx; } .map-list .list .info .sub-name { font-size: 28rpx; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #646567; } .map-list .list .index { color: #e4463b; font-size: 32rpx; font-weight: bold; position: absolute; left: 35rpx; top: 40rpx; } [代码] js [代码]data:{ kelong: { top: 0, xt: '', name: '', subname: '' }, replace: { xt: '', name: '', subname: '' }, }, dragStart: function(e) { var that = this var kelong = that.data.kelong var i = e.currentTarget.dataset.index kelong.xt = this.data.optionList[i].xt kelong.name = this.data.optionList[i].name kelong.subname = this.data.optionList[i].subname var query = wx.createSelectorQuery(); //选择id query.select('.listbox').boundingClientRect(function(rect) { // console.log(rect.top) kelong.top = e.changedTouches[0].clientY - rect.top - 30 that.setData({ kelong: kelong, showkelong: true }) }).exec(); }, dragMove: function(e) { var that = this var i = e.currentTarget.dataset.index var query = wx.createSelectorQuery(); var kelong = that.data.kelong var listnum = that.data.optionList.length var optionList = that.data.optionList query.select('.listbox').boundingClientRect(function(rect) { kelong.top = e.changedTouches[0].clientY - rect.top - 30 if(kelong.top < -60) { kelong.top = -60 } else if (kelong.top > rect.height) { kelong.top = rect.height - 60 } that.setData({ kelong: kelong, }) }).exec(); }, dragEnd: function(e) { var that = this var i = e.currentTarget.dataset.index var query = wx.createSelectorQuery(); var kelong = that.data.kelong var listnum = that.data.optionList.length var optionList = that.data.optionList query.select('.listbox').boundingClientRect(function (rect) { kelong.top = e.changedTouches[0].clientY - rect.top - 30 if(kelong.top<-20){ wx.showModal({ title: '删除提示', content: '确定要删除此条记录?', confirmColor:'#e4463b' }) } var target = parseInt(kelong.top / 60) var replace = that.data.replace if (target >= 0) { replace.xt = optionList[target].xt replace.name = optionList[target].name replace.subname = optionList[target].subname optionList[target].xt = optionList[i].xt optionList[target].name = optionList[i].name optionList[target].subname = optionList[i].subname optionList[i].xt = replace.xt optionList[i].name = replace.name optionList[i].subname = replace.subname } that.setData({ optionList: optionList, showkelong:false }) }).exec(); }, [代码]
2019-07-28 - 如何实现一个自定义导航栏
自定义导航栏在刚出的时候已经有很多实现方案了,但是还有大哥在问,那这里再贴下代码及原理: 首先在App.js的 onLaunch中获取当前手机机型头部状态栏的高度,单位为px,存在内存中,操作如下: [代码]onLaunch() { wx.getSystemInfo({ success: (res) => { this.globalData.statusBarHeight = res.statusBarHeight this.globalData.titleBarHeight = wx.getMenuButtonBoundingClientRect().bottom + wx.getMenuButtonBoundingClientRect().top - (res.statusBarHeight * 2) }, failure() { this.globalData.statusBarHeight = 0 this.globalData.titleBarHeight = 0 } }) } [代码] 然后需要在目录下新建个components文件夹,里面存放此次需要演示的文件 navigateTitle WXML 文件如下: [代码]<view class="navigate-container"> <view style="height:{{statusBarHeight}}px"></view> <view class="navigate-bar" style="height:{{titleBarHeight}}px"> <view class="navigate-icon"> <navigator class="navigator-back" open-type="navigateBack" wx:if="{{!isShowHome}}" /> <navigator class="navigator-home" open-type="switchTab" url="/pages/index/index" wx:else /> </view> <view class="navigate-title">{{title}}</view> <view class="navigate-icon"></view> </view> </view> <view class="navigate-line" style="height: {{statusBarHeight + titleBarHeight}}px; width: 100%;"></view> [代码] WXSS文件如下: [代码].navigate-container { position: fixed; top: 0; width: 100%; z-index: 9999; background: #FFF; } .navigate-bar { width: 100%; display: flex; justify-content: space-around; } .navigate-icon { width: 100rpx; height: 100rpx; display: flex; justify-content: space-around; } .navigate-title { width: 550rpx; text-align: center; line-height: 100rpx; font-size: 34rpx; color: #3c3c3c; font-weight: bold; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } /*箭头部分*/ .navigator-back { width: 36rpx; height: 36rpx; align-self: center; } .navigator-back:after { content: ''; display: block; width: 22rpx; height: 22rpx; border-right: 4rpx solid #000; border-top: 4rpx solid #000; transform: rotate(225deg); } .navigator-home { width: 56rpx; height: 56rpx; background: url(https://qiniu-image.qtshe.com/20190301home.png) no-repeat center center; background-size: 100% 100%; align-self: center; } [代码] JS如下: [代码]var app = getApp() Component({ data: { statusBarHeight: '', titleBarHeight: '', isShowHome: false }, properties: { //属性值可以在组件使用时指定 title: { type: String, value: '青团公益' } }, pageLifetimes: { // 组件所在页面的生命周期函数 show() { let pageContext = getCurrentPages() if (pageContext.length > 1) { this.setData({ isShowHome: false }) } else { this.setData({ isShowHome: true }) } } }, attached() { this.setData({ statusBarHeight: app.globalData.statusBarHeight, titleBarHeight: app.globalData.titleBarHeight }) }, methods: {} }) [代码] JSON如下: [代码]{ "component": true } [代码] 如何引用? 需要引用的页面JSON里配置: [代码]"navigationStyle": "custom", "usingComponents": { "navigate-title": "/pages/components/navigateTitle/index" } [代码] WXML [代码]<navigate-title title="青团社" /> [代码] 按上面步骤操作即可实现一个自定义的导航栏。 如何实现通栏的效果默认透明以及滚动更换title为白色背景,如下图所示: [图片] [图片] [图片] [图片] 最后代码片段如下: https://developers.weixin.qq.com/s/wi6Pglmv7s8P。 以下为收集到的社区老哥们的分享: @Yunior: 小程序顶部自定义导航组件实现原理及坑分享 @志军: 微信小程序自定义导航栏组件(完美适配所有手机),可自定义实现任何你想要的功能 @✨o0o有脾气的酸奶💤 [有点炫]自定义navigate+分包+自定义tabbar @安晓苏 分享一个自适应的自定义导航栏组件
2020-03-10