uniapp初级入门-05模拟商城完结篇
  px8Y25gMnWbQ 2023年12月23日 13 0


这个代码就是基本完结了。我把全部代码都贴出来,供大家参考学习。

项目情况截图

uniapp初级入门-05模拟商城完结篇_Data

uniapp初级入门-05模拟商城完结篇_Data_02

uniapp初级入门-05模拟商城完结篇_List_03

代码

api

home index.js

import request from '@/api/request.js'

 export const getBannerAds = () => {
	return request({
		url:'/lejuClient/home/bannerAds',
		method: 'GET'
	})
}

export const doLogin = (data) => {
	return request({
		url:'/lejuClient/login/doLogin',
		method: 'POST',
		data: data
	})
}

export const findCategory = (id) => {
	return request({
		url:'/lejuClient/productCategory/findCategory/' + id,
		method: 'GET'
	})
}

export const getHotList = ()=> {
	return request({
		url:'/lejuClient/home/hotList',
		method: 'GET'
	})
}

info index.js

import request from '@/api/request.js'


export const getDetail = (productId)=> {
	return request({
		url: '/lejuClient/product/productDetail/' + productId,
		method: 'GET'
	})
}

export const addCart = (data)=> {
	return request({
		url:'/lejuClient/cart/addCart',
		method: 'POST',
		data: data
	})
}

export const addPreOrder = (data)=> {
	return request({
		url: '/lejuClient/order/addPreOrder',
		method: 'POST',
		data: data
	})
}

kind goods goods.js

import request from '@/api/request.js'


export const getProductList = (start,limit,data)=> {
	return request({
		url:`/lejuClient/product/findProductList/${start}/${limit}`,
		method:'POST',
		data:data
	})
}

kind list list.js

import request from '@/api/request.js'

export const getCategory = (categoryId)=>{
	return request({
		url:'/lejuClient/productCategory/findCategory/' + categoryId,
		method: 'GET'
	})
}


export const getProductList = (start,limit,data)=> {
	return request({
		url:`/lejuClient/product/findProductList/${start}/${limit}`,
		method:'POST',
		data:data
	})
}

kind index.js

import request from '../request.js'

export const getAllCategory = ()=> {
	return request({
		url:'/lejuClient/productCategory/findAllCategory'
	})
}

mine login login.js

import request from '@/api/request.js'

export const doLogin = (data)=> {
	return request({
		url:'/lejuClient/login/doLogin',
		method: 'POST',
		data: data
	})
}

mine register index.js

import request from '@/api/request.js'

export const doRegister = (data)=> {
	return request({
		url:'/lejuClient/member/register',
		method:'POST',
		data: data
	})
}

mine index.js

import request from '@/api/request.js'

export const getMemberInfo = ()=>{
	return request({
		url:'/lejuClient/login/getMemberInfo',
		method: 'GET'
	})
}

order addres index.js

import request from '@/api/request.js'

export const getAllAddress = ()=> {
	return request({
		url:'/lejuClient/address/findAllAddress',
		method: 'GET'
	})
}

order index.js

import request from '@/api/request.js'

export const getPreOrderById = (orderId)=> {
	return request({
		url:'/lejuClient/order/getPreOrderById/' + orderId,
		method: 'GET'
	})
}

export const addConfirmOrder = (data)=> {
	return request({
		url:'/lejuClient/order/addConfirmOrder',
		method: 'POST',
		data: data
	})
}

baseurl.js

let baseUrl = "";

if(process.env.MODE_ENV == 'development'){
	console.log("开发环境");
	baseUrl = "http://leju.bufan.cloud";
}else{
	console.log("生产环境");
	baseUrl = "http://leju.bufan.cloud";
}

export default baseUrl

request.js

import baseUrl from '@/api/baseUrl.js'

let instance  = (config) => {
	return new Promise((resolve,rejected)=>{
		uni.request({
			url: baseUrl + config.url,
			timeout: 5000,
			data:config.data,
			method: config.method,
			header:{
				token: uni.getStorageSync("b-token")
			},
			success(res){
				if(res.data.success == false){
					uni.showToast({
						title:res.data.message,
						icon:'none',
						mask: true,
						duration: 3000
					})
				}else{
					resolve(res.data);
				}
			}
		})
	})
}

export default instance;

minxins

index.js

let obj = {
	methods:{
		checkLogin(){
			let token = uni.getStorageSync("b-token");
			if(token){
				let userInfo = uni.getStorageSync("b-userInfo");
				this.userInfo = userInfo;
				return true;
			}else{
				uni.showModal({
					title:'登录提示',
					content:'暂未登录,是否重新登录',
					success(res) {
						//console.log(res)
						if(res.confirm){
							//清空本地数据
							uni.clearStorageSync();
							uni.navigateTo({
								url:'/pages/mine/login/login'
							});
						}else{
							uni.showToast({
								title:'已取消登录',
								icon:'error'
							});
							uni.clearStorageSync();
						}
					}
				})
				return false;
			}
		}
	}
}

