uniapp 开发一些实际经验

前言

每个端,有每个端的管理规则,这不是uni-app在技术层面上可以抹平的:

  • 比如H5端的浏览器有跨域限制;
  • 比如微信小程序会强制要求https链接,并且所有要联网的服务器域名都要配到微信的白名单中;
  • 比如App端,iOS对隐私控制和虚拟支付控制非常严格;
  • 比如App端,Android、国产rom各种兼容性差异,尤其是因为谷歌服务被墙,导致的push、定位等开发混乱的坑;

1 设备状态栏高度statusBarHeight

statusBarHeight: uni.getSystemInfoSync().statusBarHeight // 精确度比css变量的高

2 跳转页面携带对象参数,一定要encodeURIComponent编码->兼容小程序!(传参携带的?、&这些特殊符号)

uni.navigateTo({
	url: 'chooseShopGood?shopInfo=' + encodeURIComponent(JSON.stringify(this.shopInfo))
})

如果不 encodeURIComponent,微信小程序就报错了!

接收端解码decodeURIComponent

onLoad(options) {
	if (options.shopInfo) {
		this.shopInfo = JSON.parse(decodeURIComponent(options.shopInfo))
		this.shopId = this.shopInfo.shopId
	}
},

如果传参携带的?、&这些特殊符号,一定要记得编码与解码

3 canvas画图

drawImage无图问题:用本地图片解决跨域:H5与微信小程序

网络图片要uni.getImageInfo(OBJECT),小程序下获取网络图片信息需先配置download域名白名单才能生效。返回 res.path 就是我们drawImage的图片地址了(getImageInfo用static地址是错误路径的(分包),所以最好是网络地址)

image 查看效果

<image :src="inviteCodePosterImagePath" :style="{width:100+'px',height:100+'px'}" />

ctx.setFillStyle('transparent'); 不能设为透明,不然图片就看不到了!

下面代码只是参考,最后还是要下载插件的,因为插件里有画圆角矩形框的!

		handlePoster(type) {
			let that = this
			if(this.inviteCodePosterImagePath) {
				uni.hideLoading()
				if (type === 1) {
					this.saveImage(this.inviteCodePosterImagePath)
				} else if (type === 2) {
					// #ifdef H5
					uni.showToast({
						icon: 'none',
						title: '请下载APP使用此功能'
					});
					// #endif
					// #ifdef APP-PLUS
					uni.share({
						provider: 'weixin',
						scene: 'WXSceneSession',
						type: 2,
						imageUrl: that.inviteCodePosterImagePath,
						success: function(res) {
							console.log('success:' + JSON.stringify(res));
						},
						fail: function(err) {
							console.log('fail:' + JSON.stringify(err));
						}
					});
					// #endif
					// #ifdef MP-WEIXIN 
					console.log('分享')
					wx.showShareImageMenu({
					   path: that.inviteCodePosterImagePath,
					   complete: function(res) {
							console.log(res);
						}
					})
					// #endif
				}
			} else {
				//#ifdef MP-WEIXIN
				uni.showLoading({
					title: '图片生成中'
				});
				uni.getImageInfo({
					src: 'https://jhoss.zgtgex.com/static/assets/images/user/22-200.png',
					success: function (image) {
						if(image.path) {
							that.canvasPoster(type,image.path)
						} else {
							uni.showToast({
								title: '失败',
								icon: 'none'
							});
						}
					}
				});
				//#endif
				
				//#ifdef H5 || APP-PLUS
				that.canvasPoster(type,'/static/assets/images/user/22-200.png')
				//#endif
			}
		},
		canvasPoster(type,posterBgImgPath) {
			console.log('canvasPoster')
			let that = this
			let ctx = uni.createCanvasContext('inviteCode', this);
			ctx.setFillStyle("#ffffff");
			ctx.fillRect(0, 0, 200, 340); // fillRect(x,y,宽度,高度)
			ctx.drawImage(posterBgImgPath, 0, 0, 200, 340);
			ctx.restore();
			
			ctx.setFontSize(16); // 字号
			ctx.setFillStyle('#fff'); // 颜色
			ctx.fillText('面对面扫码邀请', 44, 30); // (文字,x,y)

			ctx.setFontSize(14); // 字号
			ctx.setFillStyle('#333'); // 颜色
			ctx.fillText('扫描二维码进行注册', 36, 280); // (文字,x,y)
			ctx.setFontSize(16); // 字号
			ctx.setFillStyle('#333'); // 颜色
			ctx.fillText('我的邀请码:' + this.userInfo.inviteCode, 30, 310); // (文字,x,y)

			ctx.rect(15, 70, 170, 170);
			ctx.setFillStyle('#ffffff');
			ctx.fill();

			ctx.drawImage(this.codeBase64, 25, 80, 150, 150);
			ctx.draw(true, ret => {
				setTimeout(()=>{
					uni.canvasToTempFilePath({
						width: 200,
						height: 340,
						canvasId: 'inviteCode',
						quality: 1,
						complete: res => {
							that.inviteCodePosterImagePath = res.tempFilePath
							that.handlePoster(type) 
						}
					},this);
				},500)
				
			},500);
		},

