前端學習之路——uniapp+小白接口開發跨端應用筆記

需求簡述

這是一個仿多抓魚掃碼賣書的小程序,結合了uniapp和小白接口的使用。賣書流程的實現爲用戶打開應用後掃描圖書後面的ISBN條形碼,得到的數據通過小白接口在自定義數據模型(實際上類似一張數據表)查詢比對。如果該數據與已有數據中有吻合的,則進入下一頁面,將該圖書相關信息(重要的是回收價)展示給用戶,其後用戶選擇回收書籍,此時則將在登錄時緩存在本地的用戶名(username)、用戶全局id(uuid)以及回收書籍的相關信息發送到一張圖書回收表中(後期返回數據應包含緩存在本地的用戶拓展信息如聯繫方式、地址等),由工作人人工與用戶進行聯繫回收。

此項需求大概用到的技術如下:vue相關,uniapp相關,小白接口有用戶模塊的登錄接口(App.User.Login)、註冊接口(App.User.Register)、獲取用戶個人資料(App.User.Profile)、修改用戶擴展信息(App.User.UpdateExtInfo),其他的主要爲幾個元數據接口以及自定義模型的通用接口,後期可能會使用到直連數據庫接口。

筆記一 uni.reques成功回調函數的數據如何顯示在模板中

這是我在調用接口返回的數據想在頁面中輸出時遇到的問題,似乎有一些作用域的問題,有些複雜。經過不斷的摸索,得出以下解決方案,背後的原理則需要繼續思考:

onLoad() {//這是頁面加載時的方法,在此處調用接口獲取頁面填充數據
			let that = this;//關鍵步驟
			uni.request({
				url: 'http://hd215.api.okayapi.com/?s=App.Main_Meta.Get&',//接口url
				method: 'GET',
				data: {
					//接口請求數據
					key: '',
					app_key: '',			
				},
				success: (res) => {
					var a = res.data.data;
					//console.log(a);
					that.text = a;//將回調數據賦給全局作用域上的text對象,此對象需提前在data中初始化
					uni.showToast({
						title: '查詢成功!',
						mask: true,
						duration: 1500
					});
				},
			});
		},

在data中初始化需要的對象

data() {
			return {
				title: '首頁',
				background: ['color1', 'color2', 'color3'],
				indicatorDots: true,
				autoplay: true,
				interval: 2000,
				duration: 500,
				reload: true,
				listData: [],
				text: {},//初始化text對象
			}
		},

在頁面中調用

<view class="uni-media-list-text-top" >{{text.data.content}}</view><!--注意此處無需聲明this,直接調用即可-->

筆記二 uniapp頁面傳參

上述需求中提出的掃描圖書後面的ISBN條形碼,得到的數據通過小白接口在自定義數據模型(實際上類似一張數據表)查詢比對。如果該數據與已有數據中有吻合的,則進入下一頁面,將該圖書相關信息(重要的是回收價)展示給用戶這項需求的實現可以需要用到uniapp頁面傳參。因爲在查詢時實際上是根據圖書ISBN與數據表中的ISBN字段進行篩選,然後返回符合條件的數據行,這一行數據實際上已經包含了在書籍回收詳情頁中所需的書籍相關信息,因此爲簡化程序及減少接口調用次數,增加運行效率,我們不應該僅僅只將圖書的ISBN傳遞到下一頁面,在下一頁面根據此ISBN再一次調用接口,而是應該將在掃碼頁面所能獲取到的所有有用信息通過uniapp頁面傳參的方式傳遞到下一頁面進行使用。當然,除了頁面傳參還有一個笨方法,那就是將接口成功的回調函數獲得的數據緩存到本地,在下一頁面中調用緩存中的數據,但此方法效率與頁面傳參確實要低很多,現在來看具體操作細節。

在post.vue頁面(掃碼驗證頁面)使用uniapp的掃碼接口uni.scanCode,在其回調函數中獲取掃碼結果調用查詢接口,成功則將數據傳遞到下一頁面並跳轉。

//post.vue
<template>
	<view>
		<button class="btn-scan" type="primary" @tap="scan">掃碼賣書</button>
	</view>