export default obj

pages

find find.vue

<template>
	<view>

	</view>
</template>

<script>
	import mix from '@/minxins/index.js'
	
	export default {
		data() {
			return {
				
			};
		},
		mixins:[mix],
		onShow() {
			this.checkLogin();
		}
	}
</script>

<style lang="scss" scoped>

</style>

home home.vue

<template>
	<view>
		<view class="nav-area">
			<!-- 这里状态栏 -->
		</view>
		<!-- 轮播图 -->
		<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" circular>
			<swiper-item v-for="item in barnerList" :key="item.id">
				<img :src="item.pic" alt="" style="width:100%;">
			</swiper-item>
		</swiper>
		<!-- <button type="default" @tap="login">登录</button> -->
		<!-- <button type="default" @tap="doFind">获取分类</button> -->
		<view class="box">
			
		</view>
		
		<view class="parent">
			<view v-for="item in 6" :key="item">
				{{ item}}
			</view>
		</view>
		
		<swiper 
			:indicator-dots="true" 
			:autoplay="true" 
			:interval="3000" 
			:duration="1500" 
			circular 
			:display-multiple-items="3" >
			<swiper-item v-for="item in hotList" :key="item.id">
				<image :src="item.pic" mode="" style="width:95%;"></image>
			</swiper-item>
		</swiper>
	</view>
</template>

<script>
	import { getBannerAds, doLogin, findCategory, getHotList} from '@/api/home/index.js'
	
	export default {
		data() {
			return { 
				barnerList:[],
				hotList:[],
			};
		},
		methods: {
			// login(){
			// 	doLogin({
			// 		username:'17596496508',
			// 		password: '123456'
			// 	}).then(res=>{
			// 		//console.log(res)
			// 	});
			// },
			// doFind(){
			// 	findCategory(1).then(res=>{
			// 		//console.log(res)
			// 	})
			// }
		},
		onLoad(options) {
			getBannerAds().then(res=>{
				this.barnerList = res.data.items;
			})
			
			getHotList().then(res=>{
				console.log(res);
				this.hotList = res.data.items;
			})
		}
	}
</script>

<style lang="scss">
	.nav-area{
		height: var(--status-bar-height);
		width: 100%;
	}
	
.box{
	width: 208rpx;
	height: 140rpx;
	background-color: $uni-bg-color-hover;
}

.parent {
	display: flex;
	align-items: center;
	overflow-x: auto;
	view{
		height: 200rpx;
		width: 300rpx;
		background-color: gray;
		flex-shrink: 0;
	}
}
</style>

index index.vue

<template>
	<view class="content">
		<view>
			{{text}}
		</view>
		<view v-text="text">
			
		</view>
		<view v-for="item in list" :key="item.name" @tap="printName(item)">
			{{item.name}}
		</view>
		
		<view v-show="isShow">这是一行文字</view>
		<button type="default" @tap="toggleText">点击控制文字显示与隐藏</button>
		
		<view :class="{red:isActive}">文字颜色会变化</view>
		<button type="default" @tap="changeColor">点击变换颜色</button>
		
		<view :style="{color:isChange ? 'red':''}">内联样式变化文字颜色</view>
		<button type="default" @tap="changeStyle">点击变换style</button>
	</view>
</template>

<script>
	export default {
		data(){
			return {
				isChange:false,
				isActive:false,
				isShow: true,
				text:'张三',
				list:[
					{name:'苹果'},
					{name:'香蕉'},
					{name:'橘子'},
					{name:'火龙果'},
				]
			}
		},
		methods: {
			changeStyle(){
				this.isChange = !this.isChange
			},
			changeColor(){
				this.isActive = !this.isActive;
			},
			toggleText(){
				this.isShow = !this.isShow;
			},
			printName(obj){
				console.log(obj.name);
			}
		}
	}
</script>

<style>
	.red{
		color: red;
	}
</style>

info info.vue

