赞
踩
SpringBoot微信小程序电商实战项目课程 Vue3.2 Element Plus后台管理 ( 火爆连载更新中… )_哔哩哔哩_bilibili
本套课程采用主流技术栈实现,Mysql数据库,SpringBoot2+Mybatis Plus后端,微信小程序原生实现,Vue3.2+Element Plus实现后台管理。基于JWT技术实现前后端分离。
微信小程序端涵盖了axios异步请求,Promise应用,swiper组件,自定义组件,应用了微信小程序提供的登录,支付,地址管理,包括下拉滑动分页,less应用,以及结合SpringBoot后端实现了企业级微信小程序支付功能,为了方便教学,采用ngrok实现映射本机IP,开发环境演示真实支付功能。
电商的后台管理采用了主流的Vue3.2+Element Plus组件 实现,涵盖了axios+Promise工具类封装,自定义icon,vuex应用,router路由,路由守卫,使用了大量的Element Plus组件,如表格,分页,图片上传,下拉框,二级联动,Form表单,rules验证框架,dialog以及第三方vue-quil富文本组件等。
3_下载微信开发者工具以及安装_哔哩哔哩_bilibili 前几P会介绍微信开发者的注册以及开发工具的下载与使用
index.json
{
"usingComponents": {},
//正常json中不能注释,这里目的是为了说明
//程序主名字
"navigationBarTitleText": "商城首页"
}
index.js
清空后输入Page, 生成一个模板
将图标添加到库
将库中图标添加到项目
进入连接后里面的内容就是我们需要的远程图标和样式
在pages同级列表下创建styles文件夹,里面创建iconfont.wxss文件,将上面内容复制进去-
在app.wxss中进行全局引入@import "./styles/iconfont.wxss"
以在首页使用为例:
<text class="iconfont icon-kefu">
</text>
该项目创建了icons文件夹并放置了一些本地图标
接下来对app.json进行处理,下面只写出改动部分
"pages":[ //底部菜单的四个内容 "pages/index/index", "pages/category/index", "pages/cart/index", "pages/my/index" ], "tabBar": { //正常颜色 "color": "#999", //选中后的颜色 "selectedColor": "#FF5700", //底色 "backgroundColor": "#fafafa", //四个菜单元素 "list": [{ //选中后前往的地址 "pagePath": "pages/index/index", //文本信息 "text": "首页", //图标 "iconPath": "icons/_home.png", //选中后的图标 "selectedIconPath": "icons/home.png" }, { "pagePath": "pages/category/index", "text": "分类", "iconPath": "icons/_category.png", "selectedIconPath": "icons/category.png" },{ "pagePath": "pages/cart/index", "text": "购物车", "iconPath": "icons/_cart.png", "selectedIconPath": "icons/cart.png" },{ "pagePath": "pages/my/index", "text": "我的", "iconPath": "icons/_my.png", "selectedIconPath": "icons/my.png" }] },
/* 初始化全局样式,该代码会报错,但是程序正常运行,原因未知 */
page,view,text,swiper,swiper-item,image,navigator{
/* css中经典的盒式模型*/
padding:0;
margin:0;
box-sizing:border-box;
}
/* 全局变量定义,设置主题颜色,字体大小等 */
page{
/* 主题颜色 */
--themeColor:#FF5700;
/* 字体大小 rpx自适应大小,根据设备不同会自动适应屏幕大小 */
font-size:28rpx;
}
使用上述全局样式
我们曾在index.wxml中写入了view标签包含的代码
现在我们在index.wxss中使用全局样式
/* 对view标签内容设置颜色,这里使用变量要使用var,--themeColor是我们上面设置的全局样式变量 */
view{
color:var(--themeColor);
}
效果如下:
设置app.json中导航栏的颜色:
"window":{
"backgroundTextStyle":"light",
//设置导航栏的颜色
"navigationBarBackgroundColor": "#FF5700",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"white"
},
"usingComponents": {
//组件名称为:前的SearchBar
//components文件夹下的SearchBar文件夹内的SearchBar组件
"SearchBar":"/components/SearchBar/SearchBar"
},
<view>
//将上面:前的内容作为标签名
<SearchBar></SearchBar>
</view>
此时使用成功,只是没有样式、
写样式,目前没有引入less,使用正常写法
<view class="search_bar">
<!-- 设置跳转页面(在app.json的pages中注册) -->
<navigator url="/pages/search/index" open-type="navigate">
<icon type="search" size="16"></icon>搜索
</navigator>
</view>
/* 设置搜索栏的高度,边距,背景色 */ .search_bar{ height: 90rpx; padding: 10rpx; background-color: var(--themeColor); } /* 设置搜索栏文本样式 */ .search_bar navigator{ /* 100%继承上层的高度 */ height: 100%; /* 使用伸缩盒子 */ display: flex; /* 文字居中,快捷:jcc */ justify-content: center; /* 垂直居中,快捷键:alc */ align-items: center; /* 这个白色是搜索框的那个白色 */ background-color: #fff; /* 文字颜色 */ color: #666; /* 圆角 */ border-radius: 15rpx; } .search_bar navigator icon{ /* 设置右边距,让他离“搜索”文本远一些 */ padding-right: 5rpx; }
Less是一门css预处理语言,让css更容易维护,方便制作主题、扩充
安装配置方法参考:微信开发者工具配置支持less_Java开源博客系统-Powered by java1234
2022后版本先去上面链接里下载插件,安装看这个:(13条消息) 2022版本微信开发者工具引入less插件_周怼怼的博客的博客-CSDN博客_微信开发者工具如何安装less插件
使用后就在.less中写代码,保存后会自动生成.wxss内容。对上文搜索框样式内容进行修改
.search_bar{ height: 90rpx; padding: 10rpx; background-color: var(--themeColor); navigator{ height: 100%; display: flex; justify-content: center; align-items: center; background-color: #fff; color: #666; border-radius: 15rpx; icon{ padding-right: 5rpx; } } }
创建时导入的依赖:lomBok,Spring Web,Spring Boot DevTools
<dependencies> <!-- web依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- devtools可以提高开发者的工作效率,最方便的地方莫过于热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <!-- lombok省去构造器,getter,setter等实体类的代码 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!-- mysql驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- 德鲁伊连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency> <!-- mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.3.2</version> </dependency> <!-- 添加Httpclient支持 --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> <!-- fastjson,用来转化json --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.40</version> </dependency> <!-- JWT --> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.2.0</version> </dependency> <!-- JJWT --> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> </dependency> <!-- JDOM --> <dependency> <groupId>jdom</groupId> <artifactId>jdom</artifactId> <version>1.1</version> </dependency> <!-- dom4j --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> <!-- commons-io流包 --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> </dependencies>
我们一般配置文件用yml,所以把自动生成的application.properties改为yml文件
进行如下配置:
server:
port: 8080
servlet:
context-path:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
# 有些数据库版本需要加上&useSSL=false
url: jdbc:mysql://localhost:3306/mall-system?serverTimezone=Asia/Hongkong&useSSL=false
username: root
password: 123456
package com.zaughter.pojo; import java.util.HashMap; import java.util.Map; /** * 页面响应entity */ public class R extends HashMap<String, Object> { private static final long serialVersionUID = 1L; //无参构造器 public R() { put("code", 0); } //error方法的重载 public static R error() { return error(500, "未知异常,请联系管理员"); } //带异常信息 public static R error(String msg) { return error(500, msg); } //带异常代码与信息 public static R error(int code, String msg) { R r = new R(); r.put("code", code); r.put("msg", msg); return r; } //ok方法的重载 public static R ok(String msg) { R r = new R(); r.put("msg", msg); return r; } public static R ok(Map<String, Object> map) { R r = new R(); r.putAll(map); return r; } public static R ok() { return new R(); } //由于R是一个HashMap,所以可以通过键值对存入数据,这里是put的重载 public R put(String key, Object value) { //调用父类(HashMap)的put方法 super.put(key, value); return this; } }
mybatis-plus:
global-config:
db-config:
id-type: auto # id生成规律:数据库id自增
configuration:
map-underscore-to-camel-case: false # 开启驼峰功能
auto-mapping-behavior: full # 自动映射任何复杂的结果
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 日志
mapper-locations: classpath:mybatis/mapper/*.xml # mapper路径
由于是前后端分离,所以所有的日期都要有前后端分离操作
//json序列化,由于是前后端分离,所以所有的日期都要有前后端分离操作
@JsonSerialize(using=CustomDateTimeSerializer.class)
private Date hotDateTime; // 设置热门推荐日期时间
package com.zaughter.pojo; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; /** * 自定义返回JSON 数据格式中日期格式化处理 */ public class CustomDateTimeSerializer extends JsonSerializer<Date>{ @Override public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai")); gen.writeString(sdf.format(value)); } }
微信swiper官方文档:swiper | 微信开放文档 (qq.com)
//web项目配置类
@Configuration
public class WebAppConfigure implements WebMvcConfigurer {
@Override
//资源处理,给图片文件夹虚拟映射
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//访问xx路径会映射到本地路径,注意本地路径开头要加file:最后要再加一次\\
registry.addResourceHandler("/image/swiper/**").addResourceLocations("file:D:\\study files\\java files\\微信小程序-电商实战项目\\swiperImgs\\");
}
}
代码写在index.wxml中
<!-- 轮播图开始 -->
<view class="index_swiper">
<swiper>
<swiper-item>
<navigator>
<image src="http://localhost:8080/image/swiper/2.jpg"></image>
</navigator>
</swiper-item>
</swiper>
</view>
<!-- 轮播图结束 -->
目前开发阶段使用的都是本地域名,所以要进行如下设置防止出现问题
发布小程序时,要设置服务器域名白名单
小程序后台管理->开发管理->开发设置->服务器域名
index.xml
在image标签中添加mode
<swiper-item>
<navigator>
<!-- 宽度自适应,这样防止由于下面less将尺寸写死导致部分机型显示有问题 -->
<image mode="widthFix" src="http://localhost:8080/image/swiper/1.jpg"></image>
</navigator>
</swiper-item>
index.less
.index_swiper{
swiper{
//图片大小是2:1,所以这里也是2:1的比例
width: 750rpx;
height: 375rpx;
swiper-item{
image{
//宽度100%继承
width: 100%;
}
}
}
}
内容都可以从swiper官方文档中获取
在swiper标签下添加indicator-dots
在swiper标签下添加autoplay
但是此时无法循环,当滑动到最后一张图片后便不会再发生滑动
添加circular,设置为循环滑动
思路:在index.js中设置。
data: {
// 轮播图数组
swiperList:[]
},
onLoad: function (options) {
// 发送异步请求获取后端数据
wx.request({
url: 'http://localhost:8080/product/findSwiper',
method:"GET",
success:(result)=>{
this.setData({
swiperList:result.data.message
})
}
})
}
目前url是通过拼接实现的,这种实现方式并不好,后面我们要进行封装
<!-- 对已经含有后端数据的数组进行遍历,并将遍历出来的元素命名为swiper(如果不命名) -->
<swiper-item
wx:for="{{swiperList}}"
wx:for-item="swiper"
wx:key="id"
>
<navigator>
<image mode="widthFix" src="{{'http://localhost:8080/image/swiper/'+swiper.swiperPic}}"></image>
</navigator>
</swiper-item>
上面我们在没有封装的情况下请求后端,但是如果我们现在需要依赖于得到的请求结果进行进一步的请求,我们就要再续上一次wx.request。那么如果有很多层呢?就会形成“回调地狱”
在es6中提出了异步依赖回调的解决方案,同一up主的相关课程:es6视频教程-Java1234课堂
创建一个utils工具包,里面新建我们的requestUtil工具类
//后端请求工具类 //到时候requestUtil会传入一系列参数 export const requestUtil=(params)=>{ //如果请求成功就走resolve,失败就走reject return new Promise((resolve,reject)=>{ wx.request({ //解析那些参数 ...params, success:(result)=>{ //这个.data的目的是为了在使用时少打一个.data resolve(result.data) }, fail:(err)=>{ reject(err) } }) }) }
使用工具类要先导入
//导入requestUtil请求工具类
import {requestUtil} from '../../utils/requestUtil.js'
Page({
使用
requestUtil({url: 'http://localhost:8080/product/findSwiper',method:"GET"})
.then(result=>{
this.setData({
swiperList:result.message
})
})
}
跟原先版本进行对比
wx.request({
//url和method都作为参数传入工具类中,后面...params解构
url: 'http://localhost:8080/product/findSwiper',
method:"GET",
success:(result)=>{
this.setData({
//这里就是那个.data
swiperList:result.data.message
})
}
})
规范
在企业开发中,我们最好不要将业务代码整个写到js文件的onload中。
将其抽取出来变成一个方法,然后onload中只有一行调用这个方法即可
错误示范:
正确规范:
上面通过Promise方式优化后其实还有不足
requestUtil传参时requestUtil({url: 'http://localhost:8080/product/findSwiper',method:"GET"})
将url写死了,那么假如使用了很多次这个工具类,当域名发生改变时就需要修改很多次(swiper中图片的读取也存在这个问题),所以要把根路径进行封装
requestUtil.js
//定义请求跟路径baseUrl,8080后面的/我们用的时候另外加,防止错乱
const baseUrl="http://localhost:8080";
//返回请求根路径baseUrl
export const getBaseUrl=()=>{
return baseUrl;
}
在index.js中导入getBaseUrl,在data(所有页面数据的初始化都在这里,比如 上面的swiperList)中初始化baseUrl:baseUrl:"
正常拼接即可
<image mode="widthFix" src="{{baseUrl+'/image/swiper/'+swiper.swiperPic}}"></image>
requestUtil方式中传入根路径后面的剩余部分/product/findSwiper
,根路径放在setData中
requestUtil使用
requestUtil({url: '/product/findSwiper',method:"GET"})
.then(result=>{
//通过导入的getBaseUrl方法得到Url
const baseUrl=getBaseUrl();
this.setData({
swiperList:result.message,
//将得到的Url通过setDate传入
baseUrl
})
})
requestUtil定义
export const requestUtil=(params)=>{
return new Promise((resolve,reject)=>{
wx.request({
...params,
//解析处参数中的Url后与已经set好的baseUrl拼接
url:baseUrl+params.url,
success:(result)=>{
resolve(result.data)
},
fail:(err)=>{
reject(err)
}
})
})
}
终极封装,可以让异步请求更加优雅,易于维护;
配置方式:
下载facebook的regenerator库中的runtime.js
在小程序目录下新建文件夹lib/runtime/runtime.js
在每一个需要使用async语法的页面js文件中都引入(不能全局引入),只需要引入,不需要调用
import regeneratorRuntime from '../../lib/runtime/runtime'
然后就可以正常的使用async,await语法处理异步请求了
改进后的代码:
// 外层使用async声明这是一个异步方法,这样它不会阻碍到后面方法的执行
async getSwiperList(){
//await声明这里需要同步,这就是等requestUtil这个方法执行完毕,返回给result后再进行后续的代码
const result=await requestUtil({url: '/product/findSwiper',method:"GET"});
const baseUrl=getBaseUrl();
this.setData({
swiperList:result.message,
baseUrl
})
}
自己看视频P14,就是cv大法加查找替换。LJ2022版本ctrl+f为查询,替换需要用ctrl+R。注意替换前要开启大小写敏感
首先先给本地的商品大类图片在WebAppConfigure.java中进行映射
registry.addResourceHandler("/image/bigType/**").addResourceLocations("file:D:\\study files\\java files\\微信小程序-电商实战项目\\bigTypeImgs\\");
前端初始化数据
data: {
// 轮播图数组
swiperList:[],
// 根路径
baseUrl:'',
// 储存所有商品大类图片的大数组、
bigTypeList:[],
// 储存相应行上的商品大类图片的小数组
bigTypeList_row1:[],
bigTypeList_row2:[]
},
前端设置获取数据的方法
<!-- 商品大类图片开始 --> <view class="index_bigType"> <view class="bigTypeRow"> <navigator wx:for="{{bigTypeList_row1}}" wx:for-item="bigType" wx:key="id" > <image mode="widthFix" src="{{baseUrl+'/image/bigType/'+bigType.image}}"></image> </navigator> </view> <view class="bigTypeRow"> <navigator wx:for="{{bigTypeList_row2}}" wx:for-item="bigType" wx:key="id" > <image mode="widthFix" src="{{baseUrl+'/image/bigType/'+bigType.image}}"></image> </navigator> </view> </view> <!-- 商品大类图片结束 -->
设置less样式
// 商品大类图片样式
.index_bigType{
padding-top: 20rpx;
background-color: #F7F7F7;
.bigTypeRow{
display: flex;
navigator{
flex: 1;
image{
width: 150rpx;
}
}
}
}
//查询前八个热门推荐商品
@GetMapping("/findHot")
public R findHot(){
Page<Product> page = new Page<>(0,8);
Page<Product> pageProduct = productService.page(page, new QueryWrapper<Product>().eq("isHot", true).orderByAsc("hotDateTime"));
List<Product> hotProductList = pageProduct.getRecords();
Map<String,Object> map=new HashMap<>();
map.put("message",hotProductList);
return R.ok(map);
}
这里面用到了mybatis-plus给我们提供的Page分页对象,所以需要写mybatis-plus的配置才能正常分页
package com.zaughter.config; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * MybatisPlus配置类 */ @Configuration public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } }
搞到现在,对于图片展示的流程基本摸清了:后端设置路径,这个路径会调用方法返回相关数据=>WebAppConfigure.java映射=>js文件中通过数据映射路径将数据导入到数组中=>在wxml中通过图片映射路径展示图片=>去less中调整图片样式
映射本地虚拟路径registry.addResourceHandler("/image/product/**").addResourceLocations("file:D:\\study files\\java files\\微信小程序-电商实战项目\\Imgs\\productImgs\\");
// 获得推荐热卖商品列表
async getHotProductList(){
const result=await requestUtil({url: '/product/findHot',method:"GET"});
this.setData({
hotProductList:result.message,
})
},
<!-- 推荐商品图片开始 --> <view class="index_hotProduct"> <view class="product_title">热卖推荐</view> <view class="product_list"> <view class="product_detail" wx:for="{{hotProductList}}" wx:for-item="hotProduct" wx:key="id" > <navigator> <image mode="widthFix" src="{{baseUrl+'/image/product/'+hotProduct.proPic}}"></image> <view class="product_name">{{hotProduct.name}}</view> <view class="product_price"> ¥ {{hotProduct.price}}</view> <button size="mini" type="warn">立即购买</button> </navigator> </view> </view> </view> <!-- 推荐商品图片结束 -->
.index_hotProduct{ .product_title{ font-size: 32rpx; font-weight: 600; padding: 20rpx; color: var(--themeColor); background-color: #E0E0E0; } .product_list{ display: flex; //里面元素只要满足条件就会自动换行 flex-wrap: wrap; .product_detail{ margin: 15rpx; //这样就能自动换行了 width: 46%; text-align: center; navigator{ image{ width: 100%; background-color: #F5F5F5; } .product_name{ //正常情况下如果商品名字过长需要显示多行 //通过下面三行代码可以让名字只在一行显示,多余的内容通过...省略 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .product_price{ color: var(--themeColor); } // button{} } } } }
主要还是那些cv大法,看视频即可,没什么新知识
默认编译模式下我们都是在首页开始,那么如果在写其他页面前端代码,每次测试还要手动点击去跳转到那个页面比较麻烦,这时候可以添加编译模式设置启动页面,还可以携带参数
剩下还是老知识
左右两侧都是纵向的scroll-view,在wxml中使用scroll-view标签即可
<view class="cates_container">
<!-- 左侧菜单开始 -->
<scroll-view scroll-y class="left_menu">
</scroll-view>
<!-- 左侧菜单结束 -->
<!-- 右侧商品数据开始 -->
<scroll-view scroll-y class="right_context">
</scroll-view>
<!-- 右侧商品数据结束 -->
</view>
开始丰富我们上面写的scroll-view布局
左侧:
<scroll-view scroll-y class="left_menu">
<view class="menu_item"
wx:for="{{leftMenuList}}"
wx:key="*this"
>{{item}}
</view>
</scroll-view>
分析:
右侧:
<scroll-view scroll-y class="right_context"> <view class="productType" wx:for="{{rightContext}}" wx:for-item="productType" wx:key="id" > <view class="productType_title"> {{productType.name}} <view class="product_list" wx:for="{{productType.productList}}" wx:for-item="product" wx:key="id" > <navigator> <image mode="widthFix" src="{{baseUrl+'/image/product/'+product.proPic}}"></image> <view class="product_name">{{product.name}}</view> <view class="product_price"> ¥ {{product.price}}</view> </navigator> </view> </view> </view> </scroll-view>
分析:
具体样式直接看视频,这种没啥可记录的
我们先增加左侧菜单的wxml内容
<scroll-view scroll-y class="left_menu">
<view class="menu_item {{index==currentIndex ? 'active':''}}"
wx:for="{{leftMenuList}}"
wx:key="*this"
data-index="{{index}}"
bindtap="handleMenuItemChange"
>{{item}}
</view>
</scroll-view>
分析:
然后去js文件中写点击事件的内容:
//左侧菜单点击切换事件
handleMenuItemChange(e){
const {index}=e.currentTarget.dataset;
let rightContext=this.Cates[index].smallTypeList;
this.setData({
currentIndex:index,
rightContext,
})
},
分析:
{{index==currentIndex ? 'active':''}}
判断语句便可以生效现在当点击左侧切换分区时,右边滚动条位置不会重置,而是跟原来位置一样,所以每次需要初始化为0
在index.wxml
中对scroll-view
标签添加内容
<scroll-view scroll-y class="right_context" scroll-top="{{scrollTop}}">
让scroll-top
属性作为一个变量,变量为scrollTop
增加了新的数据,就去index.js
的data
区增加
data: {
baseUrl:'',
currentIndex:0, // 当前选中左侧菜单的索引
scrollTop:0, // 设置竖向滚动条位置
leftMenuList:[], // 左侧大类数据
rightContext:[], // 右侧小类数据
},
然后对点击事件handleMenuItemChange
增加初始化内容
handleMenuItemChange(e){
const {index}=e.currentTarget.dataset;
let rightContext=this.Cates[index].smallTypeList;
this.setData({
currentIndex:index,
rightContext,
scrollTop:0
})
},
使用switchTab方法实现跳转,跳转的时候我们应该携带参数,但是这个方法不能携带。所以我们使用全局参数设置的方法来间接传参
首先去全局的app.js
中设置全局变量index
// app.js
App({
onLaunch() {
},
globalData: {
index:-1
}
})
接着对首页大类的参数进行增加
<view class="index_bigType"> <view class="bigTypeRow"> <navigator bindtap="handleTypeJump" // 设置新的点击事件 data-index="{{index}}" // 第一行的index,从0开始 wx:for="{{bigTypeList_row1}}" wx:for-item="bigType" wx:key="id" > <image mode="widthFix" src="{{baseUrl+'/image/bigType/'+bigType.image}}"></image> </navigator> </view> <view class="bigTypeRow"> <navigator bindtap="handleTypeJump" // 设置新的点击事件 data-index="{{index+5}}" // 首页第二行的index,由于也是从0开始,但是实际是5开始,所以加5 wx:for="{{bigTypeList_row2}}" wx:for-item="bigType" wx:key="id" > <image mode="widthFix" src="{{baseUrl+'/image/bigType/'+bigType.image}}"></image> </navigator> </view> </view>
接着有了数据,就去index.js
中增加点击事件具体内容
// 大类点击事件 跳转 商品分类页面
handleTypeJump(e){
const {index}=e.currentTarget.dataset; // 结构传来参数中的index参数
const app=getApp(); // 使用自带的类
app.globalData.index=index; // 将这个点击得到的参数赋值给全局参数
wx.switchTab({ // 跳转
url: '/pages/category/index'
})
},
使用生命周期函数中的onShow
,每次跳转都会执行,而onLoad
只有第一次加载的时候执行
注意这里面有一个异步问题,onLoad里执行了getCates这个方法去获得数据,但是在数据还没有得到时,就会执行onShow,导致onShow是得不到数据的,所以这时我们再写一个新的,同时再增加一些其他的初始化
// 获得商品分类数据(从首页过来) async getCates2(index){ const result=await requestUtil({url: '/bigType/findCategories',method:"GET"}); this.Cates=result.message; let leftMenuList=this.Cates.map((v)=>{ return v.name }) let rightContext=this.Cates[index].smallTypeList; this.setData({ leftMenuList, rightContext, currentIndex:index,// 其他的初始化 scrollTop:0, }) }, /** * 生命周期函数--监听页面显示 */ onShow: function() { const app=getApp(); const {index}=app.globalData; console.log("index="+index) if(index!=-1){ // 从首页跳转过来 this.getCates2(index); // 使用这个方法,能拿到数据 app.globalData.index=-1; // 重置index } },
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。