项目起步
搭建项目骨架
全局配置文件
app.js 全局应用文件
App({
onLaunch() {
},
/**
* 当小程序启动,或从后台进入前台显示,会触发 onShow
*/
onShow: function (options) {
},
/**
* 当小程序从前台进入后台,会触发 onHide
*/
onHide: function () {
},
/**
* 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
*/
onError: function (msg) {
}
})
app.json 应用配置文件
{
"window":{
# 配置标题
# 设置颜色
# 设置背景色
},
"pages":{
},
"tabbar":{
}
}
{
"window": {
"navigationBarBackgroundColor": "#2980B9",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "结城sakana"
},
"pages": [
"pages/category/category",
"pages/shopcart/shopcart",
"pages/home/home",
"pages/my/my"
]
}
app.wxss 全局应用样式
page{
width:100%;
height:100%;
}
.flex{
display:flex
}
.flex_c{
displat:flex;
flex# zongxiang排列
}
新建页面
新建 pages 文件夹,创建 category 页面,shopcart页面,home页面,my页面
创建tabbar
在 app.json 中配置tarbar,配置tabbar中的路径,标题,图标,激活图标
{
"window": {
"navigationBarBackgroundColor": "#2980B9",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "结城sakana"
},
"pages": [ // 设置路由
"pages/category/category",
"pages/shopcart/shopcart",
"pages/home/home",
"pages/my/my"
],
"tabBar": { // 设置tabbar
"list": [
{
"pagePath": "pages/home/home",
"text": "首页",
"iconPath": "/static/tabbar/home_active.png",
"selectedIconPath": "/static/tabbar/home.png"
},
{
"pagePath": "pages/category/category",
"text": "分类",
"iconPath": "/static/tabbar/category.png",
"selectedIconPath": "/static/tabbar/category_active.png"
},
{
"pagePath": "pages/shopcart/shopcart",
"text": "购物车",
"iconPath": "/static/tabbar/cart.png",
"selectedIconPath": "/static/tabbar/cart_active.png"
},
{
"pagePath": "pages/my/my",
"text": "我的",
"iconPath": "/static/tabbar/my.png",
"selectedIconPath": "/static/tabbar/my_active.png"
}
],
"color": "#bfbfbf", // 设置tabbar字体颜色
"selectedColor": "#2c2c2c" // 设置tabbar字体颜色
}
}
静态图片文件
把项目中的静态图片复制到项目中
首页页面
搭建首页的静态
首页骨架
/pages/home/home.wxml
// 首页轮播图
# 设置轮播图的指示器的样式和颜色
# 首页分类的结构
# 通过 &&运算 动态添加active类名,动态设置元素的样式
<!--pages/home/home.wxml-->
<view class="home">
<!-- 轮播图 -->
<swiper class="swiper" indicator-dots indicator-color="pink" indicator-active-color="black" autoplay interval="2000" circular>
<swiper-item >
<image src="/static/image/banner1.jpg" mode="aspectFill" class="banner" />
</swiper-item>
<swiper-item >
<image src="/static/image/banner1.jpg" mode="aspectFill" class="banner" />
</swiper-item>
<swiper-item >
<image src="/static/image/banner1.jpg" mode="aspectFill" class="banner" />
</swiper-item>
</swiper>
<!-- 分类 -->
<view class="cate flex">
<!-- 动态设置伸缩项目的样式 -->
<view class="cate-item flex_c {{ index > 4 && 'bottom'}}" wx:for="{{10}}" wx:key="{{index}}">
<image src="/static/category/category1.png" mode="" class="cate-img"/>
<text class="cate-text">sakuna</text>
</view>
</view>
<!-- 首页logo -->
<image src="https://img02.hua.com/zhuanti/valentine/2023/23_valentine_mbanner_m.png?a1" mode="widthFix" class="logo"/>
<!-- 底部猜你喜欢和热门推荐 -->
<view class="footer" >
<view class="like">猜你喜欢</view>
<!-- 页面给组件传递参数:属性-类似于vue的props -->
</view>
</view>
首页样式
/pages/home/home.wxss
// 设置首页轮播图样式
// 首页分类的样式
/* pages/home/home.wxss */
.home {
width: 750rpx;
}
.home .swiper{
width: 750rpx;
height: 300rpx;
}
.home .swiper .banner{
width: 750rpx;
height: 300rpx;
}
/* 分类 */
.cate{
flex-wrap: wrap;
margin-top: 10rpx;
}
.cate .cate-img{
width: 88rpx;
height: 88rpx;
}
.cate .cate-item{
width: 150rpx;
justify-content: center;
align-items: center;
margin: 10rpx 0rpx;
}
.cate .cate-item .cate-text{
font-size: 30rpx;
margin: 10rpx 0rpx;
}
.cate .bottom .cate-img{
width: 40rpx;
height: 40rpx;
}
.cate .bottom .cate-text{
font-size: 28rpx;
margin: 10rpx 0rpx;
}
/* logo */
.home .logo{
width: 750rpx;
}
接口在线文档
http://39.98.123.211:8300/doc.html#/home
通过API 发送网络请求
# 通过API 发送网络请求
wx.request() 参数是一个对象[obj]
# 网络请求:https协议的(默认)勾选不校验合法域名可以发http请求
# 二次封装request
封装utils工具
新建一个utils文件夹,新建一个request.js文件
定义一个函数
返回一个promise对象
发送请求,出现加载效果, wx.showLoading()
获取到数据时,执行成功的回调success(res){},同时返回一个成功的Promise对象
获取不到数据时,执行失败的回调fail(error){},同时返回一个失败的Promise对象
不管成功或失败complete(){}拿到数据隐藏加载效果wx.hideLoading()
# 封装api统一管理接口:防止出现换接口,然后挨个找换
新建api文件夹,新建index.js文件
导入request
封装一个函数用于发送请求并复用
# 获取首页分类数据
定义一个函数发送请求
在加载load钩子中调用这个函数发送请求(需要在后台添加网络域名配置)
/api/index.js
import request from '../utils/request';
// 获取首页数据
// banner
export const reqBanner = () =>{
return request({
url:"/mall-api/index/findBanner"
})
}
// 获取首页分类的数据
export const reqCategory = () =>{
return request({
url:"/mall-api/index/findCategory1"
})
}
// 猜你喜欢的接口
export const reqLike = () =>{
return request({
url:"/mall-api/index/findListGoods"
})
}
// 热门推荐
export const reqHot = () =>{
return request({
url:`/mall-api/index/findRecommendGoods`
})
}
//获取分类模块的数据
export const reqSort = () => request({
url: `/mall-api/index/findCategoryTree`
})
/utils/request.js
// 网络请求全部的页面使用--功能封装函数(复用)
// params:调用函数传递参数 {url:'xxxx'.method:'post',data:{a:1}}
export default (params) => {
return new Promise((resolve,reject)=>{
//请求基础路径
const baseURL = 'https://gmall-prod.atguigu.cn'
//发请求之前加载效果出来
wx.showLoading({
title: '加载....',
});
// 获取token信息
const token = wx.getStorageSync('TOKEN');
// 定义请求头
let header = {};
// 如果token存在,添加请求头
if (token) {
header.token = token;
}
// 发请求
wx.request({
//请求URL----绝对路径
url: baseURL + params.url,
//请求方式
method: params.method || "GET",
//携带请求体
data: params.data || {},
// 携带请求头
header,
//成功回调
//res即为服务器响应数据
success(res) {
//返回一个成功的Promise对象
//简化数据
resolve(res.data);
},
fail(error) {
reject(error);
},
//成功与失败钩子
complete() {
//加载效果取消
wx.hideLoading()
}
})
})
}
网络配置
# 在小程序后台 开发 开发设置中 配置网络合法域名
# 在 小程序开发 软件中的详情 本地配置 勾选不校验合法域名
# 域名不可以使用IP地址
猜你喜欢部分
# 配置猜你喜欢静态页面
# 猜你喜欢的样式,文字居中,字体加粗
# 把猜你喜欢的内容封装成一个组件card
component文件夹内新建组件card
组件的静态骨架
组件的样式
发请求获取数据
封装api方法
页面给组件传参(同vue的写法,只是不需要 前边加 ":")
/pages/home/home.wxml
<!-- 底部猜你喜欢和热门推荐 -->
<view class="footer" >
<view class="like">猜你喜欢</view>
<!-- 引入组件 -->
<!-- 页面给组件传递参数:属性-类似于vue的props 不写 ":" -->
<card list="{{likeArr}}"></card>
<button class="more">查看更多</button>
<view class="like">热门推荐</view>
<card list="{{hotArr}}"></card>
<button class="more">查看更多</button>
</view>
封装card组件
新建 components 文件夹,新建组件文件夹card,新建组件card(不是新建页面)
/components/card/card.wxml
<!--components/card/card.wxml-->
<view class="card">
<!-- 卡片组件:item 即为展示商品 -->
<view class="item" wx:for="{{list}}" wx:key="id">
<image src="{{item.imageUrl}}" class="image" />
<view class="title">{{item.name}}</view>
<view class="subtitle">{{item.packing}}</view>
<view class="bottom">
<view class="price">{{item.price}}</view>
<view class="right">
<view class="money">{{item.marketPrice}}</view>
<image src="https://img02.hua.com/m/home/img/home_buy_btn.png" class="cart" />
</view>
</view>
</view>
</view>
/components/card/card.wxss
/* components/card/card.wxss */
.card {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.card .item {
width: 360rpx;
background: white;
margin: 10rpx 0rpx;
border-radius: 30rpx;
}
.card .item .title{
font-weight: 900;
font-size: 26rpx;
}
.card .item .image {
width: 360rpx;
height: 360rpx;
border-radius: 40rpx;
}
.card .item .subtitle{
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
font-size: 24rpx;
margin: 10rpx 0rpx;
height: 60rpx;
}
.card .item .bottom{
display: flex;
justify-content: space-around;
}
.card .item .bottom .right{
display: flex;
justify-content: space-between;
}
.card .item .cart {
width: 48rpx;
height: 48rpx;
margin-left: 20rpx;
}
.card .item .bottom .right .money{
color: #ccc;
text-decoration: line-through;
}
/components/card/card.js
// components/card/card.js
Component({
/**
* 组件的属性列表
*/
//类似于 vue中的 props,接收props
properties: {
list:{
type:Array
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
/components/card/card.json
{
"component": true,
"usingComponents": {}
}
引入组件
在页面上引用组件,并使用组件
在页面 中添加组件并注册
/pages/home/home.json
{
"usingComponents": {
"card":"/components/card/card"
}
}
在页面中使用组件
/pages/home.wxml
<!--pages/home/home.wxml-->
<view class="home">
<!-- 轮播图 -->
<swiper class="swiper" indicator-dots indicator-color="pink" indicator-active-color="black" autoplay interval="2000" circular>
<swiper-item wx:for="{{bannerArr}}" wx:key="id">
<image src="{{item.imageUrl}}" mode="aspectFill" class="banner" />
</swiper-item>
</swiper>
<!-- 分类 -->
<view class="cate flex">
<!-- 动态设置伸缩项目的样式 -->
<view class="cate-item flex_c {{ index > 4 && 'bottom'}}" wx:for="{{categoryArr}}" wx:key="id">
<image src="{{item.imageUrl}}" mode="" class="cate-img"/>
<text class="cate-text">{{item.name}}</text>
</view>
</view>
<!-- 首页logo -->
<image src="https://img02.hua.com/zhuanti/valentine/2023/23_valentine_mbanner_m.png?a1" mode="widthFix" class="logo"/>
<!-- 底部猜你喜欢和热门推荐 -->
<view class="footer" >
<view class="like">猜你喜欢</view>
<!-- 引入组件 -->
<!-- 页面给组件传递参数:属性-类似于vue的props 不写 ":" -->
<card list="{{likeArr}}"></card>
<button class="more">查看更多</button>
<view class="like">热门推荐</view>
<card list="{{hotArr}}"></card>
<button class="more">查看更多</button>
</view>
</view>
页面给组件传参
父组件:/pages/home/home.ts
<!--pages/home/home.wxml-->
<view class="home">
<!-- 轮播图 -->
<swiper class="swiper" indicator-dots indicator-color="pink" indicator-active-color="black" autoplay interval="2000" circular>
<swiper-item wx:for="{{bannerArr}}" wx:key="id">
<image src="{{item.imageUrl}}" mode="aspectFill" class="banner" />
</swiper-item>
</swiper>
<!-- 分类 -->
<view class="cate flex">
<!-- 动态设置伸缩项目的样式 -->
<view class="cate-item flex_c {{ index > 4 && 'bottom'}}" wx:for="{{categoryArr}}" wx:key="id">
<image src="{{item.imageUrl}}" mode="" class="cate-img"/>
<text class="cate-text">{{item.name}}</text>
</view>
</view>
<!-- 首页logo -->
<image src="https://img02.hua.com/zhuanti/valentine/2023/23_valentine_mbanner_m.png?a1" mode="widthFix" class="logo"/>
<!-- 底部猜你喜欢和热门推荐 -->
<view class="footer" >
<view class="like">猜你喜欢</view>
<!-- 引入组件 -->
<!-- 页面给组件传递参数:属性-类似于vue的props 不写 ":" -->
<card list="{{likeArr}}"></card>
<button class="more">查看更多</button>
<view class="like">热门推荐</view>
<card list="{{hotArr}}"></card>
<button class="more">查看更多</button>
</view>
</view>
子组件接收参数
子组件:/components/card/card.js
// components/card/card.js
Component({
/**
* 组件的属性列表
*/
//类似于 vue中的 props,接收props
properties: {
list:{
type:Array
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})
子组件:/components/card/card.json
{
"component": true,
"usingComponents": {}
}
/components/card/card.wxml
<!--components/card/card.wxml-->
<view class="card">
<!-- 卡片组件:item 即为展示商品 -->
<view class="item" wx:for="{{list}}" wx:key="id">
<image src="{{item.imageUrl}}" class="image" />
<view class="title">{{item.name}}</view>
<view class="subtitle">{{item.packing}}</view>
<view class="bottom">
<view class="price">{{item.price}}</view>
<view class="right">
<view class="money">{{item.marketPrice}}</view>
<image src="https://img02.hua.com/m/home/img/home_buy_btn.png" class="cart" />
</view>
</view>
</view>
</view>
/components/card/card.wxss
热门推荐部分
<!--pages/home/home.wxml-->
<view class="home">
<!-- 轮播图 -->
<swiper class="swiper" indicator-dots indicator-color="pink" indicator-active-color="black" autoplay interval="2000" circular>
<swiper-item wx:for="{{bannerArr}}" wx:key="id">
<image src="{{item.imageUrl}}" mode="aspectFill" class="banner" />
</swiper-item>
</swiper>
<!-- 分类 -->
<view class="cate flex">
<!-- 动态设置伸缩项目的样式 -->
<view class="cate-item flex_c {{ index > 4 && 'bottom'}}" wx:for="{{categoryArr}}" wx:key="id">
<image src="{{item.imageUrl}}" mode="" class="cate-img"/>
<text class="cate-text">{{item.name}}</text>
</view>
</view>
<!-- 首页logo -->
<image src="https://img02.hua.com/zhuanti/valentine/2023/23_valentine_mbanner_m.png?a1" mode="widthFix" class="logo"/>
<!-- 底部猜你喜欢和热门推荐 -->
<view class="footer" >
<view class="like">猜你喜欢</view>
<!-- 引入组件 -->
<!-- 页面给组件传递参数:属性-类似于vue的props 不写 ":" -->
<card list="{{likeArr}}"></card>
<button class="more">查看更多</button>
<view class="like">热门推荐</view>
<card list="{{hotArr}}"></card>
<button class="more">查看更多</button>
</view>
</view>
分类页面
搭建分类的静态
分类的静态骨架
# 左右两个view
分类的样式
# 左右flex布局
# 设置左右两侧的宽度
左侧的样式:
设置宽度和高度
使用scroll组件,设置scroll组件的高度
设置样式
右侧的样式:
设置宽度和高度
搭建右侧的样式
/pages/category/category.js
// pages/category/category.js
Page({
/**
* 页面的初始数据
*/
data: {
active: 0, //控制左侧菜单高亮
sortArr: [], //存储分类的数据
},
//左侧菜单点击事件回调
changeActive(event) {
//修改active数据
this.setData({
active: event.currentTarget.dataset.index
})
},
})
/pages/category/category.json
{
"usingComponents": {}
}
/pages/category/category.wxml
<!--pages/category/category.wxml-->
<view class="category flex">
<view class="left">
<!-- 滚动视图 -->
<scroll-view class="scroll" scroll-y enhanced show-scrollbar="{{false}}">
<view data-index="{{index}}" bind:tap="changeActive" class="item {{index===active&&'active'}}" wx:for="{{50}}" wx:key="{{index}}">
<text class="select" wx:if="{{index==active}}">|</text>
<image wx:if="{{index < 2}}" class="img" src="/static/category/hot.png" mode=""/>
<text>生命周期</text>
</view>
</scroll-view>
</view>
<view class="right">
<view class="title">香气护体</view>
<view class="box">
<view class="item" wx:for="{{11}}">
<image class="img" src="https://2216847528.oss-cn-beijing.aliyuncs.com/asset/20241118104045.png"/>
<text class="title">123</text>
</view>
</view>
</view>
</view>
/pages/category/category.wxss
x轴滚动案例
x轴滚动: /pages/category/category.wxml
<!--pages/shopcart/shopcart.wxml-->
<view class="shopcart">
<!-- 分类横向排列 -->
<!-- enable-flex 开启flex布局 -->
<!-- scroll-x x轴排列 -->
<!-- scroll-into-view 滚动到对应项目 -->
<!-- scroll-with-animation 滚动动画 -->
<scroll-view class="scroll" enable-flex scroll-x scroll-into-view="a{{activeNum}}" scroll-with-animation>
<view class="item {{ index == activeNum && 'active'}}"
bind:tap="changeActive"
id="a{{index}}"
data-index="{{index}}"
wx:for="{{50}}" wx:key="{{index}}">阿夸
</view>
</scroll-view>
</view>
/pages/category/category.js
// pages/shopcart/shopcart.js
Page({
/**
* 页面的初始数据
*/
data: {
activeNum:null,
},
// 改变激活状态
changeActive(event){
this.setData({
activeNum: event.currentTarget.dataset.index
})
},
})
/pages/category/category.wxss
/* pages/shopcart/shopcart.wxss */
.shopcart{
width: 750rpx;
height: 100%;
}
.shopcart .scroll{
display: flex;
height: 80rpx;
background-color: antiquewhite;
}
.shopcart .scroll .item{
width: 80rpx;
/* 伸缩项目不等比缩小 */
flex-shrink:0;
line-height: 80rpx;
text-align: center;
}
.shopcart .scroll .active{
background-color: white;
font-weight: 700;
}
获取数据渲染数据
封装获取分类数据api接口
获取数据,存储数据状态,渲染数据
api/index.js
//获取分类模块的数据
export const reqSort = () => request({
url: `/mall-api/index/findCategoryTree`
})
/pages/category/category.js
import { reqSort } from "../../api/index"
// pages/category/category.js
Page({
/**
* 页面的初始数据
*/
data: {
active: 0, //控制左侧菜单高亮
sortArr: [], //存储分类的数据
},
//左侧菜单点击事件回调
changeActive(event) {
//修改active数据
this.setData({
active: event.currentTarget.dataset.index
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
//获取分类的功能函数
this.getData();
},
// 获取分类项目的数据
async getData(){
const res = await reqSort();
if(res.code === 200){
this.setData({
sortArr:res.data
})
}
},
})
/pages/category/category.wxml
<!--pages/category/category.wxml-->
<view class="category flex">
<view class="left">
<!-- 滚动视图 -->
<scroll-view class="scroll" scroll-y enhanced show-scrollbar="{{false}}">
<view data-index="{{index}}"
bind:tap="changeActive"
class="item {{index===active&&'active'}}"
wx:for="{{sortArr}}"
wx:key="id">
<text class="select" wx:if="{{index==active}}">|</text>
<image wx:if="{{index < 2}}" class="img" src="/static/category/hot.png" mode=""/>
<text>{{item.name}}</text>
</view>
</scroll-view>
</view>
<view class="right">
<view class="title">{{sortArr[active].name}}</view>
<view class="box">
<view class="item" wx:for="{{sortArr[active].children}}"
wx:key="id"
data-category2id="{{item.id}}" >
<image class="img"
src="{{item.imageUrl}}"/>
<text class="title">{{item.name}}</text>
</view>
</view>
</view>
</view>