<template>
	<view class="info">
		<swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" circular>
			<swiper-item v-for="(item,index) in albumPics" :key="index">
				<view class="swiper-item">
					<img :src="item" alt="" style="width: 100%;">
				</view>
			</swiper-item>
		</swiper>
		<view class="row">商品名称:{{productData.name}}</view>
		<view class="row">商品价格:¥{{productData.price}}</view>
		<view class="row">商品描述:{{productData.description}}</view>
		<view class="row">明细标题:{{productData.detailTitle}}</view>
		<view class="row">明细描述:{{productData.detailDesc}}</view>
		<view class="row">品牌名称:{{productData.brandName}}</view>
		<view class="row">品牌目录:{{productData.productCategoryName}}</view>
		<mp-html :content="productData.detailMobileHtml"></mp-html>
		
		<view class="mask" @touchmove.stop.prevent v-if="isMaskShow">
			<view class="box">
				<image :src="picUrl" mode="" class="pic"></image>
				<uni-icons type="close" @tap="isMaskShow = false" style="position: absolute;right: 120rpx;top: 260rpx;"></uni-icons>
				<view>商品选择</view>
				<view class="sp-data">
					<view 
						v-for="(item,idx) in productData.skuList" 
						:key="item.id" 
						class="sp-data-row" 
						:class="spDataSelectedIndex == idx ? 'active': ''" @tap="spDataSelect(idx)">
						<text v-for="(ele,index) in item.spData" :key="index" class="sp-data-item">
							{{ele.key}}:{{ele.value}}
						</text>
					</view>
				</view>
				<view style="width: 60%;margin: 0 auto;">
					<button type="warn" size="default" @tap="confirm">购买</button>
				</view>
			</view>
		</view>
		
		<view class="fixed-btn">
			<uni-icons type="headphones" class="btn-icon"></uni-icons>
			<button type="default" class="btn-cart" @tap="addCart(0)">添加至购物车</button>
			<button type="primary" class="btn-buy" @tap="goBuy(1)">立即购买</button>
		</view>
	</view>
</template>

<script>
	import { getDetail, addCart, addPreOrder } from '@/api/info/index.js'
	import mix from '@/minxins/index.js'
import { registerRuntimeCompiler } from "vue";
	
	export default {
		
		mixins:[mix],
		data() {
			return {
				currentTap:0, //0购物车,1立即购买
				picUrl:'',
				spDataSelectedIndex: null,
				isMaskShow: false,
				productId:null,
				productData: {},
				albumPics:[],
				obj:{
					img:"width:90%;"
				}
			};
		},
		methods:{
			//确认购买
			confirm(){
				//先判断是否登录
				if(!this.checkLogin()){
					return;
				}
				//判断是否选择了规格
				if(this.spDataSelectedIndex == null) {
					uni.showToast({
						title:'请选择规格',
						icon:'error'
					});
					return;	
				}
				//获取sku
				let sku = this.productData.skuList[this.spDataSelectedIndex];
				
				if(this.currentTap == 0){
					console.log('添加至购物车')
					
					
					addCart({
						  productId: sku.productId,
						  productSkuId: sku.id,
						  quantity: 1  //默认了
					}).then(res=>{
						console.log(res)
						uni.showToast({
							title:res.message,
							icon:'success'
						});
						this.isMaskShow = false;
					})
				}else if(this.currentTap == 1){
					console.log('立即购买');				
					addPreOrder({
						  addressId: "",
						  orderId: "",
						  orderItemList: [
						    {
						      cartId: "",
						      productId: sku.productId,
						      productQuantity: 1,
						      productSkuId: sku.id
						    }
						  ],
						  payType: 0,
						  sourceType: 1
					}).then(res=>{
						console.log(res);
						this.isMaskShow = false;
						uni.showToast({
							title:`下单${res.message},订单号是${res.data.orderId}`,
							icon:'none',
							mask:true,
							duration:2000
						});
						setTimeout(()=>{
							uni.navigateTo({
								url:'/pages/order/order?orderId=' + res.data.orderId
							});
						},2000);
						
					})
				}
				
				
			},
			//选中
			spDataSelect(index){
				this.spDataSelectedIndex = index;
				this.picUrl = this.productData.skuList[index].pic;
				
			},
			//添加至购物车
			addCart(val){
				this.goBuy(val);
			},
			//立即购买
			goBuy(val){
				this.currentTap = val;
				this.isMaskShow = !this.isMaskShow;
				
				
			}
		},
		onLoad(options) {
			this.productId = options.id
			getDetail(this.productId).then(res=>{
				console.log(res)
				res.data.product.skuList.forEach(ele=>{
					ele.spData = JSON.parse(ele.spData);
				});
				
				this.productData = res.data.product;
				this.albumPics = this.productData.albumPics.split(",");
				uni.setNavigationBarTitle({
					title: this.productData.name
				});
			
			})
		}
	}
</script>

