保姆级教学:从0搭建微信小程序SpringBoot+Vue(二)

保姆级教学:从0搭建微信小程序SpringBoot+Vue(二)

上篇有人看,趁放假玩耍间隙来更完这篇!国庆快乐各位~~~
教学(一)链接: https://blog.csdn.net/weixin_44545610/article/details/142491302?spm=1001.2014.3001.5501
目前在玩儿cursor,做一个备忘录uni-app开发,有人有兴趣的话后续也放上来

五、微信小程序前端

1.新建Vue项目

打开HbuilderX(更新至最新版),新建项目,选择uni-app,版本选择Vue2。
20240910171955689
初始配置结构如下
20240911090732443

2.前端页面设计

在路径pages/index/index.vue文件中粘贴如下代码:

<template>
	<view>
	<view class="order-view">
		<view class="commodity">
			<view class="order-left"><!-- 左 -->
				<scroll-view scroll-y="true" class="scroll-Hei" :scroll-with-animation="true" :enhanced="true" :show-scrollbar="false">
					<block v-for="(item,index) in itemize" :key="index">
						<view class="itemize-text" :class="{active: index == trigger}" @click="itemIze(index,item.id)">
							<text>{{item.name}}</text>
						</view>
					</block>
				</scroll-view>
			</view> 
			<view class="order-right"><!-- 右 -->
				<scroll-view scroll-y="true" class="scroll-Hei"  :scroll-with-animation="true" :enhanced="true" :show-scrollbar="false" :scroll-into-view="scroll_into" @scroll="scroLl">
					<block v-for="(item,index) in goods" :key="index">
						<view :id="item.id" class="rig-height">
							<view class="classif">{{item.name}}</view>
								<view class="classif-goods" v-for="(itemgood,good_index) in item.dishList" :key="good_index" @click="popup_item(true,index,good_index,item.id,itemgood)">
									<view class="goods-image"><image :src="baseUrl+'/image/dish/'+itemgood.image" mode="aspectFill"></image></view>
									<view class="goods-Price">
										<view class="goods-name">
											<text class="Bold">{{itemgood.name}}</text>
										</view>
										<view class="unit-price">
											<text class="Symbol">¥</text>
											<text class="Bold">{{itemgood.price}}</text>
											<text class="Thinning">/{{itemgood.unit}}</text>
										</view>
									</view>
								</view>
						</view>
					</block>
					<view style="height: 400rpx;"></view>
				</scroll-view>
			</view>
		</view>
	</view>
	</view>
</template>
<script>
	import { getBaseUrl,requestUtil } from "../../utils/requestUtil.js"
export default{
	data() {
		return {
			baseUrl:'',
			exist:true,
			itemize:[],//类目
			trigger:0,//类目选中的值
			goods:[],//所有菜品
			heightset:[],//存储右边每一个分类菜品的高度
			tophei:0,//滚动时距离顶部的高度
			scroll_into:'',
		}
	},
	methods:{
		// 点击类目加上背景色
		itemIze(index,id){
			this.trigger = index
			this.scroll_into = id
			setTimeout(()=>{
				this.scroll_into = ''
			},200)
		},
		// 右边菜品滚动时触发
		scroLl(event){
			// console.log(event.detail.scrollTop)
			let scrollTop = event.detail.scrollTop
			if(scrollTop >= this.tophei){//上拉
				// 当前分类商品的高度小于滚动高度时跳转下一个分类
				if(scrollTop >= this.heightset[this.trigger]){
					this.trigger += 1
				}
			}else{//下拉
				// 当前分类商品的高度大于滚动高度时跳转下一个分类
				if(scrollTop < this.heightset[this.trigger - 1]){
					this.trigger -= 1
				}
			}
			this.tophei = scrollTop
		},
		//请求数据
		async dishEs(){
					const res=await requestUtil({url:"/menu/ListAll",method:"get"})
					const res2=await requestUtil({url:"/dish/ListAll",method:"get"})
					console.log(res)
					this.itemize = res.menulistall//类目
					this.goods = res2.dishList//所有菜品
					this.$nextTick(()=>{
						this.goods_height()
					})
				},
				// 计算右边每个分类菜品的高度
		goods_height(){
			this.heightset = []
			let cate_height = 0
			const query = wx.createSelectorQuery()
			query.selectAll('.rig-height').boundingClientRect()
			query.exec((res)=>{
				res[0].forEach((item)=>{
					cate_height += item.height
					this.heightset.push(cate_height)
				})
				this.exist = false
			})
		}
	},
	onLoad(){
		this.baseUrl=getBaseUrl()
		this.dishEs()
	}
}
</script>
<style scoped>
/* 点餐界面 */
.order-view{
	top:0;
}
.commodity{
	display: flex;
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	}
.order-left{
	background-color: #fafafa;
	width: 150rpx;
	overflow-y: auto;
}
.itemize-text{
	font-size: 27rpx;
	padding: 30rpx 10rpx;
	display: flex;
	align-items: center;
	color: #797979;
}
.itemize-text text:nth-child(1){flex: 1;}
.itemize-text text:nth-child(2){
	background-color: #eb5941;
	border-radius: 50%;
	font-size: 20rpx;
	color: #FFFFFF;
	width: 30rpx;
	height: 30rpx;
	display: flex;
	justify-content: center;
	align-items: center;
	margin-left: 2rpx;
}
.scroll-Hei{
	height: 100vh;
	/* white-space: nowrap; */
}
.order-right{
	background-color: #FFFFFF;
	flex: 1;
	overflow-y: auto;
	
}
.classif{
	font-size: 27rpx;
	padding: 30rpx 20rpx;
	color: #797979;
}
/* 分类商品 */
.classif-goods{
	display: flex;
	justify-content: space-between;
	padding: 0 20rpx;
	height: 150rpx;
	font-size: 30rpx;
	margin-bottom: 45rpx;
}

