E商城(移动App)项目实施
一、创建项目
1.安装 vue-cli
$ npm install -g @vue/cli
2.创建项目
$ vue create e-mall
第一步:
第二步:
第三步:
第四步:
第五步:
第六步:
第七步:
项目创建成功:
二、安装使用 Vant UI
1.安装 Vant UI
$ npm i vant@latest-v2 -S
2.引入使用Vant UI
修改 main.js
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
三、修改 App.vue
修改 App.vue
<template>
<div id="app">
<router-view style="padding-bottom: 60px"/>
<van-tabbar active-color="#42b983" route>
<van-tabbar-item to="/" icon="home-o">首页</van-tabbar-item>
<van-tabbar-item to="/category" icon="apps-o">分类</van-tabbar-item>
<van-tabbar-item to="/cart" icon="shopping-cart-o">购物车</van-tabbar-item>
<van-tabbar-item to="/mine" icon="user-o">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
}
body {
margin: 0;
}
#app .van-nav-bar__title {
font-weight: bold;
color: #fff;
}
</style>
四、添加首页布局
修改 HomeView.vue
<template>
<div class="home">
<van-nav-bar title="E商城" border style="background-color: #42b983"/>
<van-sticky>
<van-search
v-model="search"
shape="round"
placeholder="请输入搜索关键词"
background="#42b983"
/>
</van-sticky>
<van-swipe class="my-swipe" height="200" :autoplay="3000">
<van-swipe-item v-for="(item, index) in banner" :key="index">
<img :src="item.url" :alt="item.content">
</van-swipe-item>
</van-swipe>
<van-grid :column-num="5">
<van-grid-item
v-for="(item, index) in channel"
:key="item.id"
:icon="item.iconUrl"
:text="item.name"
/>
<van-grid-item
icon="ellipsis"
text="更多"
/>
</van-grid>
<div>
<van-card
v-for="item in filterGoodsList"
:price="item.retailPrice.toFixed(2)"
:origin-price="item.counterPrice.toFixed(2)"
:desc="item.brief"
:title="item.name"
:thumb="item.picUrl"
@click="toDetailPage(item.id)"
>
<template #tags>
<van-tag plain type="danger" v-if="item.isHot">热销</van-tag>
<van-tag plain type="danger" v-if="item.isNew">新品</van-tag>
</template>
</van-card>
</div>
</div>
</template>
<script>
export default {
name: 'HomeView',
data() {
return {
search: '',
banner: [],
channel: [],
goodsList: [],
}
},
methods: {
toDetailPage(id) {
this.$router.push({
name: 'product',
params: {
id
}
})
}
}
}
</script>
<style>
.my-swipe img {
width: 100%;
height: 100%;
object-fit: cover;
}
.title {
padding: 10px 16px 0;
color: rgba(69, 90, 100, 0.6);
font-size: 14px;
}
</style>
五、添加首页API
1.启动 litemall-wx-api-0.1.0-exec
$ java -jar litemall-wx-api-0.1.0-exec.jar
2.安装 axios
$ npm i axios -S
3.修改 main.js
import axios from "axios";
Vue.prototype.$axios = axios
4.完善 HomeView.vue
<template>
<div class="home">
<van-nav-bar title="E商城" border style="background-color: #42b983"/>
<van-sticky>
<van-search
v-model="search"
shape="round"
placeholder="请输入搜索关键词"
background="#42b983"
/>
</van-sticky>
<van-swipe class="my-swipe" height="200" :autoplay="3000">
<van-swipe-item v-for="(item, index) in banner" :key="index">
<img :src="item.url" :alt="item.content">
</van-swipe-item>
</van-swipe>
<van-grid :column-num="5">
<van-grid-item
v-for="(item, index) in channel.slice(0, 9)"
:key="item.id"
:icon="item.iconUrl"
:text="item.name"
/>
<van-grid-item
icon="ellipsis"
text="更多"
/>
</van-grid>
<van-list
v-model="loading"
:finished="finished"
finished-text="我是有底线的"
@load="onLoad"
>
<van-card
v-for="item in filterGoodsList"
:price="item.retailPrice.toFixed(2)"
:origin-price="item.counterPrice.toFixed(2)"
:desc="item.brief"
:title="item.name"
:thumb="item.picUrl"
@click="toDetailPage(item.id)"
>
<template #tags>
<van-tag plain type="danger" v-if="item.isHot">热销</van-tag>
<van-tag plain type="danger" v-if="item.isNew">新品</van-tag>
</template>
</van-card>
</van-list>
<!-- <van-divider>我是有底线的</van-divider>-->
</div>
</template>
<script>
export default {
name: 'HomeView',
data() {
return {
search: '',
banner: [],
channel: [],
goodsList: [],
loading: false,
finished: false,
page: 1,
limit: 20
}
},
computed: {
filterGoodsList() {
return this.goodsList.filter(item => item.name.includes(this.search))
}
},
created() {
this.$axios({
url: 'http://localhost:8081/wx/home/index',
}).then(res => {
this.banner = res.data.data.banner
this.channel = res.data.data.channel
this.floorGoodsList = res.data.data.floorGoodsList
})
this.loading = true
this.$axios({
url: 'http://localhost:8081/wx/goods/list',
}).then(res => {
this.goodsList = res.data.data.list
console.log(res.data.data)
}).finally(() => {
this.loading = false
})
},
methods: {
onLoad() {
this.page++
this.$axios({
url: `http://localhost:8081/wx/goods/list?page=${this.page}&limit=${this.limit}`,
}).then(res => {
this.goodsList = [...this.goodsList, ...res.data.data.list]
console.log(res.data.data)
if (res.data.data.list.length < this.limit) {
this.finished = true
}
}).finally(() => {
this.loading = false
})
},
toDetailPage(id) {
this.$router.push({
name: 'product',
params: {
id
}
})
}
}
}
</script>
<style>
.my-swipe img {
width: 100%;
height: 100%;
object-fit: cover;
}
.title {
padding: 10px 16px 0;
color: rgba(69, 90, 100, 0.6);
font-size: 14px;
}
</style>
六、商品详情页实施
1.views/
文件夹创建 ProductView.vue
<template>
<div>
<van-nav-bar title="E商城" border style="background-color: #42b983"/>
<van-swipe
class="my-swipe"
height="300"
:autoplay="3000"
indicator-color="#42b983"
>
<van-swipe-item v-for="(image, index) in productInfo.gallery" :key="index">
<img :src="image" alt="">
</van-swipe-item>
</van-swipe>
<div class="info">
<div class="price">
<span>价格:<b></b></span>
<span>原价:<del></del></span>
</div>
<div class="name"></div>
<div class="desc"></div>
</div>
<div class="detail" v-html="productInfo.detail"></div>
<van-goods-action style="bottom: 50px">
<van-goods-action-icon icon="chat-o" text="客服" />
<van-goods-action-icon icon="cart-o" text="购物车" />
<van-goods-action-icon icon="shop-o" text="店铺" />
<van-goods-action-button type="warning" text="加入购物车" />
<van-goods-action-button type="danger" text="立即购买" />
</van-goods-action>
</div>
</template>
<script>
export default {
name: "ProductView",
data() {
return {
productInfo: {},
product: {},
}
},
created() {
const { id } = this.$route.params
this.$axios({
url: 'http://localhost:8081/wx/goods/detail?id='+id
}).then(res => {
console.log(res.data.data)
console.log(res.data.data.info)
this.productInfo = res.data.data.info
this.product = res.data.data
})
},
methods: {
onClickButton() {
}
}
}
</script>
<style lang="less">
.my-swipe img {
height: 100%;
width: 100%;
object-fit: cover;
}
.info {
.price {
background: #ea5b5b;
display: flex;
align-items: flex-end;
color: #ffd01e;
padding: 15px;
font-size: 22px;
span:last-child {
margin-left: 10px;
font-size: 14px;
color: #fff;
}
}
.name {
padding: 10px 10px 0;
font-size: 18px;
}
.desc {
padding: 0 10px 10px;
font-size: 14px;
color: gray;
}
}
.detail {
p {
margin: 0;
}
img {
display: block;
width: 100%;
}
}
</style>
2.添加路由访问
{
path: '/product/:id',
name: 'product',
component: () => import('../views/ProductView')
},
七、商品分类页实施
1.views/
文件夹创建 CategoryView.vue
<template>
<div>
<van-nav-bar title="E商城 | 分类" border style="background-color: #42b983"/>
<van-tree-select
:items="categories"
:main-active-index="mainActiveIndex"
@click-nav="clickNav"
@click-item="clickItem"
/>
</div>
</template>
<script>
export default {
name: "CategoryView",
data: () => ({
mainActiveIndex: 0,
categories: []
}),
created() {
this.$axios({
url: 'http://localhost:8081/wx/catalog/index'
}).then(res => {
this.categories = res.data.data.categoryList.map(item => {
return {
text: item.name,
id: item.id
}
})
this.categories[0].children = res.data.data.currentSubCategory.map(item => {
return {
text: item.name,
id: item.id
}
})
})
},
methods: {
onSearch() {
console.log(this.search)
},
clickNav(index) {
if (!this.categories[index].children) {
const id = this.categories[index].id
this.$axios({
url: ' http://localhost:8081/wx/catalog/current?id='+id
}).then(res => {
this.categories[index].children = res.data.data.currentSubCategory.map(item => {
return {
text: item.name,
id: item.id,
}
})
this.mainActiveIndex = index
})
} else {
this.mainActiveIndex = index
}
},
clickItem(data) {
console.log(data)
}
}
}
</script>
<style>
.van-tree-select {
height: 100%!important;
}
</style>
2.添加路由访问
{
path: '/category',
name: 'category',
component: () => import('../views/CategoryView')
},