<style lang="scss">
	.info{
		
		.row{
			min-height: 100rpx;
			width: 100%;
			font-size: 18px;
			padding: 10px 10px;
			margin-bottom: 20rpx;
			margin-top: 10rpx;
		}
		
		.mask{
			width: 100%;
			height: 100vh;
			position: fixed;
			top: 0;
			left: 0;
			z-index: 999;
			background-color: rgba(0,0,0,0.6);
			display: flex;
			align-items: center;
			justify-content: center;
			.box{
				width: 80%;
				min-height: 1000rpx;
				margin: 0 auto;
				background-color: #fff;
				
				.pic{
					width: 240rpx;
					height: 240rpx;
					border: 2px solid #FFC6CC;
					border-radius: 100rpx;
					position: relative;
					top: -90rpx;
					left: 60rpx;
					background-color: #FFC6CC;
					
				}
				
				.sp-data{
					height: 500rpx;
					overflow-y: scroll;
					
					.sp-data-row{
						height: 60rpx;
						line-height: 60rpx;
						width: 100%;
						margin: 15rpx 0;
						padding-left: 40rpx;
						box-sizing: border-box;
						
						.sp-data-item{
							margin-left: 25rpx;
							border: 1px solid green;
							border-radius: 10rpx;
							padding: 10rpx;
							height: 40rpx;
							font-size: 14px;
						}
								
					}
					
					.active{
						background-color: #E2E2E2;
					}
				}
			}
		}
		
		.fixed-btn{
			display: flex;
			align-items: center;
			position: fixed;
			bottom: 0;
			left: 0;
			width: 100%;
			border: 1px solid #cccccc;
			padding: 10px;
			background-color: #fff;
			button{
				width: 40%;
				margin: 0;
				border-radius: 0;
			}
			.btn-icon{
				width: 15%;
			}
			
			.btn-cart{
				background-color: #E2E2E2;
			}
			.btn-buy{
				background-color: #344B44;
			}
		}
	}

</style>

kind goods goods.vue

<template>
	<view>
		<view class="tab">
			<view class="tab-item" v-for="(item,index) in tabList" :key="index">
				<view :class="{active: index == currentTabIndex }" @tap="tabClick(index)">
					{{item.name}}
				</view>
				<view v-if=" item.name == '销量' || item.name == '价格'" class="icon-box">
					<uni-icons type="up" size="16" :color="item.current == 'up'?'#dd524d': ''"></uni-icons>
					<uni-icons type="down" size="16" :color="item.current == 'down'?'#dd524d': ''"></uni-icons>
				</view>
			</view>
		</view>
		<ul class="product-area">
			<li v-for="item in productList" :key="item.id" @tap="goInfo(item)">
				<img :src="item.pic" alt="" />
				<view>{{item.name}}</view>
				<view>¥{{item.price}}</view>
				<view>{{item.brandName}}</view>
			</li>
		</ul>
	</view>
</template>

<script>
	import { getProductList } from '@/api/kind/goods/goods.js'
	
	export default {
		data() {
			return {
				total: 0,
				start: 1,
				limit: 4,
				sortBy:'',
				desc: 0,
				currentTabIndex: 0,
				categoryId: 0,
				productList:[],
				tabList:[
					{
						name:'新品',
						current:'default', //default up down
					},
					{
						name:'销量',
						current:'default', //default up down
					},
					{
						name:'价格',
						current:'default', //default up down
					},
					{
						name:'筛选',
						current:'default', //default up down
					},
				]
			}
		},
		methods: {
			goInfo(item){
				console.log(item)
				uni.navigateTo({
					url:'/pages/info/info?id=' + item.id
				})
			},
			tabClick(index){
				//重置数据
				this.productList = [];
				//当前索引保存起来
				this.currentTabIndex = index;
				//除了当前点击项,其余项恢复默认标识
				this.tabList.forEach((ele,idx)=>{
					if(idx != index){
						ele.current = 'default';
					}
				});
				
				//获取当前项
				let item = this.tabList[index];
				//判断是升序,还是降序
				if(item.current == 'default'){
					this.tabList[index].current = 'up';
					this.desc = 0; //升序
				}else if(item.current == 'up'){
					this.tabList[index].current = 'down';
					this.desc = 1; //降序
				}else {
					this.tabList[index].current = 'up';
					this.desc = 0; //升序
				}
				
				//判断是销量排序,还是价格排序
				if(item.name =='销量'){
					this.sortBy = 'sale'
				}else if(item.name =='价格'){
					this.sortBy = 'price'
				}
				//请求接口获取数据
				this.getData();
			},
			getData(){
				let data = {
				  "brandId": "",
				  "categoryId": this.categoryId,
				  "isDesc": this.desc,
				  "keywords": "",
				  "sortBy": this.sortBy
				}
				//调用接口函数
				getProductList(this.start,this.limit,data).then(res=>{
					//console.log(res)
					this.productList.push(...res.data.rows);
					this.total = res.data.total;
					uni.stopPullDownRefresh();
				})
			}
		},
		onLoad(options) {
			//从页面传参中获取id
			this.categoryId = options.id;
			//然后获取数据
			this.getData();
		},
		//上拉加载
		onReachBottom(){
			//判断目前数据小于总数据时,继续获取数据
			if(this.productList.length < this.total){
				this.start += 1;
				this.getData();
			}else
			{
				console.log("没有更多了")
			}
			
		},
		//下拉刷新
		onPullDownRefresh(){
			this.start = 1;
			this.productList = [];
			this.getData();
			
		}
	}
</script>

<style lang="scss">
	.tab{
		display: flex;
		align-items: center;
		justify-content: space-around;
		padding: 10px 0;
		.tab-item{
			display: flex;
			align-items: center;
			.icon-box{
				display: flex;
				align-items: center;
				justify-content: center;
				flex-direction: column;
			}
			.active{
				color: #dd524d;
			}
		}
	}
	