</template>		
<script>
	
	export default {
		data() {
			return {
				ISBN: '',//初始化重要數據
			};
		},
		onLoad : function() {
			var loginRes = this.checkLogin('../login/login', '2');//檢查用戶登錄狀態
			if(!loginRes){
				return false;
				uni.showModal({
				    title: '未登錄',
				    content: '您未登錄,需要登錄後才能繼續',
				    /**
				     * 如果需要強制登錄,不顯示取消按鈕
				     */
				    showCancel: false,
				    success: (res) => {
				        if (res.confirm) {
							/**
							 * 如果需要強制登錄,使用reLaunch方式
							 */
				            if (this.forcedLogin) {
				                uni.reLaunch({
				                    url: '../login/login'
				                });
				            }
				        }
				    }
				});
			}else{
				// console.log(loginRes);
				//在本地緩存中緩存用戶信息
				this.userId = uni.getStorageSync('userlogin');
				// console.log(this.userInfo);
				this.userInfo = uni.getStorageSync('userInfo');
				console.log(this.userInfo);
			}
				
		},
		methods: {
			scan() {
				uni.scanCode({
					scanType: ['barCode'],
					success: function (res) {
						
						console.log('條碼內容:' + res.result);
						uni.request({
							url: 'http://hd215.api.okayapi.com/?&service=App.Table.FreeFindOne&',//接口url
							method: 'GET',
							data:{
								//調用接口數據
								model_name: '',
								where: [["book_ISBN","=",res.result]],
								app_key: ''
							},
							success: function(ret) {
								if(res.result == ret.data.data.data.book_ISBN){
									//檢查返回數據是否與圖書表中ISBN相符
									// console.log(ret.data);
									var bookInfo = ret.data.data.data;
									uni.navigateTo({
										url: "../maishuDetail/maishuDetail?info="+JSON.stringify(bookInfo)//重要步驟,將接口返回數據(json對象)通過JSON.stringify()轉化爲字符串,在下一頁面的onload方法中接收此字符串
									});
									uni.showToast({
										title: '查詢成功!',
										mask: true,
										duration: 1500
									});
								}else{
									uni.showToast({
										title: '查詢失敗!',
										mask: true,
										duration: 1500
									});
								}
							},
						});
					}
				});
			},
		}
	}
</script>

在maishuDetail.vue(賣書詳情頁)中接收post.vue 傳遞過來的參數並展示在詳情頁面中,並準備用戶提交的相關信息。

//maishuDetail.vue
<template>
	<view>
		<view>書名:{{test.book_name}}</view>
		<view>ISBN:{{test.book_ISBN}}</view>
		<view>作者:{{test.book_author}}</view>
		<view>出版社:{{test.book_chubanshe}}</view>
		<view>原價:¥{{test.book_oldprice}}</view>
		<view>回收價:¥{{test.book_price}}</view>
		<button type="default" @tap="maiShu">回收書籍</button>
		<view>打印{{consol}}</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				test: {},//初始化頁面展示信息,爲一個對象
				consol: '',//由於hbuilder真機調試時不能直接在控制檯輸出詳細信息,因此將回調數據在此處聲明並在頁面中顯示
			};
		},
		onLoad: function (option) { //option爲object類型,會序列化上個頁面傳遞的參數
			this.test = JSON.parse(option.info);//接收post.vue頁面傳遞過來的參數,並將字符串的json對象轉化爲js對象方便頁面顯示調用。
			this.userInfo = uni.getStorageSync('userInfo');//獲取用戶的相關信息
		} ,
		methods: {
			maiShu() {
				let that = this;//參照筆記一 uni.reques成功回調函數的數據如何顯示在模板中的相關方法,打印回調信息調試
				var bookSale = {};//準備書籍相關信息的傳遞,先初始化對象,實際傳遞時需將此對象轉化爲字符串
				bookSale.book_saleUUID = this.userInfo.uuid;//注意對象屬性的鍵要與模型(數據表)中的字段吻合
				bookSale.book_saleUNMAE = this.userInfo.username;
				bookSale.book_saleISBN = this.test.book_ISBN;
				bookSale.book_saleBKNAME = this.test.book_name;
				bookSale.book_salePrice = this.test.book_price;
				var jsonData = JSON.stringify(bookSale);//字符串對象,方便傳遞
				uni.request({
					url:'http://hd215.api.okayapi.com/?service=App.Table.Create&',
					method: 'GET',
					data: {
						//接口參數
						model_name: 'book_saleUser',
						data: jsonData,
						app_key: '',
					},
					success:function(res){
						
						that.consol = JSON.stringify(res.data);//字符串後方便在頁面中顯示回調信息,方便調試
						
					}
				})
			}
		}
	}
</script>

…未完待續

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章