购物车项目
实现语言:css、html、javascript
实现框架:vue3
使用插件:vue-cil4、vue-router、vue-axios
相关组件:swiper、better-scroll
实现功能:
1.商品内容分块展示
2.商品详细信息展示
3.商品点击添加购物车
4.页面轮播图
5.页面滚动效果
6.页面吸顶效果
7.页面返回顶部功能
8.上拉加载功能
9.点击跳转功能
vue.config.js
module.exports = {
configureWebpack: {
resolve: {
alias: {
'assets': '@/assets',
'common': '@/common',
'components': '@/components',
'network': '@/network',
'views': '@/views',
}
}
}
}
相关素材样式:
main.js:
创建组件,挂载组件(only创建项目)
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
Vue.prototype.$bus = new Vue()
new Vue({
render: h => h(App),
router,
store
}).$mount('#app')
App.vue:组件管理,通过MainTabBar搭建项目框架
keep-alive:自带插件,保持状态
router-view:
router-link:
<template>
<div id="app" class="wrapper">
<keep-alive exclude="Detail"><router-view/></keep-alive>
<main-tab-bar/>
</div>
</template>
<script>
import MainTabBar from 'components/content/mainTabbar/MainTabBar'
export default {
name: 'app',
components: {
MainTabBar
}
}
</script>
<style>
@import "assets/css/base.css";
</style>
MainTabBar.vue:搭建项目框架,添加跳转路径
<template>
<tab-bar>
<tab-bar-item path="/home">
<img slot="item-icon" src="~assets/img/tabbar/home.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/home_active.svg" alt="">
<div slot="item-text">首页</div>
</tab-bar-item>
<tab-bar-item path="/category">
<img slot="item-icon" src="~assets/img/tabbar/category.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/category_active.svg" alt="">
<div slot="item-text">分类</div>
</tab-bar-item>
<tab-bar-item path="/cart">
<img slot="item-icon" src="~assets/img/tabbar/shopcart.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/shopcart_active.svg" alt="">
<div slot="item-text">购物车</div>
</tab-bar-item>
<tab-bar-item path="/profile">
<img slot="item-icon" src="~assets/img/tabbar/profile.svg" alt="">
<img slot="item-icon-active" src="~assets/img/tabbar/profile_active.svg" alt="">
<div slot="item-text">我的</div>
</tab-bar-item>
</tab-bar>
</template>
<script>
import TabBar from 'components/common/tabbar/TabBar'
import TabBarItem from 'components/common/tabbar/TabBarItem'
export default {
name: "MainTabBar",
components: {
TabBar,
TabBarItem
}
}
</script>
router/index.js
配置路由:
1.路由懒加载:异步加载,用到时候再显示
2.路由传参:动态传参、query传参
3.路由模式:history
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = () =>
import ('../views/home/Home')
const Category = () =>
import ('../views/category/Category')
const Cart = () =>
import ('../views/cart/Cart')
const Profile = () =>
import ('../views/profile/Profile')
const Detail = () =>
import ('../views/detail/Detail')
// 1.安装插件
Vue.use(VueRouter)
// 2.创建router
const routes = [{
path: '',
redirect: '/home'
},
{
path: '/home',
component: Home
},
{
path: '/category',
component: Category
},
{
path: '/cart',
component: Cart
},
{
path: '/profile',
component: Profile
},
{
path: '/detail/:iid',
component: Detail
}
]
const router = new VueRouter({
routes,
mode: 'history'
})
export default router
home.vue:首页home组件,管理首页内容
首页内容:
1.nav导航栏
2.swiper轮播图
3.recommend
4.feature本周流行
5.tabcontrol商品类别
6.商品展示
7.maintabbar
<template>
<div id="home" class="wrapper">
<nav-bar class="home-nav"><div slot="center">购物街</div></nav-bar>
<tab-control :titles="['流行', '新款', '精选']"
@tabClick="tabClick"
ref="tabcontrol1"
class="tab-control" v-show="isFixed"/>
<scroll class="content"
ref="scroll"
:probe-type="3"
@scroll="contentScroll"
:pull-up-load="true"
@pullingUp="loadMore">
<home-swiper :banners="banners" @swiperImageLoad="swiperImageLoad" ref="hswiper"/>
<recommend-view :recommends="recommends"/>
<feature-view/>
<tab-control :titles="['流行', '新款', '精选']"
@tabClick="tabClick"
ref="tabcontrol2"/>
<good-list :goods="showGoods"/>
</scroll>
<div>呵呵呵呵</div>
<back-top @click.native="backClick" v-show="isShowBackTop"/>
</div>
</template>
<script>
import HomeSwiper from './childComps/HomeSwiper'
import RecommendView from './childComps/RecommendView'
import FeatureView from './childComps/FeatureView'
import NavBar from 'components/common/navbar/NavBar'
import TabControl from 'components/content/tabControl/TabControl'
import GoodList from 'components/content/goods/GoodsList'
import Scroll from 'components/common/scroll/Scroll'
import BackTop from 'components/content/backTop/BackTop'
import { getHomeMultidata, getHomeGoods } from "network/home"
import {itemListenerMixin} from 'common/mixin'
export default {
name: "Home",
components: {
HomeSwiper,
RecommendView,
FeatureView,
NavBar,
TabControl,
GoodList,
Scroll,
BackTop
},
mixins:[itemListenerMixin],
data() {
return {
banners: [],
recommends: [],
goods: {
'pop': {page: 0, list: []},
'new': {page: 0, list: []},
'sell': {page: 0, list: []},
},
currentType: 'pop',
isShowBackTop: false,
offsetTop: 0,
isFixed: false,
}
},
computed: {
showGoods() {
return this.goods[this.currentType].list
}
},
created() {
// 1.请求多个数据
this.getHomeMultidata()
// 2.请求商品数据
this.getHomeGoods('pop')
this.getHomeGoods('new')
this.getHomeGoods('sell')
},
mounted() {
},
methods: {
/**
* 事件监听相关的方法
*/
tabClick(index) {
switch (index) {
case 0:
this.currentType = 'pop'
break
case 1:
this.currentType = 'new'
break
case 2:
this.currentType = 'sell'
break
}
//两个tabcontrol
this.$refs.tabcontrol1.currentIndex = index;
this.$refs.tabcontrol2.currentIndex = index;
},
backClick() {
this.$refs.scroll.scrollTo(0, 0)
},
contentScroll(position) {
// console.log(this.$refs.tabcontrol.$el.offsetTop);
this.isShowBackTop = (-position.y) > 1000
this.isFixed = (-position.y) > this.offsetTop
// console.log(this.isFixed);
},
loadMore() {
this.getHomeGoods(this.currentType)
},
/**
* 网络请求相关的方法
*/
swiperImageLoad(){
// 获取组件里元素的offsetTop
this.offsetTop=this.$refs.tabcontrol2.$el.offsetTop
},
getHomeMultidata() {
getHomeMultidata().then(res => {
// this.result = res;
this.banners = res.data.banner.list;
this.recommends = res.data.recommend.list;
console.log(res);
})
},
getHomeGoods(type) {
const page = this.goods[type].page + 1
getHomeGoods(type, page).then(res => {
this.goods[type].list.push(...res.data.list)
this.goods[type].page += 1
this.$refs.scroll.finishPullUp()
// this.$refs.scroll.refresh()
console.log(res);
})
}
}
}
</script>
NavBar.vue:
1.插槽slot可以对应填充内容
<template>
<div class="nav-bar">
<div class="left"><slot name="left"></slot></div>
<div class="center"><slot name="center"></slot></div>
<div class="right"><slot name="right"></slot></div>
</div>
</template>
<script>
export default {
name: 'NavBar',
}
</script>
Recommend.vue:
1.父组件请求数据,然后传给子组件显示
2.子组件根据数据生成相应内容
<template>
<div class="recommend">
<div v-for="item in recommends" class="recommend-item">
<a :href="item.link">
<img :src="item.image" alt="">
<div>{{item.title}}</div>
</a>
</div>
</div>
</template>
<script>
export default {
name: "RecommendView",
props: {
recommends: {
type: Array,
default() {
return []
}
}
}
}
</script>
Feature.vue:
仅仅是一张图片套了一个a标签
<template>
<div class="feature">
<a href="https://act.mogujie.com/zzlx67">
<img src="~assets/img/home/recommend_bg.jpg" alt="">
</a>
</div>
</template>
<script>
export default {
name: "FeatureView"
}
</script>
TabControl.vue:
1.实现局部的商品刷新
2.点击对应类别传递不同商品参数
3.
<template>
<div class="tab-control">
<div v-for="(item, index) in titles"
class="tab-control-item"
:class="{active: index === currentIndex}"
@click="itemClick(index)">
<span>{{item}}</span>
</div>
</div>
</template>
<script>
export default {
name: "TabControl",
props: {
titles: {
type: Array,
default() {
return []
}
}
},
data() {
return {
currentIndex: 0
}
},
methods: {
itemClick(index) {
this.currentIndex = index;
this.$emit('tabClick', index)
}
}
}
</script>
request.js:
1.使用axios插件请求数据
import axios from 'axios'
export function request(config) {
// 1.创建axios的实例
const instance = axios.create({
baseURL: 'http://152.136.185.210:7878/api/m5',
timeout: 5000
})
// 2.axios的拦截器
// 2.1.请求拦截的作用
instance.interceptors.request.use(config => {
return config
}, err => {
// console.log(err);
})
// 2.2.响应拦截
instance.interceptors.response.use(res => {
return res.data
}, err => {
console.log(err);
})
// 3.发送真正的网络请求
return instance(config)
}
home.js:
1.home首页的数据请求
import { request } from "./request";
export function getHomeMultidata() {
return request({
url: '/home/multidata'
})
}
export function getHomeGoods(type, page) {
return request({
url: '/home/data',
params: {
type,
page
}
})
}
利用封装好的swiper、better-scroll、back-top渲染页面功能