.product-area{
	list-style: none;
	width: 100%;
	padding: 10rpx;
	li{
		width: 45%;
		height: 600rpx;
		float: left;
		border: 1px solid gray;
		text-align: center;
		margin: 10rpx;
		img{
			width: 100%;
			height: 400rpx;
		}
		text{
			color: gray;
		}
	}
}
</style>

king list list.vue

<template>
	<view>
		二级分类页
		<button type="default" @tap="goKind">api方式跳转回分类页</button>
		<button type="default" @tap="goBack">返回上级菜单</button>
		<navigator url="/pages/kind/kind" open-type="switchTab">组件方式跳转回分类页</navigator>
		<navigator :delta="1" open-type="navigateBack">组件方式回退上一级</navigator>
		<view class="nav-item" v-for="item in categoryList" :key="item.id" @tap="catetoryClick(item)">
			<!-- <image :src="item.icon" mode=""></image> -->
			<text>{{item.name}}</text>
		</view>
	</view>
</template>

<script>
	import { getCategory} from '@/api/kind/list/list.js'

	
	export default {
		data() {
			return {
				categoryId:0,
				categoryList:[]
			};
		},
		methods:{
			catetoryClick(obj){
				console.log(obj)
				uni.navigateTo({
					url:'/pages/kind/goods/goods?id=' + obj.id
				})
			},
			goKind(){
				uni.switchTab({
					url:'/pages/kind/kind'
				})
			},
			goBack(){
				uni.navigateBack({
					delta:1
				})
			}
		},
		onLoad(options) {
			this.categoryId = options.id;
			getCategory(this.categoryId).then(res=>{
				//console.log(res)
				this.categoryList = res.data.category.children;
			})
		}
	}
</script>

<style lang="scss" scoped>
.nav-item{
	width: 100%;
	height: 110rpx;
	border: 1px solid gray;
	margin-bottom: 10px;
	box-sizing: border-box;
	text-align: center;
	font-size: 18px;
	font-weight: bold;
	line-height: 110rpx;
	background-color: $uni-bg-color-grey;
}
</style>

kind kind.vue

<template>
	<view>
		<button type="default" @tap="goProduct">api方式跳转到商品页</button>
		<navigator url="/pages/kind/list/list">组件方式跳转至商品页</navigator>
		<view class="nav-item" v-for="item in categoryList" :key="item.pmsProductCategory.id" @tap="catetoryClick(item)">
			<!-- <image :src="item.pmsProductCategory.icon" mode=""></image> -->
			<text>{{item.pmsProductCategory.name}}</text>
		</view>
	</view>
</template>

<script>
	import { getAllCategory } from '@/api/kind/index.js'
	
	export default {
		data() {
			return {
				categoryList:[]
			};
		},
		methods: {
			goProduct(){
				uni.navigateTo({
					url:'/pages/kind/list/list'
				})
			},
			catetoryClick(obj){
				uni.navigateTo({
					url:'/pages/kind/list/list?id=' + obj.pmsProductCategory.id
				})
			}
		},
		onLoad() {
			getAllCategory().then(res=>{
				console.log(res)
				this.categoryList = res.data.items;
			})
		}
	}
</script>

<style lang="scss">
	
	navigator{
		width: 100%;
		height: 150rpx;
		line-height: 150rpx;
		text-align: center;
	}
	
.nav-item{
	width: 100%;
	height: 150rpx;
	border: 1px solid gray;
	margin-bottom: 10px;
	box-sizing: border-box;
	text-align: center;
	font-size: 18px;
	font-weight: bold;
	line-height: 150rpx;
	background-color: $uni-bg-color-grey;
}
</style>

mine login login.vue

<template>
	<view class="login-area">
		<view class="row">
			<image src="/static/logo.png" style="width: 300rpx;height: 250rpx;margin: 0 auto;display: block;"></image>
		</view>
		<view class="row">
			<input type="text" class="input" placeholder="用户名" v-model="loginForm.username"/>
		</view>
		<view class="row">
			<input type="password" class="input" placeholder="密码" v-model="loginForm.password"/>
		</view>
		<view class="row">
			<button type="default" @tap="login" class="btn">登录</button>
		</view>
		<navigator url="/pages/mine/register/register" class="register">没有账号?注册一个</navigator>
	</view>
</template>

<script>
	import {doLogin} from '@/api/mine/login/login.js'
	import { getMemberInfo } from '@/api/mine/index.js'
	
	export default {
		data() {
			return {
				loginForm:{
					username:'17596496508',
					password:'123456'
				}
			};
		},
		methods:{
			login(){
				doLogin(this.loginForm).then(res=>{
					console.log(res)
					uni.showToast({
						title:'登录成功',
						icon:'success'
					});
					//登录成功,存token
					uni.setStorageSync("b-token",res.data.token);
					//同时获取用户信息,存用户
					getMemberInfo().then(res=>{
						uni.setStorageSync("b-userInfo",res.data.userInfo);
					});
					setTimeout(()=>{
						uni.switchTab({
							url:'/pages/mine/mine'
						});
					},1200);
					
				})
			}
		}
	}
