项目实战
一、项目搭建
- 利用HBiulder创建基本项目结构
- 运行项目
- 整理基本结构,并修改窗口外观
"globalStyle": {
"navigationBarTextStyle": "white", //标题文字颜色
"navigationBarTitleText": "商场", // 整体标题名称
"navigationBarBackgroundColor": "#b50e03",
"backgroundColor": "#F8F8F8"
},
二、配置tabbar

"tabBar": {
"selectedColor": "#b50e03", //选中的文字颜色
"color": "#CCC", //未选中图片颜色
"list": [{
"text": "首页", //标题
"pagePath": "pages/index/index", //首页
"iconPath": "static/icon/home.png", //未选中图标
"selectedIconPath": "static/icon/home-active.png" //选中图标
}, {
"text": "咨询",
"pagePath": "pages/news/news",
"iconPath": "static/icon/news.png",
"selectedIconPath": "static/icon/news-active.png"
}, {
"text": "购物车",
"pagePath": "pages/cart/cart",
"iconPath": "static/icon/cart.png",
"selectedIconPath": "static/icon/cart-active.png"
}, {
"text": "会员",
"pagePath": "pages/member/member",
"iconPath": "static/icon/member.png",
"selectedIconPath": "static/icon/member-active.png"
}]
},
三、获取轮播图数据
轮播图接口
接口地址:/api/getlunbo
请求方式:GET
参数:无
数据格式:
{
"status":0,
"message":[
{
"id":1,
"url":"http://www.itcast.cn/subject/phoneweb/index.html",
"img":"http://m.itheima.com/images/slidead/mobile/20191213180241750x410.jpg"
},
{
"id":2,
"url":"http://www.itcast.cn/subject/phoneweb/index.html",
"img":"http://m.itheima.com/images/slidead/mobile/20191210154717750-410.jpg"
},
{
"id":3,
"url":"http://www.itcast.cn/subject/phoneweb/index.html",
"img":"http://m.itheima.com/images/slidead/mobile/20190327135101750x410-%E4%BC%A0%E6%99%BA%E9%BB%91%E9%A9%AC%E7%A7%BB%E5%8A%A8%E7%AB%AF%E5%B9%BB%E7%81%AF.jpg"
}
]
}
1.常规get请求获取轮播图
<script>
export default {
data() {
return {
swiper: []
}
},
onLoad() {
},
methods: {
//获取轮播图的数据
getSwiper() {
console.log("获取轮播图数据!")
uni.request({
url: "http://localhost:8082/api/getlunbo",
success: (res) => { //这里注意要用箭头函数才能找到数据
if (res.data.status !== 0) {
return uni.showToast({
title: "获取轮播图失败!"
})
}
this.swiper = res.data.message;
}
})
}
},
onLoad() { //加载好后调用获取轮播图方法
this.getSwiper();
}
}
</script>
2.封装uni.request请求
util - api.js文件封装
const BASE_URL = 'http://localhost:8082' // 这里定义域名
export const myRequest = (options) => {
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + options.url, // 接口地址
method: options.method || 'GET', // 默认GET请求
data: options.data || {}, // 默认没有参数
success: (res) => {
if (res.data.status !== 0) { // 状态码判断为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 = myRequest;
如何使用GET
<script>
export default {
data() {
return {
swipers: []
}
},
onLoad() {
},
methods: {
//获取轮播图的数据
async getSwiper() {
const res = await this.$myRequest({
url: "/api/getlunbo"
})
console.log(res.data)
this.swipers = res.data.message;
}
},
onLoad() {
this.getSwiper();
}
}
</script>
四、实现轮播图结构数据渲染
swiper swiper | uni-app官网 (dcloud.net.cn)
滑块视图容器。【设计人员应以375px的宽度设计小程序】
一般用于左右滑动或上下滑动,比如banner轮播图。
组件代码
<swiper indicator-dots circular>
<swiper-item v-for="item in swipers" :key="item.id">
<image :src="item.img"></image>
</swiper-item>
</swiper>
SCSS样式
.home {
swiper {
width: 750rpx;
height: 380rpx;
image {
height: 100%;
width: 100%;
}
}
}
五、实现菜单导航结构
1.导入字体图标库需要的文件

2.修改引用路径iconfont.css

3.导入到App.vue中
<style>
@import url(./static/font/iconfont.css);
</style>
导航区域代码

VUE代码
<template>
<view class="home">
<!-- 导航区域 -->
<view class="nav">
<view class="nav_item" v-for="(item,index) in navs" :key="index" @click="navItemClick(item.path)">
<view :class="item.icon"></view>
<text>{{item.title}}</text>
</view>
</view>
</view>
</template>
JS代码
<script>
export default {
data() {
return {
navs: [{
icon: 'iconfont icon-ziyuan',
title: '黑马超市',
path: '/pages/goods/goods'
},
{
icon: 'iconfont icon-guanyuwomen',
title: '联系我们',
path: '/pages/contact/contact'
},
{
icon: 'iconfont icon-tupian',
title: '社区图片',
path: '/pages/pics/pics'
},
{
icon: 'iconfont icon-shipin',
title: '学习视频',
path: '/pages/videos/videos'
}
]
}
}
}
</script>
scss样式
<style lang="scss">
.home {
.nav {
display: flex; // 开启flex布局,飘到一行
.nav_item {
width: 25%; // 一行4个
text-align: center; // 文字居中
view {
width: 120rpx; //宽度
height: 120rpx; //高度
background: #b50e03; //背景色
border-radius: 60rpx; //圆角
margin: 10px auto; //外边距 左右10 上下自动
line-height: 120rpx; // 上下居中
color: #fff; //字体颜色
font-size: 50rpx; //图标大小
}
.icon-tupian {
font-size: 45rpx;
}
text {
font-size: 30rpx; //设置文字大小
}
}
}
}
</style>
导航页跳转
通过通用方法完成跳转
// 导航点击的处理函数
navItemClick(url) {
uni.navigateTo({
url
})
}
六、实现推荐商品列表
1.推荐商品横幅

VUE代码
<!-- 推荐商品区 -->
<view class="hot_goods">
<view class="tit">推荐商品</view>
</view>
scss样式
<style lang="scss">
.home {
.hot_goods {
background: #eee; //设置背景色
overflow: hidden; //不影响父元素
margin-top: 10px;
.tit {
height: 50px; // 高度
line-height: 50px; // 垂直居中
color: $shop-color; //字体颜色
text-align: center; //文字居中
letter-spacing: 20px; //字间距
background: #fff; //背景颜色
margin: 7rpx 0;
}
}
}
</styl
2.推荐商品列表
for循环方式

获取商品列表
接口地址:/api/getgoods?pageindex=number
请求方式:GET
参数:pageindex: 页码;传递方式:/api/getgoods?pageindex=1
数据格式:
{
"status":0,
"message":[
{
"id":87,"title":"华为(HUAWEI)荣耀6Plus 16G双4G版",
"add_time":"2015-04-19T16:51:03.000Z",
"zhaiyao":"荣耀6 Plus,该机型分为两款型号,分别为PE-",
"click":0,
"img_url":"http://demo.dtcms.net/upload/201504/20/thumb_201504200046589514.jpg",
"sell_price":2195,
"market_price":2499,
"stock_quantity":60
}
]
}
VUE
<!-- 推荐商品区 -->
<view class="hot_goods">
<view class="tit">推荐商品</view>
<!-- 商品列表 -->
<view class="goods_list">
<view class="goods_item" v-for="item in goods" :key="item.id">
<image :src="item.img_url"></image>
<view class="price">
<text>¥{{item.sell_price}}</text>
<text>¥{{item.market_price}}</text>
</view>
<view class="name">
{{item.title}}
</view>
</view>
</view>
</view>
JS
<script>
export default {
data() {
return {
goods: [],
}
},
onLoad() {
this.getHotGoods()
},
methods: {
// 获取热门商品列表数据
async getHotGoods() {
const res = await this.$myRequest({
url: '/api/getgoods?pageindex=1'
})
this.goods = res.data.message
}
}
}
</script>
scss样式
<style lang="scss">
.home {
.hot_goods {
background: #eee; //设置背景色
overflow: hidden;
margin-top: 10px;
.tit {
height: 50px; // 高度
line-height: 50px; // 垂直居中
color: $shop-color; //字体颜色
text-align: center; //文字居中
letter-spacing: 20px;
background: #fff; //背景颜色
margin: 7rpx 0;
}
.goods_list {
padding: 0 15rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.goods_item {
background: #fff;
width: 355rpx;
margin: 10rpx 0;
padding: 15rpx;
box-sizing: border-box;
image {
width: 80%;
height: 150px;
display: block;
margin: auto;
}
.price {
color: $shop-color;
font-size: 36rpx;
margin: 20rpx 0 5rpx 0;
text:nth-child(2) {
color: #ccc;
font-size: 28rpx;
margin-left: 17rpx;
text-decoration: line-through;
}
}
.name {
font-size: 28rpx;
line-height: 50rpx;
padding-bottom: 15rpx;
padding-top: 10rpx;
}
}
}
}
}
</style>
七、完成商品列表
1.封装商品列表并使用
商品组件封装
<template>
<!-- 商品列表 -->
<view class="goods_list">
<view class="goods_item" v-for="item in goods" :key="item.id">
<image :src="item.img_url"></image>
<view class="price">
<text>¥{{item.sell_price}}</text>
<text>¥{{item.market_price}}</text>
</view>
<view class="name">
{{item.title}}
</view>
</view>
</view>
</template>
<script>
export default {
props: ['goods'], // 接收父组件传值
name: "goods-list",
data() {
return {
};
}
}
</script>
<style lang="scss">
.goods_list {
padding: 0 15rpx;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.goods_item {
background: #fff;
width: 355rpx;
margin: 10rpx 0;
padding: 15rpx;
box-sizing: border-box;
image {
width: 80%;
height: 150px;
display: block;
margin: auto;
}
.price {
color: $shop-color;
font-size: 36rpx;
margin: 20rpx 0 5rpx 0;
text:nth-child(2) {
color: #ccc;
font-size: 28rpx;
margin-left: 17rpx;
text-decoration: line-through;
}
}
.name {
font-size: 28rpx;
line-height: 50rpx;
padding-bottom: 15rpx;
padding-top: 10rpx;
}
}
}
</style>
使用组件示例

<template>
<view>
<goods-list :goods="goods"></goods-list>
</view>
</template>
<script>
import goodsList from "../../components/goods-list/goods-list.vue"//1.导入
export default {
data() {
return {
goods: [],
pageIndex: 1
}
},
onLoad() {
this.getHotGoods();
},
methods: {
// 获取热门商品列表数据
async getHotGoods() {
const res = await this.$myRequest({
url: '/api/getgoods?pageindex=' + this.pageIndex
})
this.goods = res.data.message
}
},
components: {
"goods-list": goodsList //2.注册
}
}
</script>
2.实现上下拉加载刷新

触底刷新代码
<template>
<view class="goods_list">
<goods-list :goods="goods"></goods-list>
<view class="isOver" :v-if="flag">-----我是有底线的-----</view>
</view>
</template>
<script>
import goodsList from "../../components/goods-list/goods-list.vue"
export default {
data() {
return {
goods: [],
pageIndex: 1,
flag: false // 如果数据到底则为true
}
},
onLoad() {
this.getHotGoods();
},
methods: {
// 获取热门商品列表数据
async getHotGoods(callBack) {
const res = await this.$myRequest({
url: '/api/getgoods?pageindex=' + this.pageIndex
})
this.goods = [...this.goods, ...res.data.message]
callBack && callBack(); //如果是下拉刷新则调用这个callBack,如果不是(也就是没有)不调用
}
},
components: {
"goods-list": goodsList
},
// 触底刷新
onReachBottom() {
if (this.goods.length < this.pageindex * 10) return this.flag = true // 判断没有下一页数据的时候停止发送请求
console.log("触底刷新")
this.pageIndex++;
this.getHotGoods();
},
//下拉刷新
onPullDownRefresh() {
this.flag = false;
this.pageIndex = 1;
this.goods = [];
setTimeout(() => { //动画效果延迟1秒
this.getHotGoods(() => {
uni.stopPullDownRefresh() //关闭动画
});
}, 1000)
}
}
</script>
<style lang="scss">
.goods_list {
background: #eee;
.isOver {
width: 100%;
height: 80px;
line-height: 50px;
text-align: center;
font-size: 28rpx;
}
}
</style>
3.联系我们页

代码
map文档:map | uni-app官网 (dcloud.net.cn)
<template>
<view class="contact">
<image class="img" src="http://www.itcast.cn/2018czydz/images/gywmban.jpg"></image>
<view class="info">
<view @click="phone">联系电话:400-618-9090 ( 点击拨打 )</view>
<view>校区地址:浙江省杭州市下沙经济开发区4号大街187号盛泰时代山</view>
</view>
<map class="map" :longitude="longitude" :scale="scale" :latitude="latitude" :markers="markers"></map>
<!-- 地图控件
longitude :中心经度
latitude:中心纬度
scale:缩放级别,取值范围为3-20
-->
</view>
</template>
<script>
export default {
data() {
return {
longitude: 120.363172,//中心经度
latitude: 30.312212,//中心维度
scale: 13,//缩放级别
markers: [{// 标记点
longitude: 120.363172, //标记经度
latitude: 30.312212,//标记维度
iconPath: '../../static/hmlogo.png',//标记图标
width: 30,//图标宽度
height: 30//图标高度
}]
}
},
methods: {
phone() {
uni.makePhoneCall({//拨打电话内置方法
phoneNumber: '400-618-9090'
})
}
}
}
</script>
<style lang="scss">
.contact {
.img {
width: 750rpx;
height: 320rpx;
}
.info {
padding: 10rpx 20rpx;
font-size: 30rpx;
view {
line-height: 80rpx;
border-bottom: 1px solid #eee;
}
}
.map {
width: 750rpx;
height: 750rpx;
}
}
</style>
4.社区图片页面

scroll-view scroll-view | uni-app官网 (dcloud.net.cn)
可滚动视图区域。用于区域滚动。
需注意在webview渲染的页面中,区域滚动的性能不及页面滚动。
<template>
<view class="pics">
<scroll-view class="left" scroll-y> scroll-y 允许纵向滚动
<view @click="leftClickHandle(index,item.id)" :class="active===index?'active':''"
v-for="(item,index) in cates" :key="item.id">
{{item.title}}
</view>
</scroll-view>
<scroll-view class="right" scroll-y>
<view class="item" v-for="item in secondData" :key="item.id">
<image @click="previewImg(item.img_url)" :src="item.img_url"></image>
<text>{{item.title}}</text>
</view>
<text v-if="secondData.length === 0">暂无数据</text>
</scroll-view>
</view>
</template>
<script>
export default {
//如何做高亮显示active == 当前选中分类的索引时 表达式 :class="active===index?'active':''
data() {
return {
cates: [],
active: 0,
secondData: []
}
},
methods: {
//获取分类数据
async getPicsCate() {
const res = await this.$myRequest({
url: '/api/getimgcategory'
})
this.cates = res.data.message
this.leftClickHandle(0, this.cates[0].id)//根据一级分类的初始ID获取了二级分类
},
//获取右侧图片数据
async leftClickHandle(index, id) {
this.active = index //高亮左侧使用的
// 获取右侧的数据
const res = await this.$myRequest({
url: '/api/getimages/' + id
})
this.secondData = res.data.message
},
previewImg(current) {//预览图片
const urls = this.secondData.map(item => {//连续预览图片
return item.img_url
})
uni.previewImage({
current,//点击的当前图片
urls
})
}
},
onLoad() {
this.getPicsCate()
}
}
</script>
<style lang="scss">
page {
height: 100%;
}
.pics {
height: 100%;
display: flex;
.left {
width: 200rpx;
height: 100%;
border-right: 1px solid #eee;
view {
height: 60px;
line-height: 60px;
color: #333;
text-align: center;
font-size: 30rpx;
border-top: 1px solid #eee;
}
.active {//选中的样式
background: $shop-color;
color: #fff;
}
}
.right {
height: 100%;
width: 520rpx;
margin: 10rpx auto;
.item {
image {
width: 520rpx;
height: 520rpx;
border-radius: 5px;
}
text {
font-size: 30rpx;
line-height: 60rpx;
}
}
}
}
</style>
获取图片分类
接口地址: /api/getimgcategory
请求方式:GET
参数:无
数据格式:
{
"status":0,
"message":[
{"title":"家居生活","id":14},
{"title":"摄影设计","id":15},
{"title":"明星美女","id":16},
{"title":"空间设计","id":17},
{"title":"古典美女","id":24}
]
}
二级图片列表
接口地址:/api/getimages/:cateid
请求方式:GET
参数:cateid: 图片的类别id,传入url写法: /api/getimages/23
数据格式:
{
"status":0,
"message":[
{
"id":40,
"title":"欧式风格继承了巴洛克风格中豪华、动感、多变的视觉效果",
"img_url":"http://demo.dtcms.net/upload/201504/18/thumb_201504181246376332.jpg",
"zhaiyao":"继上编欧式客厅装修效果图之后,今天,小编为大家带来的是一组不同类型的欧式卧室装修效果图。欧式卧室的设计风格按不同的地域文化可分为北欧卧室、简欧卧室和传统欧式卧室。在中国,因为欧式风格继承了巴洛克风格中豪华、动感、多变的视觉效果,也吸取了洛可可风格中唯美、律…"},
]
}
5.咨询列表页面

组件
<template>
<view>
<view class="news_item" @click="navigator(item.id)" v-for="item in list" :key="item.id">
<image :src="item.img_url"></image>
<view class="right">
<view class="tit">
{{item.title}}
</view>
<view class="info">
<text>发表时间:{{item.add_time | formatDate}}</text>
<text>浏览:{{item.click}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: ['list'],
filters: { //过滤器
formatDate (date) {//过滤时间处理
const nDate = new Date(date)//创建事件对象
const year = nDate.getFullYear()//年
const month = nDate.getMonth().toString().padStart(2,0)//月
const day = nDate.getDay().toString().padStart(2,0)//日
return year+'-'+month+'-'+day//中间要加上‘-’否则会变成数值相加
}
},
methods:{
navigator (id) {//跳转详情页,调用父组件的方法
this.$emit('itemClick',id)
}
}
}
</script>
<style lang="scss">
.news_item{
display: flex;
padding: 10rpx 20rpx;
border-bottom: 1px solid $shop-color;
image{
min-width: 200rpx; //最小宽度和·最大宽度都是一样的,必须是200
max-width: 200rpx;
height: 150rpx;
}
.right{
margin-left: 15rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.tit{
font-size: 30rpx;
}
.info{
font-size: 24rpx;
text:nth-child(2){//表示第二个text
margin-left: 30rpx;
}
}
}
}
</style>
引用组件代码
<template>
<view class="news">
<news-item @itemClick="goDetail" :list="newsList"></news-item>
</view>
</template>
<script>
import newsItem from '../../components/news-item/news-item.vue'
export default {
data() {
return {
newsList: []
}
},
methods: {
async getNews() {
const res = await this.$myRequest({
url: '/api/getnewslist'
})
this.newsList = res.data.message
},
goDetail(id) {//跳转到详情页,并传咨询ID(由组件调用)
uni.navigateTo({
url: '/pages/news-detail/news-detail?id=' + id
})
}
},
components: {
"news-item": newsItem
},
onLoad() {
this.getNews()
}
}
</script>
<style lang="scss">
.news {}
</style>
资讯列表
接口地址:/api/getnewslist
请求方式:GET
参数:无
数据格式:
{
"status":0,
"message":[
{"id":13,
"title":"1季度多家房企利润跌幅超50% 去库存促销战打响",
"add_time":"2015-04-16T03:50:28.000Z",
"zhaiyao":"房企一季度销售业绩已经陆续公布,克而瑞研究中心统计",
"click":1,
"img_url":"http://demo.dtcms.net/upload/201504/16/201504161149414479.jpg"
}
]
}
6.咨询详情页面

全局的时间过滤器
main.js
// 定义一个全局的时间过滤器
Vue.filter('formatDate', (date) => {
const nDate = new Date(date)
const year = nDate.getFullYear()
const month = nDate.getMonth().toString().padStart(2, 0)
const day = nDate.getDay().toString().padStart(2, 0)
return year + '-' + month + '-' + day
})
vue代码
rich-text 富文本。rich-text | uni-app官网 (dcloud.net.cn)
支持默认事件,包括:click、touchstart、touchmove、touchcancel、touchend、longpress。
<template>
<view class="news_detail">
<text class="title">{{detail.title}}</text>
<view class="info">
<text>发表时间:{{detail.add_time | formatDate}}</text> <-- formatDate 全局时间过滤器-->
<text>浏览:{{detail.click}}</text>
</view>
<view class="content">
<rich-text :nodes="detail.content"></rich-text> 富文本。
</view>
</view>
</template>
<script>
export default {
data() {
return {
id: 0,
detail: {}
}
},
methods: {
async getNewsDetail() {
const res = await this.$myRequest({
url: '/api/getnew/' + this.id
})
console.log(res)
this.detail = res.data.message[0]
}
},
onLoad(options) {
this.id = options.id //拿到组件给的参数
console.log(this.id)
this.getNewsDetail()
}
}
</script>
<style lang="scss">
.news_detail {
font-size: 30rpx;
padding: 0 20rpx;
.title {
text-align: center;
width: 710rpx;
display: block;
margin: 20rpx 0;
}
.info {
display: flex;
justify-content: space-between;
}
}
</style>
接口地址:/api/getnew/:newid
请求方式:GET
参数:newid:资讯id,传入url写法: /api/getnew/43
数据格式:
{
"status":0,
"message":[
{"id":13,
"title":"1季度多家房企利润跌幅超50% 去库存促销战打响",
"click":1,
"add_time":"2015-04-16T03:50:28.000Z",
"content":"<p>\r\n\t房企一季度销售业绩已经陆续公布,克而瑞研究中心统计数据显示,今年一季度,TOP20的房企仅6家实现业绩同比增长。\r\n</p>\r\n<p>\r\n\t<b>多家企业销售下滑</b> \r\n</p>\r\n<p>\r\n\t记者了解到,虽然恒大、融创一季度交出了不错的答卷,但是,万科等排名靠前的房企均出现销售下滑。其中万科公布前三个月销售金额为460.6亿元,同比去年的542.3亿元减少15%,而碧桂园公布,截至2015年3月31日止三个月,集团共实现合同销售金额约177.3 恒大地产2014年全年销售额达1315亿元,2015年销售目标定为1500亿元,较2014年目标增36.4%\r\n</p>"
}
]
}
八、实现商品详情页面

商品组件代码
<template>
<view class="goods_list">
<view class="goods_item" v-for="item in goods" :key="item.id" @click="navigator(item.id)">
<image :src="item.img_url"></image> /* @click="navigator(item.id)" 触发新增的方法*/
<view class="price">
<text>¥{{item.sell_price}}</text>
<text>¥{{item.market_price}}</text>
</view>
<view class="name">
{{item.title}}
</view>
</view>
</view>
</template>
<script>
export default {
props: ['goods'],
methods: {
navigator (id) { // 新增方法,调用父组件的跳转方法
this.$emit('goodsItemClick',id)
}
}
}
</script>
父组件-主页
<template>
<view class="home">
<!-- 推荐商品 -->
<view class="hot_goods">
<view class="tit">推荐商品</view>
<goods-list @goodsItemClick="goGoodsDetail" :goods="goods"></goods-list>
/* @goodsItemClick="goGoodsDetail" 注册方法 新增的导航到商品详情页*/
</view>
</view>
</template>
<script>
import goodsList from '../../components/goods-list/goods-list.vue'
export default {
data() {
return {
},
components: {
"goods-list": goodsList
},
methods: {
// 导航点击的处理函数
navItemClick(url) {
uni.navigateTo({
url
})
},
// 新增的导航到商品详情页
goGoodsDetail(id) {
uni.navigateTo({
url: '/pages/goods-detail/goods-detail?id=' + id
})
}
}
}
</script>
详情页代码完整
uni-goods-nav uni-app官网 (dcloud.net.cn)
<template>
<view class="goods_detail">
<swiper indicator-dots> /*商品详情页的轮播图*/
<swiper-item v-for="(item,index) in swipers" :key="index">
<image :src="item.src"></image>
</swiper-item>
</swiper>
<view class="box1">
<view class="price">
<text>¥{{info.sell_price}}</text>
<text>¥{{info.market_price}}</text>
</view>
<view class="goods_name">{{info.title}}</view>
</view>
<view class="line"></view>
<view class="box2">
<view>货号:{{info.goods_no}}</view>
<view>库存:{{info.stock_quantity}}</view>
</view>
<view class="line"></view>
<view class="box3">
<view class="tit">详情介绍</view>
<view class="content">
<rich-text :nodes="content"></rich-text>
</view>
</view>
<view class="goods_nav">
<uni-goods-nav :fill="true" :options="options" :button-group="buttonGroup" @click="onClick"
@buttonClick="buttonClick"></uni-goods-nav>
</view>
</view>
</template>
<script>
import uniGoodsNav from '@/components/uni-goods-nav/uni-goods-nav.vue'
export default {
data() {
return {
id: 0,
swipers: [],
info: {},
content: '',
options: [{
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/uni-ui/goodsnav/kefu.png',
text: '客服'
}, {
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/uni-ui/goodsnav/dianpu.png',
text: '店铺'
}, {
icon: 'https://img-cdn-qiniu.dcloud.net.cn/uniapp/uni-ui/goodsnav/carts.png',
text: '购物车',
info: 12
}, ],
buttonGroup: [{
text: '加入购物车',
backgroundColor: '#ff0000',
color: '#fff'
},
{
text: '立即购买',
backgroundColor: '#ffa200',
color: '#fff'
}
]
}
},
methods: {
async getSwipers() {
const res = await this.$myRequest({
url: '/api/getthumimages/' + this.id
})
this.swipers = res.data.message
},
async getDetailInfo() {
const res = await this.$myRequest({
url: '/api/goods/getinfo/' + this.id
})
this.info = res.data.message[0]
},
async getDetailContent() {
const res = await this.$myRequest({
url: '/api/goods/getdesc/' + this.id
})
this.content = res.data.message[0].content
},
onClick(e) {
// uni.showToast({
// title: `点击${e.content.text}`,
// icon: 'none'
// })
console.log(e)
},
buttonClick(e) {
console.log(e)
// this.options[2].info++
}
},
onLoad(options) {
this.id = options.id
this.getSwipers()
this.getDetailInfo()
this.getDetailContent()
},
components: {
uniGoodsNav
}
}
</script>
<style lang="scss">
.goods_detail {
swiper {
height: 700rpx;
image {
width: 100%;
height: 100%;
}
}
.box1 {
padding: 10px;
.price {
font-size: 35rpx;
color: $shop-color;
line-height: 80rpx;
text:nth-child(2) {
color: #ccc;
font-size: 28rpx;
text-decoration: line-through;
margin-left: 20rpx;
}
}
.goods_name {
font-size: 32rpx;
line-height: 60rpx;
}
}
.box2 {
padding: 0 10px;
font-size: 32rpx;
line-height: 70rpx;
}
.box3 {
padding-bottom: 50px;
.tit {
font-size: 32rpx;
padding-left: 10px;
border-bottom: 1px solid #eee;
line-height: 70rpx;
}
.content {
padding: 10px;
font-size: 28rpx;
color: #333;
line-height: 50rpx;
}
}
}
.goods_nav {
position: fixed;
bottom: 0;
width: 100%;
}
.line {
height: 10rpx;
width: 750rpx;
background: #eee;
}
</style>
详情轮播图
接口地址: /api/getthumimages/:imgid
请求方式:GET
参数: imgid: 图片id,传入url写法:/api/getthumimages/43
数据格式:
{"status":0,
"message":[
{"src":"http://demo.dtcms.net/upload/201504/20/thumb_201504200059017695.jpg"},
{"src":"http://demo.dtcms.net/upload/201504/20/thumb_201504200059022920.jpg"}
]
}
获取详情参数
接口地址: /api/goods/getinfo/:id
请求方式:GET
参数:Id:商品主键值 /api/goods/getinfo/100
数据格式:
{
"status":0,
"message":[
{
"id":87,
"title":"华为(HUAWEI)荣耀6Plus 16G双4G版",
"add_time":"2015-04-19T16:51:03.000Z",
"goods_no":"SD9102356032",
"stock_quantity":60,
"market_price":2499,
"sell_price":2195
}
]
}
获取详细介绍
接口地址: /api/goods/getdesc/:id
请求方式:GET
参数:Id:商品数据的id Url : /api/goods/getdesc/87
数据格式:
{
"status":0,
"message":[
{
"title":"华为(HUAWEI)荣耀6Plus 16G双4G版",
"content":"<p>\r\n\t荣耀6 Plus,该机型分为两款型号,分别为PE-TL10和PE-UL00的新机型,并且根据工信部设备认证中心公布的信息显示,移动版本PE-TL20和PE-TL00M也已经拿到了入网许可证,拥有7.5mm的纤薄机身,支持TDD-LTE/TD-SCDMA/GSM网络。双800万后置摄像头+800万前置摄像头。采用5.5英寸1080p分辨率显示屏,搭载1.8GHz麒麟925八核处理器,内置3GB RAM+32GB ROM存储组合,支持存储卡扩展。\r\n</p>\r\n<p align=\"center\">\r\n\t<span style=\"color:#FF0000;font-size:16px;\"><img class=\"gomeImgLoad\" alt=\"\" src=\"http://img5.gomein.net.cn/image/bbcimg/productDesc/descImg/201503/desc04/A0004794664/3997361.jpg\" /></span> \r\n</p>"
}
]
}
uniapp定位和选择城市_u-index-anchor-CSDN博客
九、打包
1.H5打包
配置:

- 页面标题
- 路由模式
发行


2.安卓打包

原声app云打包