.goods-image image{
	display: block;
	width: 150rpx;
	height: 150rpx;
	border-radius: 10rpx;
}
.goods-Price{
	flex: 1;
	position: relative;
	padding: 0 20rpx;
}
.goods-Price text{display: block;}
.goods-name{
	display: flex;
	flex-direction: column;
	position: relative;
	top: 0;
}
.goods-name text:nth-child(1){padding-bottom: 9rpx;}
.unit-price{
	position: absolute;
	bottom: 0;
	display: flex;
	align-items: baseline;
}
.Bold{font-weight: bold;}
.Symbol{font-size: 20rpx;}
.Thinning{font-size: 25rpx;
color: #cccccc;
}
/* 点击分类列表加上背景色 */
.active{
	background-color: #FFFFFF;
	color: #000000 !important;
}
</style>

3.前端请求配置

新建utils文件目录→新建requestUtil.js文件,设定请求方法。
20240912101500528

代码如下:

// 同时发送异步代码的次数
let ajaxTimes=0;

// 定义公共的url
const baseUrl="http://localhost:80";

/**
 * 返回baseUrl
 */
export const getBaseUrl=()=>{
  return baseUrl;
}

/**
 * 后端请求工具类
 * @param {*} params 请求参数
 */
export const requestUtil=(params)=>{
 
   let header={...params.header};
 
    // 拼接header 带上token
    header["token"]=uni.getStorageSync("token");

    ajaxTimes++;
	
     // 显示加载中 效果
    wx.showLoading({
      title: "加载中",
      mask: true
    });

    var start = new Date().getTime();

    // 模拟网络延迟加载
    while(true)  if(new Date().getTime()-start > 1000*1) break;

  return new Promise((resolve,reject)=>{
    wx.request({
     ...params,
     header:header,
     url:baseUrl+params.url,
     success:(result)=>{
       resolve(result.data);
     },
     fail:(err)=>{
		 uni.showToast({
			icon:'error',
		 	title:'连接服务器失败',
			duration:3000
		 })
       reject(err);
     },
     complete:()=>{
      ajaxTimes--;
      if(ajaxTimes===0){
        //  关闭正在等待的图标
        wx.hideLoading();
      }
     }
    });
  })
}

4.后端图片远程访问配置

首先需要上传图片,将提前准备好的用于前端菜品展示的图片放到自己电脑中(即本地服务器),位置通常为后端项目路径下的资源文件夹\src\main\resources\image,方便部署到远程服务器时一起打包(放在其它位置应该也找得到,程序中路径修改了就行)。图片命名对应数据库菜单表中image字段。
在这里插入图片描述
为保证前端能通过url向后端获取到图片,需要后端配置处理器接口。右键包org.example.xiaomaibu,新建一个package命名为config→新建ImageConfig.java文件,贴进如下代码。记得将程序末尾的路径修改为图片存放位置。

package org.example.xiaomaibu.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;


@Configuration
public class ImageConfig implements WebMvcConfigurer {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/image/dish/**").addResourceLocations("file:C:\\Users\\IdeaProjects\\XiaoMaiBu\\src\\main\\resources\\image\\");
    }
}

5.小程序参数配置

获取自己的小程序:注册登录地址https://mp.weixin.qq.com

管理→开发管理→开发设置→开发者ID
20240911142637535

打开HbuilderX的项目,manifest.json配置,输入自己的小程序ID
20240911142842947

打开工具→设置→运行配置→微信开发者工具路径,输入安装好的微信开发者工具路径
20240911143510285
登录微信开发者工具→设置→安全→服务端口启用
20240911105258133

6.模拟器测试

打开HbuilderX→运行→运行到小程序模拟器→微信开发者工具
20240913141947146

7.实现效果

HbuilderX会自动打开微信开发者工具,并编译成微信原生态。
20240913142012926
20240913142108657
20240913142125035

六、调试及错误处理

微信小程序中,发现点击类别右侧滚动功能失效。定位到index.vue的scroll-view滚动组件,scroll-into-view 属性可以指定滚动到指定id的位置。在前端下面设计中:

<scroll-view scroll-y="true" class="scroll-Hei"
  :scroll-with-animation="true" :enhanced="true" 
  :show-scrollbar="false" :scroll-into-view="scroll_into" @scroll="scroLl">

scroll_into为其id,发现滚动功能失效是因为不能以数字开头。
因此,第一种办法是在点击方法将itemIze下面的this.scroll_into = id加上前缀字符串。

itemIze(index,id){
			this.trigger = index
			this.scroll_into = "item"+id
			setTimeout(()=>{
				this.scroll_into = ''
			},200)
		}

同时,在右侧滚动的组件中,将<view :id="item.id" class="rig-height">更换为<view :id="'item'+item.id" class="rig-height">以此对应所选类别。

第二种是在数据库设计中,菜单类别新增一列是字母开头的唯一识别,与类别一一对应,将item.id替换为item.新增列。

七、总结

至此,从0搭建微信小程序SpringBoot+Vue最基本的功能便成功搭建了,从后台到前端,实现了最基本的访问后台数据库展示功能。接下来我们应该考虑商品页的购物车功能、订单功能、用户登录等功能,但基本框架已经成型,后续只需要在此基础上继续叠加。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值