</script>

<style lang="scss">

.login-area{
	
	background-color: #F3EDE7;
	width: 100%;
	
	
	.row{
		margin: 15rpx auto;
		min-height: 150rpx;
		width: 80%;
	
		
		.input{
			margin-top: 30rpx;
			border: 1px solid gray;
			box-sizing: border-box;
			height: 100rpx;
			width: 100%;
			font-size: 30rpx;
			line-height: 30rpx;
			border-radius: 50rpx;
			padding: 15rpx 20rpx;
		}
		
		.btn{
			background-color: #344B44;
			border-radius: 50rpx;
			color: #ffffff;
		}
	}
	.register{
		text-align: center;
		font-size: 14px;
		color: #625D5E;
	}
}
	
	
</style>

mine register register.vue

<template>
	<view class="register-area">
		<view class="row">
			<image src="/static/logo.png" style="width: 300rpx;height: 250rpx;margin: 0 auto;display: block;"></image>
		</view>
		<view class="row">
			<input type="text" class="input" placeholder="用户名 该用户名将用于账号登录" v-model="relForm.username"/>
		</view>
		<view class="row">
			<input type="password" class="input" placeholder="请输入登录密码" v-model="relForm.password"/>
		</view>
		<view class="row">
			<input type="text" class="input" placeholder="手机号" v-model="relForm.phone"/>
		</view>
		<view class="row">
			<input type="text" class="input" placeholder="请输入昵称" v-model="relForm.nickname"/>
		</view>
		<view class="row">
			<button type="default" @tap="register" class="btn">注 册</button>
		</view>
		<navigator url="/pages/mine/login/login" class="register">返回登录</navigator>
	</view>
</template>

<script>
	import { doRegister } from '@/api/mine/register/index.js'
	
	export default {
		data() {
			return {
				relForm:{
					phone:'',
					password:'',
					username:'',
					nickname:''
				}
			};
		},
		methods:{
			register(){
				doRegister(this.relForm).then(res=>{
					console.log(res)
					if(res.success){
						uni.showToast({
							title:res.message,
							icon:'success'
						})
					}else{
						uni.showToast({
							title:res.message,
							icon:'none'
						})
					}
				})
			}
		}
	}
</script>

<style lang="scss">
.register-area{
	
	background-color: #F3EDE7;
	width: 100%;
	
	
	.row{
		margin: 10rpx auto;
		min-height: 120rpx;
		width: 90%;
	
		.input{
			margin-top: 20rpx;
			border: 1px solid gray;
			box-sizing: border-box;
			height: 100rpx;
			width: 100%;
			font-size: 30rpx;
			line-height: 30rpx;
			border-radius: 50rpx;
			padding: 10rpx 50rpx;
		}
		
		.btn{
			background-color: #344B44;
			border-radius: 50rpx;
			color: #ffffff;
		}
	}
	.register{
		text-align: center;
		font-size: 14px;
		color: #625D5E;
	}
}
</style>

mine mine.vue

<template>
	<view class="info">
		<view class="user-info">
			<image :src="userInfo.icon" mode="" class="avatar"></image>
			<text class="nickname">{{userInfo.nickname}}</text>
			<text class="username">用户名:{{userInfo.username}}</text>
		</view>
		<navigator url="/pages/mine/login/login">登录</navigator>
	</view>
</template>

<script>
	import {getMemberInfo} from '@/api/mine/index.js'
	import mix from '@/minxins/index.js'
	
	export default {
		name:'Mine',
		mixins:[mix],
		data() {
			return {
				userInfo:null
			};
		},
		methods:{
			// getUser(){
			// 	let token = uni.getStorageSync("b-token");
			// 	if(token){
			// 		let userInfo = uni.getStorageSync("b-userInfo");
			// 		this.userInfo = userInfo;
			// 	}else{
			// 		uni.showModal({
			// 			title:'登录提示',
			// 			content:'暂未登录,是否重新登录',
			// 			success(res) {
			// 				console.log(res)
			// 				if(res.confirm){
			// 					//清空本地数据
			// 					uni.clearStorageSync();
			// 					uni.navigateTo({
			// 						url:'/pages/mine/login/login'
			// 					});
			// 				}
			// 			}
			// 		})
			// 	}
			// }
		},
		onLoad() {
			//this.getUser();
		},
		onShow() {
			this.checkLogin();
		}
		
	}
</script>