4 微信小程序图片分享(分享canvas画图)

// #ifdef MP-WEIXIN 
console.log('分享')
wx.showShareImageMenu({
	path: that.inviteCodePosterImagePath,
	complete: function(res) {
		console.log(res);
	}
})
// #endif

5 保存图片到相册

saveImage(path) {
			// #ifdef H5
			var oA = document.createElement('a');
			oA.download = '邀请码'; // 设置下载的文件名,默认是'下载'
			oA.href = path;
			document.body.appendChild(oA);
			oA.click();
			oA.remove(); // 下载之后把创建的元素删除
			return;
			// #endif
		
			// #ifndef H5
			uni.saveImageToPhotosAlbum({
				filePath: path,
				success: function() {
					uni.showToast({
						title: '保存成功',
						icon: 'success',
						duration: 2000
					});
				}
			});
			// #endif
		},

6 小程序右边胶囊的尺寸信息

let menuButtonInfo = {};
let systemInfo = uni.getSystemInfoSync();
// 如果是小程序,获取右上角胶囊的尺寸信息,避免导航栏右侧内容与胶囊重叠(支付宝小程序非本API,尚未兼容)
// #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ
menuButtonInfo = uni.getMenuButtonBoundingClientRect();
this.rightButtonWidth = systemInfo.windowWidth - menuButtonInfo.left;
// #endef

7 有弹窗的分享(直接分享、海报分享)

8 scroll-view回到顶部

<scroll-view scroll-y="true" class="sv" :style="{'height': 'calc(100% - ' + scrollHeight+'px)' }"
			:scroll-into-view="topItem" @scroll="scroll" scroll-with-animation @scrolltolower="searchListMore">
    <view id="all"></view>
    <view class="list-box" v-for="(item, index) in dataList" :key="index"         @click="Util.goto(`/pages/goods/info?goods_id=${item.goods_id_}`, 'navigateTo')">
    </view>
</scroll-view>

data() {
	return {
        topItem: '', // 初始一定要为空,scroll-into-view才不受影响
    }
},
methods: {
    scroll(e) {
        this.topItem = '' // 滚动以后就置空,这样每一次的topItem = 'all',才会生效!
    },
    // 列表接口: 主要是第一页的时候,要置顶
    searchList() {
        if (this.searchForm.page == 1) {
			this.dataList = []
			this.$nextTick(() => {
				this.topItem = 'all'
			});
	    }
    },

}

9 抖音小程序查看发票

invoiceShow(){ // 查看发票
    var that = this
    tt.downloadFile({
		url: 'https://xxxxx.pdf',
		success: function (res) {
			const filePath = res.tempFilePath
			tt.openDocument({
			filePath: filePath,
			success: function (res) {
				console.log("打开文档成功")
			},
		})},
	})
},

// 微信也有wx.openDocument

猜你喜欢

转载自blog.csdn.net/weixin_43991241/article/details/128996574