Ⅰ.项目介绍
1.1项目概述
慕尚花坊是⼀款同城鲜花订购 的小程序,项目常用功能模块分为项目首页、商品分类、商品列表、商品详情、用户管理、收货地址、购物车、结算支付和订单管理等等。
1.2项目技术栈
小程序内置组件:采用小程序内置组件,结合 Vant 组件库实现⻚⾯结构的搭建。
项⽬中使⽤了 css 拓展语言 Scss 绘制页面的结构。
小程序内置API:交互、支付、文件上传、地图定位、网络请求、预览图片、本地存储等。
小程序分包加载:降低⼩程序的启动时间、包的体积,提升⽤户体验度。
小程序组件开发:将页面内的功能模块抽象成⾃定义组件,实现代码的复⽤。
网络请求封装:request 方法封装、快捷⽅式封装、响应拦截器、请求拦截器。
骨架屏组件:利⽤开发者⼯具提供了⾃动⽣成⻣架屏代码的能力,提⾼了整体使用体验和用户满意 度。
UI 组件库:使用 Vant 组件库实现小程序 结构的绘制。
LBS :使⽤腾讯地图服务进行 LBS逆地址解析,实现选择收货地址功能。
miniprogram-licia :使用 licia 进行函数的防抖节流。
async-validator :使用async-validator 实现表单验证。
miniprogram-computed : 使用 miniprogram-computed 进行计算属性功能。
mobx-miniprogram :使用 mobx-miniprogram 进行项目状态的管理。
Ⅱ.项目初始化
1.1项目创建
1.2项目目录
1.3自定义构建
⾸先在project.config.json 配置 miniprogramRoot 选项,指定⼩程序源码的⽬录。
然后配置 project.config.json 的 setting.packNpmManually 为 true。
初始化项目,在内建终端打开
packageJsonPath 表示 node_modules 源对应的 package.json
miniprogramNpmDistDir 表示 node_modules 的构建结果⽬标位置
安装 vant ,然后进⾏ npm 构建,测试是否能够正常 vant 构建成功。
1.4 scss集成
在 project.config.json ⽂件中,修改 setting 下的 useCompilerPlugins 字段为 scss,即可开 启⼯具内置的 scss 编译插件。
Ⅲ.构建项目界面
1.1项目整体框架
assets⽂件导⼊ 配置app.json⽂件
{
"pages": [
"pages/category/category",
"pages/index/index",
"pages/cart/cart",
"pages/my/my"
],
"window": {
"navigationBarTextStyle": "white",
"navigationBarTitleText": "幕尚花坊",
"navigationBarBackgroundColor": "#FF734C"
},
"tabBar": {
"color": "#252933",
"selectedColor": "#FF734C",
"backgroundColor": "#ffffff",
"borderStyle":"black",
"list": [
{
"pagePath": "pages/index/index",
"text": "首页",
"iconPath": "assets/tabbar/index.png",
"selectedIconPath": "assets/tabbar/index-active.png"
},
{
"pagePath": "pages/category/category",
"text": "分类",
"iconPath": "assets/tabbar/cate.png",
"selectedIconPath": "assets/tabbar/cart-active.png"
},
{
"pagePath": "pages/cart/cart",
"text": "购物车",
"iconPath": "assets/tabbar/cart.png",
"selectedIconPath": "assets/tabbar/cate-active.png"
},
{
"pagePath": "pages/my/my",
"text": "我的",
"iconPath": "assets/tabbar/index.png",
"selectedIconPath": "assets/tabbar/my-active.png"
}
]
},
"sitemapLocation": "sitemap.json",
"lazyCodeLoading": "requiredComponents",
"usingComponents": {
"van-button": "@vant/weapp/button/index",
"van-card": "@vant/weapp/card/index",
"van-submit-bar": "@vant/weapp/submit-bar/index"
}
}
1.2样式图
Ⅳ.首页
1.1首页结构
在index.wxml构建首页结构
<view class="index-container">
<!-- 首页背景图 -->
<view class="window-bgc"></view>
<!-- 页面主体部分 -->
<view class="container">
<!-- 轮播图区域 -->
<banner />
<!-- 导航区域 -->
<entrance />
<!-- 广告区域 -->
<view class="adver">
<view class="adver-left">
<navigator url="">
<image src="../../assets/images/love.jpg" mode="widthFix" />
</navigator>
</view>
<view class="adver-right">
<view>
<navigator url="">
<image src="../../assets/images/elder.jpg" mode="widthFix" />
</navigator>
</view>
<view>
<navigator url="">
<image src="../../assets/images/friend.jpg" mode="widthFix" />
</navigator>
</view>
</view>
</view>
<!-- 商品列表 -->
<goods-list title="人气推荐"/>
<goods-list title="猜我喜欢"/>
<goods-card/>
</view>
</view>
1.1.1navigator
navigator是一个全局对象,它提供了与浏览器相关的信息和操作接口。在前端开发中,我们通常会使用 navigator 对象来获取用户浏览器的相关信息。
navigator 对象的常见属性和方法包括:
navigator.userAgent: 返回当前浏览器的用户代理字符串。
navigator.appName: 返回当前浏览器的名称。
navigator.appVersion: 返回当前浏览器的版本号。
navigator.language: 返回当前浏览器的语言设置。
navigator.platform: 返回当前浏览器所在设备的操作系统平台。
navigator.geolocation: 提供了一组 API,用于获取当前设备的地理位置信息。
navigator.mediaDevices: 提供了一组 API,用于访问当前设备的音频、视频、屏幕等媒体设备。
navigator.serviceWorker: 提供了一组 API,用于在浏览器中注册和管理 Service Worker,实现离线缓存和推送通知等功能
1.2首页背景图
在index.sass中构建首页样式
.index-container{
//首页背景图
.window-bgc{
height: 200rpx;
position:absolute;
width:100%;
background-color: #f3514f;
border-radius:0rpx 0rpx 40% 40%;
}
.adver {
display: flex;
margin:0 auto;
width: 96%;
padding: 18rpx;
box-sizing: border-box;
background-color:rgb(177, 54, 54);
border-radius: 18rpx;
.adver-left{
width: 50%;
padding: 8rpx 8rpx 0rpx 8rpx;
}
.adver-right{
width: 50%;
padding: 8rpx 8rpx 0rpx 6rpx;
view:laat-child{
padding-top: 10rpx;
}
}
image{
width: 100%;
}
}
}
1.2.1 flex布局
flex-direction属性
flex-direction属性用于设置主轴方向,通过设置主轴方向可以规定项目的排列方向。
row:默认值,主轴为从左到右的水平方向。
row-reverse:主轴为从右到左的水平方向。
column:主轴为从上到下的垂直方向。
column-reverse:主轴为从下到上的垂直方向。
justify-content属性
justify-content属性用于设置项目在主轴方向上的对齐方式。能够分配项目之间及其周围 多余的空间。
flex-start:默认值,表示项目对齐到主轴起点,项目间不留空隙。
flex-end:项目对齐到主轴终点,项目间不留空隙。
center:项目在主轴上居中排列,项目间不留空隙。
space-between:两端对齐,两端的项目分别靠向容器的两端,其他项目之间的间隔相等 space-around:每个项目之间的距离相等
align-items属性align-items属性用于设置项目在交叉轴上的对齐方式。
center:项目在交叉轴的中间位置对齐。
flex-start:项目顶部与交叉轴起点对齐,flex-end:项目底部与交叉轴终点对齐。
baseline:项目的第一行文字的基线对齐。
1.3 banner组件
1.3.1构建banner组件结构
banner.js
Properties
(1)Properties类是专门用于读写配置文件的集合类
(2)配置文件的后缀名为.properties
(3)Properties类的方法可查找api文件
banner.json
1.4轮播图组件
在banner.wxml中通过swiper组件建立一个自动轮播列表
使用wx:for循环遍历bannerList数组
bannerList.length为数组长度
<view class="swiperbox">
<swiper autoplay class="swiper" indicator-active-color="#FF734C" interval="2000" duration="1000" indicator-color="rgba(0,0,0,3)">
<block wx:for="{{ bannerList }}" wx:key="index">
<swiper-item class="swiper-item">
<image class="img" src="{{item}}"></image>
</swiper-item>
</block>
</swiper>
<view class="indicator">
<text wx:for="{{bannerList.length}}" wx:key="id"
class="rectangle"></text>
</view>
</view>
设置swiperbox样式
.swiperbox{
position: relative;
.swiper{
height: 320rpx;
//设置圆角弧度
border-radius: 18rpx;
//设置溢出隐藏
overflow: hidden;
width: 95%;
//margin设置外边距
margin: 0 auto;
}
.swiper-item{
.img{
width: 100%;
height: 100%;
border-radius: 18rpx;
}
}
.indicator{
display: flex;
justify-content: center;
position: absolute;
bottom: 16rpx;
left: 0rpx;
right: 0rpx;
.rectangle{
width: 30rpx;
height: 6rpx;
background-color: #f3514f;
margin: 0 8rpx;
border-radius: 6rpx;
}
}
}
样式图
1.5entrance导航组件
在entrance.wxml中渲染一个导航列表
<view class="nav-list">
<view wx:for="{{10}}" wx:key="index" class="nav-item">
<navigator url="" class="navigator-nav">
<image src="../../../assets/images/cate-1.png" mode="" class="nav-img"/>
<text class="nav-text">鲜花玫瑰</text>
</navigator>
</view>
</view>
导航分类样式
.nav-list {
//设置弹性布局
display: flex;
//设置换行
flex-wrap: wrap;
margin: 20rpx;
border-radius: 18rpx;
padding: 10px 0px 10px 10px;
background-color: white;
}
.nav-item {
.navigator-nav {
//更改主轴方向
//由默认的横向排列更改为纵向排列
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-right: 10px;
margin-top: 10px;
.nav-text {
margin-top: 4px;
font-size: 12px;
}
.nav-img {
width: 66rpx;
height: 66rpx;
}
}
}
1.6完成广告区域
广告区域结构
<!-- 广告区域 -->
<view class="adver">
<view class="adver-left">
<navigator url="">
<image src="../../assets/images/love.jpg" mode="widthFix" />
</navigator>
</view>
<view class="adver-right">
<view>
<navigator url="">
<image src="../../assets/images/elder.jpg" mode="widthFix" />
</navigator>
</view>
<view>
<navigator url="">
<image src="../../assets/images/friend.jpg" mode="widthFix" />
</navigator>
</view>
</view>
</view>
广告区域样式
.adver {
display: flex;
margin:0 auto;
width: 96%;
padding: 18rpx;
box-sizing: border-box;
background-color:rgb(177, 54, 54);
border-radius: 18rpx;
.adver-left{
width: 50%;
padding: 8rpx 8rpx 0rpx 8rpx;
}
.adver-right{
width: 50%;
padding: 8rpx 8rpx 0rpx 6rpx;
view:laat-child{
padding-top: 10rpx;
}
}
样式图:
1.7注册goods-card和goods-list全局组件
在index.wxml设置两个标题
1.7.1完成goods-card组件
在goods-card.wxml中构建结构
<view class="goods_cart_container">
<navigator url="" class="navigator-nav">
<image src="../../assets/images/floor.jpg" mode="widthFix" class="good_img" />
<!-- 详细信息-->
<view class="goods_item_info">
<!-- 商品名称-->
<text class="goods_item_info_name">亲爱的/情人节网红款/19枝</text>
<!-- 商品描述-->
<text class="goods_item_info_promo">情人节新品情人节新品情人节新品</text>
<!-- 商品价钱-->
<view class="goods_item_info_bottom">
<!-- 优惠价钱 -->
<view class="goods_item_info_price">
<text class="text">$</text>99
</view>
<!-- 原价 -->
<view class="goods_item_info_origin_price">
<text class="text">$</text>199
</view>
<!-- 购物车 -->
<view class="goods_item_info_btn">
<image class="goods_image" src="../../assets/images/buybtn.png" mode="" />
</view>
</view>
</view>
</navigator>
</view>
在goods-card.scss中构建样式
.goods_cart_container{
width: 350rpx;
margin-top: 18rpx;
background: #fff;
border-radius: 18rpx;
}
.good_img{
width: 100%;
max-height: 360rpx;
border-top-left-radius: 18rpx;
border-top-right-radius: 18rpx ;
}
.goods_item_info{
//设置弹性布局
display: flex;
//更改主轴方向为纵轴
flex-direction: column;
padding: 10rpx 20rpx;
}
.goods_item_info .goods_item_info_name{
//设置字体粗细
font-weight: 600;
font-size: 30rpx;
line-height: 20px;
//溢出隐藏
overflow: hidden;
//超过一行就算溢出
white-space: nowrap;
//溢出之后的文本为省略号
text-overflow: ellipsis;
}
.goods_item_info .goods_item_info_promo{
padding-top: 20rpx;
padding-bottom: 3px;
font-size: 12px;
color: #71797f;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.goods_item_info_bottom{
//弹性布局 在同一行显示
display: flex;
line-height: 50rpx;
margin-top: 20rpx;
}
.goods_item_info_bottom .goods_image{
width: 48rpx;
height: 48rpx;
}
.goods_item_info_price{
font-size: 30rpx;
font-weight: bold;
color: #f3514f;
}
.goods_item_info_price .text{
font-size: 24rpx;
padding-right: 4rpx;
font-weight: normal;
}
.goods_item_info_origin_price{
//设置flex为1 则该元素拥有所有剩余部分
flex:1;
font-size: 20rpx;
color: #71797f;
text-decoration-line:line-through;
margin-left: 6%;
margin-top: 4rpx;
}
.goods_item_info_origin_price .text{
font-size: 20rpx;
}
1.7.2完成goods-list组件
在goods-list.wxml中构建结构
<!-- 商品列表组件-->
<view class="goods_container">
<!-- 标题-->
<view class="goods_title">{{ title }}</view>
<!-- 列表区域-->
<view class="goods_card_list">
<block wx:for="{{ 3 }}" wx:key="index">
<goods-card />
</block>
</view>
</view>
<!-- 查看更多-->
<view class="goods_more">
<navigator url="" class="goods_more_btn">查看更多</navigator>
</view>
在goods-list.scss中构建样式
.goods_title{
//设置文本居中
text-align: center;
font-size: 40rpx;
line-height: 52rpx;
font-weight: bold;
color: #232628;
padding: 20rpx 0 0rpx 0rpx;
}
.goods_card_list{
display: flex;
//设置换行
flex-wrap: wrap;
//设置元素在主轴上的排列方式
justify-content: space-between;
}
.goods_card_list::after{
content:'' ;
width: 350rpx;
}
.goods_more{
margin: 10rpx 0;
}
.goods_more_btn{
width: 95%;
display: block;
margin: 0 auto;
background: rgb(233, 94, 94);
margin: 0 auto;
border-radius: 20rpx;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 14px;
color: rgba(35,38,40,0.7);
}
样式图
Ⅴ.分类
1.1分类结构
<view>
<view class="category-container">
<scroll-view class="category-left-view" scroll-y>
<view class="left-view-item active">爱礼精选</view>
<view class="left-view-item ">鲜花玫瑰</view>
<view class="left-view-item ">永生玫瑰</view>
<view class="left-view-item ">玫瑰珠宝</view>
</scroll-view>
<scroll-view class="category-right-view" scroll-y>
<view class="test">
<view wx:for="{{ 10 }}" wx:key="index" class="right-view-item">
<navigator class="navigator" url="">
<image class="" src="../../assets/images/cate-1.png" mode="" />
<text class="goods_item_name">真情告白</text>
</navigator>
</view>
</view>
</scroll-view>
</view>
</view>
1.2分类样式
.category-container {
display: flex;
.category-left-view {
width: 220rpx;
height: 100vh;
background: #fff !important;
.left-view-item {
line-height: 99rpx;
//文本排列方式
text-align: center;
font-size: 26rpx;
}
.active {
background-color: #ffffff;
position: relative;
color: #f3514f;
//&表示当前标签
//::before是伪元素选择器
//在指定元素的添加内容
&::before {
content: '';
display: block;
width: 6rpx;
height: 66rpx;
background-color: #f3514f;
position: absolute;
left: 0;
top: 50%;
//沿着y轴平移
transform: translateY(-50%);
}
}
}
}
.category-right-view{
width: 100%;
height: 100vh;
flex-wrap: wrap;
background: #fff !important;
margin-left: 8rpx;
.right-view-item{
width: 33%;
float: left;
margin-top: 30rpx;
.navigator{
display: flex;
flex-direction: column;
align-items: center;
}
image{
width: 90rpx;
height: 90rpx;
}
text{
font-size: 26rpx;
margin-top: 18rpx;
}
&::before{
content: '';
display: block;
width: 6rpx;
height: 100vh;
background-color: rgb(177, 174, 174);
position: absolute;
left: 0;
top: 0%;
transform: translateY();
}
}
}
1.2.1伪元素选择器
所谓“伪元素” 就是在dom结构本来是不存在的 但是通过css创建出来的元素
::before ::after
用于向指定元素的前面或者后面加入特定的内容
样式图
Ⅵ.购物车
1.1购物车结构
<view class="container">
<!-- 购物车列表区域 -->
<view class="carList-container" wx:if="{{carList.length}}">
<view class="carList-container-cell" wx:for="{{carList}}" wx:key="index">
<van-swipe-cell right-width="{{ 65 }}" left-width="{{ 65 }}">
<view slot="left" class="van-swipe-cell__left">选择</view>
<van-cell-group>
<view class="goods-info">
<view class="left">
<van-checkbox value="{{ false }}" checked-color="#e60017" bind:change="onChange">
</van-checkbox>
</view>
<view class="mid">
<image src="../../assets/images/floor-img.jpg" mode="" />
</view>
<view class="right">
<view class="title">【11枝红玫瑰】买玫瑰送老婆</view>
<view class="buy">
<view class="price">¥99.00</view>
<view class="buy-btn">
<van-stepper value="{{ 1 }}" bind:change="onChange" />
</view>
</view>
</view>
</view>
</van-cell-group>
<view slot="right" class="van-swipe-cell__right">删除</view>
</van-swipe-cell>
</view>
</view>
<!-- 购物车列表为空的情况 -->
<van-empty description="还没有商品,快去添加吧~" wx:else>
<navigator url="">
<van-button round type="danger">去购物</van-button>
</navigator>
<navigator url="">
<van-button round type="danger">去登录</van-button>
</navigator>
</van-empty>
<!-- 提交订单栏区域 -->
<van-submit-bar price="{{ 3050 }}" button-text="提交订单" bind:submit="onClickButton" tip="{{ true }}">
<van-checkbox value="{{ true }}" checked-color="#e60017" bind:change="onChange">
全选
</van-checkbox>
</van-submit-bar>
</view>
1.1.1 wx:for嵌套
wx:for 是用来做列表渲染,在组件上使用wx:for绑定一个数组,数组的下标变量名默认为index,数组当前项的变量名默认为item.
1.1.2 wx:key遍历数组
wx:key 提升性能。
wx:key 属性值有两种添加属性。
字符串,需要是遍历的数组中 item 的某个属性,要求该属性是列表中唯一的字符串或者数字,不能进行动态改变。
保留关键字 this ,this代表的是 item 本身,item 本身是唯一的字符串或者数字
1.2购物车样式
.container {
background-color: whitesmoke;
height: 100vh;
}
.carList-container {
.carList-container-cell {
.goods-info {
display: flex;
background-color: white;
border-radius: 16rpx;
margin: 20rpx 20rpx 5rpx 20rpx;
padding: 24rpx 16rpx;
.left {
display: flex;
align-items: center;
}
.mid {
width: 200rpx;
height: 230rpx;
image {
width: 100%;
height: 100%;
}
}
.right {
display: flex;
flex-direction: column;
height: 230rpx;
justify-content: space-between;
padding-left: 20rpx;
.title {
font-size: 26rpx;
}
.buy {
display: flex;
justify-content: space-between;
.price {
font-size: 30rpx;
color: #fa4126;
}
}
}
}
}
}
.van-empty__bottom {
height: 250rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
}
1.2.1 margin和padding的使用(内外边距)
外边距(margin):
外边距定义了元素与其周围元素之间的空白区域。
外边距可以设置为正值、负值或百分比。
外边距可以用来控制元素之间的间距、对齐元素、扩展元素的可点击区域等。
外边距不会影响元素的背景颜色或边框。
内边距(padding):
内边距定义了元素的内容与其边框之间的空白区域。
内边距可以设置为正值、负值或百分比。
内边距可以用来控制元素内容与边框之间的间距、增加元素的可点击区域等。
内边距会影响元素的背景颜色。
在CSS中,可以使用以下属性来控制外边距和内边距:
外边距属性:
margin-top:顶部外边距
margin-right:右侧外边距
margin-bottom:底部外边距
margin-left:左侧外边距
内边距属性:
padding-top:顶部内边距
padding-right:右侧内边距
padding-bottom:底部内边距
padding-left:左侧内边距
这些属性可以接受不同的值,例如像素(px)、百分比(%)、em等
1.2.2 justify-content
justify-content 属性:设置主轴的对齐方式,弹性子元素在主轴方向上的对齐方式,
justify-content: flex-start; 默认值,主轴顶端对齐
justify-content: flex-end; 主轴的末端对齐
justify-content: center; 居中对齐,子元素位于弹性容器的中心
justify-content: space-between; 两端对齐,子元素和子元素之间有空白空间,项目之间的间隔都相等。
justify-content: space-around; 子元素之前、之间、之后都留有空白空间,且空间自行分配,项目之间的间隔比项目与边框的间隔大一倍。
space-evenly:弹性项目平均分布在该行上,相邻项目的间隔,项目与容器之间空间相等
1.3效果图
Ⅶ.我的
版权归原作者 鹿辞 所有, 如有侵权,请联系我们删除。