<style lang="scss">
	.info{
		background-color: #F3EDE7;
		width: 100%;
		
		.user-info{
			width: 100%;
			height: 300rpx;
			.avatar{
				width: 230rpx;
				height: 230rpx;
				border: 1px solid black;
				border-radius: 50%;
				margin-top: 40rpx;
				margin-left: 40rpx;
				
			}
			
			.nickname{
				font-size: 30px;
				position: absolute;
				top: 100rpx;
				left: 320rpx;
				color: #6C7A77;
			}
			
			.username{
				font-size: 14px;
				position: absolute;
				top: 200rpx;
				left: 320rpx;
				color: #C5C1C0;
			}
		}
		
		
	}
	
</style>

order order.vue

<template>
	<view class="order">
		<navigator url="/pages/order/address/address">选择收货地址</navigator>
		<view class="address">
			<text class="address-name">姓名:{{address.name}}</text>
			<text class="address-phone">电话:{{address.phoneNumber}}</text>
			<view class="address-detail">地址:{{address.province}}{{address.city}}{{address.region}}{{address.detailAddress}}</view>
		</view>
		<view class="row">id:{{orderData.orderBase && orderData.orderBase.id}}</view>
		<view class="row">orderSn:{{orderData.orderBase && orderData.orderBase.orderSn}}</view>
		<view class="row">totalAmount:{{orderData.orderBase && orderData.orderBase.totalAmount}}</view>
		<view class="row">status:{{orderData.orderBase && orderData.orderBase.status}}</view>
		<view class="order-items">
			<view class="order-item" v-for="(item,index) in orderData.orderItems" :key="index">
				<view class="item-row">id:{{item.id}}</view>
				<view class="item-row">orderId:{{item.orderId}}</view>
				<view class="item-row">orderSn:{{item.orderSn}}</view>
				<view class="item-row">productId:{{item.productId}}</view>
				<view class="item-row">productName:{{item.productName}}</view>
				<view class="item-row">productSn:{{item.productSn}}</view>
				<view class="item-row">productQuantity:{{item.productQuantity}}</view>
				<view class="item-row">productSkuId:{{item.productSkuId}}</view>
				<view class="item-row">productCategoryId:{{item.productCategoryId}}</view>
				<view class="item-row">realAmount:{{item.realAmount}}</view>
				<view class="item-row">totalPrice:{{item.totalPrice}}</view>
				<view class="item-row">productAttr:{{item.productAttr}}</view>
			</view>
		</view>
		<view>
			<button type="primary" @tap="save">确认付款</button>
		</view>
	</view>
</template>

<script>
	import {getPreOrderById, addConfirmOrder} from '@/api/order/index.js'
	
	export default {
		data() {
			return {
				orderId:null,
				orderData:{},
				address:null
			};
		},
		methods: {
			save(){
				addConfirmOrder({
					addressId: uni.getStorageSync("b-address").id,
					orderId: this.orderId,
					orderItemList: this.orderData.orderItems,
					payType: "",
					sourceType: ""
				}).then(res=>{
					console.log(res)
					uni.showToast({
						title:`付款${res.message},订单号是${res.data.orderId},订单查询码是${res.data.ordersn},总金额是${res.data.totalAmount}`,
						icon:'none',
						mask:true,
						duration:2000
					});
					setTimeout(()=>{
						uni.switchTab({
							url:'/pages/home/home'
						});
					},1500);
					
				})
			}
		},
		onLoad(options) {
			this.orderId = options.orderId;
			getPreOrderById(this.orderId).then(res=>{
				console.log(res);
				this.orderData = res.data;
			})
		},
		onShow() {
			let address = uni.getStorageSync("b-address");
			this.address = address;
		}
	}
</script>

<style lang="scss">
.order{
	background-color: #F3EDE7;
	width: 100%;
	height: 100vh;
	
	.address{
		padding: 10rpx;
		.address-name{
			font-size: 40rpx;
			font-weight: bold;
		}
		
		.address-phone{
			font-size: 30rpx;
			margin-left: 100rpx;
		}
		
		.address-detail{
			font-size: 30rpx;
		}
	}
	
	.row{
		width: 100%;
		height: 30rpx;
		padding: 2rpx 10rpx;
		
	}
	
	.order-items{
		width: 90%;
		margin: 0 auto;
		background-color: #fff;
		border-radius: 30rpx;
		
		.order-item{
			min-height: 300rpx;
			margin-top: 20rpx;
			.item-row{
				font-size: 14px;
				min-height: 20rpx;
				line-height: 20rpx;
				padding: 2rpx 10rpx;
				margin-top: 15rpx;
				
			}
		}
	}
}
</style>

order address address.vue

<template>
	<view class="address">
		<view class="row" v-for="item in addressList" :key="item.id" @tap="save(item)">
			<text class="item-name">{{item.name}}</text>
			<text class="item-address">{{item.province}}{{item.city}}{{item.region}}</text>
			<text class="item-detail">{{item.detailAddress}}</text>
		</view>
		
		<button type="default" @tap="add" style="background-color:#344B44; border-radius: 50rpx;color: white;">新增地址</button>
	</view>
</template>

