uni-app商城项目
黑马商城实战项目 项目搭建
- 利用HBuilder X创建基本项目结构
- 运行项目
- 整理基本项目结构,并修改窗口外观
"globalStyle": { "navigationBarTextStyle": "white", "navigationBarTitleText": "黑马商城", "navigationBarBackgroundColor": "#1989fa", "backgroundColor": "#F8F8F8" }
- 创建tabbar对应的四个页面和图标准备好
- 将页面路径配置到pages.json中的pages数组中
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages { "path": "pages/index/index" }, { "path": "pages/member/member" }, { "path": "pages/cart/cart" }, { "path": "pages/search/search" } ]
- 配置tabbar
{ "tabBar": { "list": [ { "pagePath":"pages/index/index", "text":"首页", "iconPath":"static/icon/home.png", "selectedIconPath":"static/icon/home-active.png" }, { "pagePath":"pages/member/member", "text":"会员", "iconPath":"static/icon/member.png", "selectedIconPath":"static/icon/member-active.png" }, { "pagePath":"pages/cart/cart", "text":"购物车", "iconPath":"static/icon/cart.png", "selectedIconPath":"static/icon/cart-active.png" }, { "pagePath":"pages/search/search", "text":"搜索", "iconPath":"static/icon/search.png", "selectedIconPath":"static/icon/search-active.png" } ]} }
- 封装uni.request请求,并挂在到全局
- 创建util》api.js
// 封装get请求 const baseUrl = "http://localhost:8082" export const myRequest = (options)=>{ return new Promise((resolve,reject)=>{ uni.request({ method: options.method, data: options.data, url: baseUrl+options.url, success(res) { if(res.data.status !== 0) { return uni.showToast({ title: '获取数据失败' }) } resolve(res) }, fail(err) { uni.showToast({ title: '获取数据失败' }) reject(err) } }) }) }
- 在main.js中导入并挂载到全局
import { myRequest } from './util/api.js' Vue.prototype.$myRequest = myReques
- 创建util》api.js
- 获取轮播图的数据
- 定义获取轮播图的方法
methods: { async getSwipers () { const res = await this.$myRequest({ method: 'GET', url: '/api/getlunbo' }) this.swipers = res.data.message } }
- 在onLoad中调用该方法
this.getSwipers()
- 定义获取轮播图的方法
- 定义轮播图的基本结构
- 样式,在工具中安装scss
.home{ swiper{ height: 380rpx; image{ width: 750rpx; height: 380rpx; } } }
@font-face {font-family: "iconfont";
src: url('~@/static/fonts/iconfont.eot?t=1576335469449');
/* IE9 */
src: url('~@/static/fonts/iconfont.eot?t=1576335469449#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;
charset=utf-8;
base64,d09GMgABAAAAAAVMAAsAAAAAChwAAAT/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDKAqHQIYhATYCJAMUCwwABCAFhG0HUBurCFGUTk6f7EeBu6eIlFFajBY208XLlGHx/6/hiYfvx76d+2xFJLlUn75pp4tCoyQ8NgiJUJjuJfzNpSrpXIDoeDbs3GjyH7Lfv+zTy1mok+GyEhYAW8AKaPvz/6eeG1QvDUo6SQW8bE4KYTDSMRj1R/5x7/TP88Dmo7Jc/misYXOelwWYYEBjbGxrAQ7KEvQW8SwuJBO4nkCvRQ21q/PbB5hXQLdAvDU6gHmbRQnhhG598xlb1lEvsu70PvEBfFU/H/+hF1IkNYO+149nMRz+6v7/fwrv4JAqI6T5uXCbRMYWUIhnX8+tKT22ZUrvJ3PaCdCNryR+Sb2RfRPT+c9kbdF0s788siIRDWj6GXkWL/ySEsVkfsmyftoYKiIZsiQfJ+Y2ll7MgdgDiE/AMF+CumLWsCSpdFXpjsNkefoatW8WSY8xapRhreWm1a9vWvVEM6edaQdPapImTzTLLG4BwEBG/HJsK4bVEKkStJbxbUYy3othvO2ofJA7jBARcUZ4illDuEL29TB2C/3AGWj4WUfGYbG25LTICaEk1jWBR8KWC0bqQJ+EjJYmOnvisiHzqtifvZ08X7NYzBaJWAJBglDIRIi3Fd/C3cbZjqEKvkh9Qmx2SKCgMAhD15VHVkCQMCWOP72YnLB0euHUpROzJ/PEYiR6wxK8ShC+ZsryVibGlbIzorOjqRKnhwyOKTIlMRoPSLgMlYvInDIKdwsQ8K2YbO2PReRsyxzZvrK0dWxUYUrIE2sPj8+sHNw6tUVhj0AgslvelUfhDnNG4k0YwgedbyX/ovPRL8SnqwOt/atMII/RGGMacyXGJOaq+MtGYDFMOL1Hk8OSJdfqARNMZkPmnDVh5DP0bjDpx6XAB6RO0JkqM4F0fNSNZMKXB20QqI//n+swdzCvnv1/JszOzMEszPsskD8RZtrarNB14gGhubjWlduokVnWD9e9PyCQd1jtvPjStKTGs6VZFT/xjhhW0hpkG6PoC0wW8iGUrPK9prFY4AM+9GF8APhKfIvr5tct+IoAxU/eE3ILa4yrDxTgUfkrG0lPTtshU4pGtXT9UJqywWkDhzyi/5ka15D+WlPn1Gd+QYF7s0j3dXTuS0oStZLum6on86NOwIbPcydIP3+STiDFaYk1Z6WFLPt7b7M6EhMA+Gr+qtDilfia4mPFr0p8JZUS973QHulzYJxsPjJ6xdeW7Wd75WHHrZsGDXaUb1hacCuQVmrOkt1DjdgTxSeY3EcWDqCzRLxB9PmH2DNplYhzhCDbNLfzY7dKy1jb/dqNFfBTXbWg8vhWsH1JP9IN0VQmIcif4isHay1vtVDzNIiyxeirbpZ0JKEXg3QAAqN+8jFMLN9E6DZhQtJlAbJuS2ght6DqcwRNt1Potelicp8xbEqUHmz4IBCGfUIy6DtkwyZoIb+hmvQLzXAQoddNbM3ZZyWKFk+YAqEYwxGayJZKsMuiVnxH2ucBW+Uq94m4MkHstjrO5AWVxHkMqPq6J6JQsS3wnGxGeW7RsU0pklYi4rbbbeV3plZkC1h0iZGAIDEUGkFGxCopubpYdL3/DtG8XIBDSn4knxBWMbWjrpZODPRCU8YqWZfGlT6tRwjFOynMKqBz6iI5xizk/FulSES0JCkizrY2q6Tialrl64ppLD0VysKcNVLkKFGjae8S40w5K14OB+WS9lKjkR/YgsrZsRnZzAAA') format('woff2'),
url('~@/static/fonts/iconfont.woff?t=1576335469449') format('woff'),
url('~@/static/fonts/iconfont.ttf?t=1576335469449') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('~@/static/fonts/iconfont.svg?t=1576335469449#iconfont') format('svg');
/* iOS 4.1- */
}.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}.icon-shipin:before {
content: "\f0024";
}.icon-tupian:before {
content: "\e650";
}.icon-guanyuwomen:before {
content: "\e608";
}.icon-ziyuan:before {
content: "\e60d";
}
完成菜单导航基本结构
黑马超市
联系我们
社区图片
视频专区
菜单导航样式
.nav{
display: flex;
align-items: center;
.item{
width: 25%;
text-align: center;
view{
background: $shop-color;
line-height: 120rpx;
width: 120rpx;
height: 120rpx;
border-radius: 90px;
margin:10px auto;
}
text{
font-size: 15px;
}
}
.iconfont{
font-size: 25px;
color: #fff;
height: 50px;
}
.icon-tupian{
font-size: 20px;
}
}
实现推荐商品列表 定义基本结构
推荐商品
1299
12990
华为(HUAWEI)荣耀6Plus 16G双4G版
美化样式
.hot_goods {
background: #eee;
.tit{
border-top: 2px solid #eee;
border-bottom: 2px solid #eee;
margin-top: 20px;
margin-bottom: 3px;
color: $shop-color;
height: 50px;
line-height: 50px;
text-align: center;
letter-spacing: 20px;
background: #fff;
}
.goods_list {
display: flex;
padding: 0 15rpx;
justify-content: space-between;
overflow: hidden;
flex-wrap: wrap;
.goods_item {
width: 355rpx;
margin-bottom: 15rpx;
background: #fff;
padding: 10px;
box-sizing: border-box;
image{
height: 150px;
width: auto;
mix-width:160px;
margin: 10px auto;
}
.price{
font-size: 18px;
color: red;
padding: 8px 0;
text:nth-child(2){
color: #ccc;
text-decoration: line-through;
margin-left: 10px;
font-size: 13px;
}
}
.name {
font-size: 14px;
}
}
}
}
获取数据
- 【uni-app商城项目】定义获取数据的方法
// 获取推荐商品 async getGoods () { const res = await this.$myRequest({ url: '/api/getgoods?pageindex=1' }) this.goods = res.data.message }
- 在onLoad生命周期中调用该方法
this.getGoods()
- 通过v-for渲染数据
推荐商品 {{item.sell_price}} {{item.market_price}} {{item.title}}
- 定义数据
navs: [ { icons: "iconfont icon-ziyuan", title: "黑马超市", path: "/pages/goods/list" }, { icons: "iconfont icon-tupian", title: "社区图片", path: "/pages/pics/pics" }, { icons: "iconfont icon-guanyuwomen", title: "联系我们", path: "/pages/contact/contact" }, { icons: "iconfont icon-shipin", title: "学习视频", path: "/pages/videos/videos" } ]
- 渲染数据
{{item.title}}
- 给导航菜单注册点击事件
- 定义跳转的方法
goNavigator (url) { uni.navigateTo({ url }) }
- 创建页面,goods>list.vue
- 将页面路劲配置到pages文件中,修改标题
- 在components下面创建goods>list.vue
{{item.sell_price}} {{item.market_price}} {{item.title}}
- 在首页引入该组件
import goodsList from "../../components/goods-list/index.vue"components: { "goods-list":goodsList }
- 使用组件并将数据传递到组件内部
- 定义获取商品列表数据的方法并调用
- 引入商品组件并使用
- 通过onReachBottom来监听触底
onReachBottom () { this.pageindex++ this.getGoods() }
- 修改给goods赋值
this.goods = [...this.goods,...res.data.message]
- 动态显示底线
- 通过onReachBottom监听是否还有更多
if(this.pageindex*10>this.goods.length) return this.flag = true
- 通过v-if控制底线
----------我是有底线的----------
- 通过onReachBottom监听是否还有更多
- 通过onPullDownRefresh进行下拉刷新的操作
onPullDownRefresh() { this.goods = [] this.pageindex = 1 this.flag = false setTimeout(()=>{ this.getGoods(()=>{ uni.stopPullDownRefresh() }) },1000) }
1季度多家房企利润跌幅超50% 去库存促销战打响
发表时间:2019-12-23
浏览:1次
样式
.news{
.news_item{
display: flex;
padding: 5px 10px;
border-bottom: 3px solid $shop-color;
image{
width: 300rpx;
height: 150rpx;
}
.content {
padding: 5px 10px;
position: relative;
.tit{
font-size: 30rpx;
}
.info{
font-size: 26rpx;
position: absolute;
left: 10px;
bottom: 5px;
text:nth-child(2){
margin-left: 20px;
}
}
}
}
}
封装为组件 创建news-item.vue
{{item.title}}
发表时间:{{item.add_time | formatDate}}
浏览:{{item.click+123}}次
.news_item{
display: flex;
padding: 5px 10px;
border-bottom: 1rpx solid $shop-color;
image{
max-width: 200rpx;
min-width: 200rpx;
height: 150rpx;
}
.content {
padding: 5px 10px;
position: relative;
.tit{
font-size: 30rpx;
}
.info{
font-size: 26rpx;
position: absolute;
left: 10px;
bottom: 5px;
text:nth-child(2){
margin-left: 20px;
}
}
}
}
在新闻页面导入并使用
点击列表进入详情
- 点击子组件列表项通过this.$emit触发父组件的方法
navigatorTo (item) { this.$emit('clickItem',item) }
- 父组件通过注册clickItem事件及事件函数实现跳转操作
- 新建/pages/news-detail/news-detail页面
标题
发表时间:
浏览:
.news_detail {
padding: 15rpx;
.news_title{
text-align: center;
font-size: 32rpx;
}
.info{
font-size: 28rpx;
display: flex;
justify-content: space-between;
}
}
获取详情的数据
methods: {
async getNewsDetail(id){
const res = await this.$myRequest({
url: '/api/getnew/'+id
})
console.log(res)
this.newsDetail = res.data.message[0]
}
},onLoad (options){
this.getNewsDetail(options.id)
}
实现详情的渲染
{{newsDetail.title}}
发表时间:{{newsDetail.add_time | formatDate}}
浏览:{{newsDetail.click}}
实现商品详情页 商品列表注册点击事件
父组件绑定自定义事件进行跳转
godetail (item) {
uni.navigateTo({
url: '/pages/goods-detail/goods-detail?id='+item.id
})
}
创建商品详情页 获取详情轮播图数据
methods: {
async getDetail(){
const res = await this.$myRequest({
url:'/api/getthumimages/'+this.id
})
console.log(res)
}
},
onLoad(options){
this.id = options.id
this.getDetail()
}
渲染轮播图
.goods_detail{
swiper{
height: 700rpx;
image{
width: 100%;
height: 100%;
}
}
}
获取商品信息
methods: {
async getDetailInfo () {
const res = await this.$myRequest({
url:'/api/goods/getinfo/'+this.id
})
this.info = res.data.message[0]
}
},
onLoad(options){
this.id = options.id
this.getDetailInfo()
}
完成商品信息结构和渲染
推荐阅读
- 17|17 关山松 第二课作业#公众号项目# D20
- RxJava|RxJava 在Android项目中的使用(一)
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- 靠QQ月入上万灰色暴利偏门的项目
- spring|spring boot项目启动websocket
- vuex|vuex 基础结构
- 区块链开发平台(以太坊)
- java|java b2b2c shop 多用户商城系统源码- config 修改配置
- 如何在手机上查看测试vue-cli构建的项目
- django2.2|django2.2 一般项目步骤(初步)