<script>

	
	import {getAllAddress} from '@/api/order/address/index.js'
	import mix from '@/minxins/index.js'
	
	export default {
		mixins:[mix],
		data() {
			return {
				addressList:[]
			};
		},
		methods:{
			add(){
				
			},
			save(obj){
				uni.setStorageSync("b-address",obj);
				//回退一层
				uni.navigateBack({
					delta:1
				});
			}
		},
		onLoad() {
			//先判断是否登录
			if(!this.checkLogin()){
				uni.showToast({
					title:'请先登录',
					icon:'none'
				});
				return;
			}
			getAllAddress().then(res=>{
				console.log(res)
				this.addressList = res.data.items;
			})
		}
	}
</script>

<style lang="scss">
.address{
	background-color: #F3EDE7;
	width: 100%;
	height: 100vh;
	
	.row{
		width: 100%;
		height: 100rpx;
		line-height: 100rpx;
		border-bottom: 1px solid #E4DED9;
		
		.item-name{
			padding: 20rpx;
			font-size: 45rpx;
			margin-right: 40rpx;
		}
		
	}
}
</style>

app.vue

<script>
	export default {
		onLaunch: function() {
			console.log('App Launch')
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		}
	}
</script>

<style>
	/*每个页面公共css */
	* {
		padding: 0;
		margin: 0;
	}
	
</style>

pages.json

{
	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
		{
			"path" : "pages/home/home",
			"style" : 
			{
				"navigationBarTitleText" : "首页",
				"enablePullDownRefresh" : false,
				//也可以去掉导航栏
				"navigationStyle": "custom"
				//在h5中,去掉导航栏
				// "h5": {
				// 	"titleNView": false
				// }
			}
		},
		{
			"path" : "pages/kind/kind",
			"style" : 
			{
				"navigationBarTitleText" : "分类",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/find/find",
			"style" : 
			{
				"navigationBarTitleText" : "发现",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/mine/mine",
			"style" : 
			{
				"navigationBarTitleText" : "我的",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/index/index",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path": "pages/index2/index2",
			"style": {
				"navigationBarTitleText": "首页",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/kind/list/list",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/kind/goods/goods",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : true
				
			}
		},
		{
			"path" : "pages/info/info",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/mine/login/login",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/mine/register/register",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/order/order",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		},
		{
			"path" : "pages/order/address/address",
			"style" : 
			{
				"navigationBarTitleText" : "",
				"enablePullDownRefresh" : false
			}
		}
	],
	"globalStyle": {
		"navigationBarTextStyle": "black",
		"navigationBarTitleText": "uni-app",
		"navigationBarBackgroundColor": "#F8F8F8",
		"backgroundColor": "#F8F8F8"
	},
	"uniIdRouter": {},
	"tabBar": {
		"color": "#7A7E83",
		"selectedColor": "#3cc51f",
		"borderStyle": "black",
		"backgroundColor": "#ffffff",
		"list": [
			{
				"pagePath": "pages/home/home",
				"iconPath": "static/images/icon1.png",
				"selectedIconPath": "static/images/icon2.png",
				"text": "首页"
			}, 
			{
				"pagePath": "pages/kind/kind",
				"iconPath": "static/images/icon1.png",
				"selectedIconPath": "static/images/icon2.png",
				"text": "分类"
			}, 
			{
				"pagePath": "pages/find/find",
				"iconPath": "static/images/icon1.png",
				"selectedIconPath": "static/images/icon2.png",
				"text": "发现"
			}, 
			{
				"pagePath": "pages/mine/mine",
				"iconPath": "static/images/icon1.png",
				"selectedIconPath": "static/images/icon2.png",
				"text": "我的"
			}
		]
	}
}

/*
接口文档
http://leju.bufan.cloud/swagger-ui.html#/23458251433147158583614129289367102716922359/addCartUsingPOST_1

*/

测试

首页

uniapp初级入门-05模拟商城完结篇_Data_04

 分类

uniapp初级入门-05模拟商城完结篇_List_05

 我的

uniapp初级入门-05模拟商城完结篇_Data_06

 登录

uniapp初级入门-05模拟商城完结篇_List_07

 注册

uniapp初级入门-05模拟商城完结篇_Data_08

二级分类

uniapp初级入门-05模拟商城完结篇_ci_09

 商品列表

uniapp初级入门-05模拟商城完结篇_List_10

商品详情

uniapp初级入门-05模拟商城完结篇_uni-app_11

 立即购买

uniapp初级入门-05模拟商城完结篇_List_12

 初始订单

uniapp初级入门-05模拟商城完结篇_List_13

 地址列表

uniapp初级入门-05模拟商城完结篇_uni-app_14

 确认付款

uniapp初级入门-05模拟商城完结篇_List_15

以上就是全部代码了,虽然我没有按照视频教程中的内容把剩余的步骤完成。但是这个我学习的差不多了,需要吸收一下。

后续如果我还有uniapp的代码,还是会贴出来的。

感谢大家。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月23日 0

暂无评论

px8Y25gMnWbQ