在vue脚手架环境利用vant组件简单实现移动端购物商城系统
程序员文章站
2022-04-21 20:13:44
...
用vue脚手架创建好项目,进行以下操作
①下载vant插件
在终端或cmd中运行
npm i vant -S
在main.js中全局配置vant
import Vant from 'vant';
import 'vant/lib/index.css';
Vue.use(Vant);
②下载安装axios
在终端或cmd中运行
npm install axios -S
在main.js中全局配置axios
import axios from 'axios'
Vue.prototype.$axios = axios
③在views中创建Carts.vue(购物车页面),Classify.vue(商品分类),Goodslist.vue(商品列表),Index.vue,Main.vue(首页),Myself.vue(我的),Search.vue(搜索页面)
④在router下的index.js配置路由
const routes = [
{
path: '/',
name: 'Index',
component: () => import( '../views/Index.vue'),
redirect:'/main',
children:[
{
path: '/main',
name: 'Main',
component: () => import( '../views/Main.vue')
},
{
path: '/classify',
name: 'Classify',
component: () => import( '../views/Classify.vue')
},
{
path: '/carts',
name: 'Carts',
component: () => import( '../views/Carts.vue')
},
{
path: '/myself',
name: 'Myself',
component: () => import( '../views/Myself.vue')
},
]
},
{
path: '/search',
name: 'Search',
component: () => import( '../views/Search.vue')
},
{
path: '/list',
name: 'Goodlist',
component: () => import( '../views/Goodlist.vue')
}
]
⑤App.vue
<template>
<div>
<router-view></router-view>
</div>
</template>
⑥Index.vue
<template>
<div>
<router-view></router-view>
<van-tabbar route active-color="#1989fa" >
<van-tabbar-item name="home" icon="home-o" to='/main'>首页</van-tabbar-item>
<van-tabbar-item name="home" icon="search" to="/classify" badge="2">分类</van-tabbar-item>
<van-tabbar-item name="home" icon="cart-o" to="/carts" :dot='true'>购物车</van-tabbar-item>
<van-tabbar-item name="home" icon="manager-o" to="/myself">我的</van-tabbar-item>
</van-tabbar>
</div>
</template>
<script>
export default {
data(){
return {
active:0
}
}
}
</script>
<style>
</style>
⑦Main.vue (首页)
<template>
<div>
<!-- 输入搜索框 -->
<van-search
v-model="value"
show-action
shape="round"
placeholder="请输入搜索关键词"
background="#E73A68"
@focus="searchFocus"
>
<template #label>
<span class="search-logo">JD</span>
</template>
<template #action>
<span style="color:#fff;font-size:16px;">登录</span>
</template>
<template #left>
<van-icon name="wap-nav" color="#fff" size="25px" style="margin-right:10px" />
</template>
</van-search>
<!-- 轮播广告 -->
<div>
<van-swipe :autoplay="3000" style="width:90%;margin:15px auto;border-radius:10px" indicator-color="red" >
<van-swipe-item v-for="url in images" :key="url">
<img :src="url" style="width:100%" />
</van-swipe-item>
</van-swipe>
</div>
<!-- 宫格 -->
<van-swipe :autoplay="3000" :loop="false" style="padding:10px 0">
<van-swipe-item>
<van-grid :column-num="5" :border="false">
<van-grid-item v-for="(item,index) in imgData" :key="index" :text="item.title" v-show="index < 10">
<template #icon>
<img :src="item.img" width="50px" />
</template>
</van-grid-item>
</van-grid>
</van-swipe-item>
<van-swipe-item>
<van-grid :column-num="5" :border="false">
<van-grid-item v-for="(item,index) in imgData" :key="index" :text="item.title" v-show="index >= 10 && index < 20">
<template #icon>
<img :src="item.img" width="50px" />
</template>
</van-grid-item>
</van-grid>
</van-swipe-item>
</van-swipe>
<!-- 商品卡片 -->
<div class="card-list">
<goodscard v-for="i in 4" :key="i" img='/images/wise.jpg' title="面膜" :price='80'></goodscard>
</div>
</div>
</template>
<script>
import Goodscard from '@/components/Goodscard.vue'
export default {
components:{
'goodscard' : Goodscard
},
data(){
return {
value:'',
images:[
'/images/01.jpg',
'/images/02.jpg',
'/images/03.jpg'
],
imgData:[
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'京东超市',
img:'/images/grid02.png'
},
{
title:'京东服饰',
img:'/images/grid03.png'
},
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'京东超市',
img:'/images/grid02.png'
},
{
title:'京东服饰',
img:'/images/grid03.png'
},
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'京东超市',
img:'/images/grid02.png'
},
{
title:'京东服饰',
img:'/images/grid03.png'
},
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'京东超市',
img:'/images/grid02.png'
},
{
title:'京东服饰',
img:'/images/grid03.png'
},
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'京东超市',
img:'/images/grid02.png'
},
{
title:'京东服饰',
img:'/images/grid03.png'
},
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'京东超市',
img:'/images/grid02.png'
},
{
title:'京东服饰',
img:'/images/grid03.png'
},
{
title:'京东数码',
img:'/images/grid01.png'
},
{
title:'全部',
img:'/images/grid02.png'
}
]
}
},
methods:{
searchFocus(){
this.$router.push({
path:'/search'
})
}
}
}
</script>
<style>
.search-logo{
color: #E93C3E;
font-weight: bold;
font-size: 20px;
}
.card-list{
width: 100%;
display: flex;
justify-content: space-around;
box-sizing: border-box;
flex-wrap: wrap;
margin-bottom: 60px;
}
</style>
⑧Search.vue(搜索页面)
<template>
<div>
<van-search
v-model="searchValue"
shape="round"
show-action
placeholder="请输入搜索关键词"
@search='onSearch'
>
<template #action>
<van-button type="primary" size="mini" color="#E93B3D" style="font-size:16px;border-radius:5px" @click="onSearch">搜索</van-button>
</template>
<template #left>
<van-icon name="arrow-left" size="20px" style="margin-right:10px" @click="pageBack"/>
</template>
</van-search>
<!-- 搜索记录 -->
<div class="search-history">
<div class="search-history-title">
<span>最近搜索</span>
<van-icon name="delete" size="20px" @click="clearHistory"/>
</div>
<div class="search-tag-list">
<van-tag type="large" color="#F0F2F5" class="search-tag" v-for="(item,index) in historyList" :key="index" @click="onSearch(item)">{{item}}</van-tag>
</div>
</div>
<!-- 智能搜索提示 -->
<div class="showList" v-show="showKwList" >
<van-cell v-for="kw in showTist" :key="kw" :title="kw" value='内容' @click="onSearch(kw)" />
</div>
</div>
</template>
<script>
export default {
data(){
return {
searchValue:'',
showTist:[],
showKwList:false,
historyList:[],
data: [
"html",
"css",
"javascript",
"jquery",
"node.js",
"vue.js",
"swiper",
"bootstrap",
"php",
"mongodb",
"mysql",
"react.js",
"github",
"glup",
"webpack",
"sass",
"echarts",
"vant"
]
}
},
created(){
let historylist = localStorage.historyList
if(historylist){
this.historyList = JSON.parse(historylist)
}
},
watch:{
searchValue(kw){
this.showKwList = kw.length > 0 ? true : false
this.showTist = this.data.filter(item=>{
return item.includes(kw)
})
}
},
methods:{
pageBack(){
window.history.back()
},
onSearch(kw){
let keyword = ''
if(typeof kw === 'string'){
keyword = kw
}else if(typeof kw === 'object'){
if(this.searchValue.trim() === '') return
keyword = this.searchValue
}
if(keyword){
//执行搜索功能
this.$router.push({
path:'/list',
query:{
kw : keyword
}
})
}
//query类似于get请求,params类似于post请求
//如果路由跳转使用path,必须使用query方式传参,如果使用name跳转,query和params可以
//使用query传参,参数可以保存,使用params传参,页面刷新后,参数不会保存
// this.$router.push({
// name:'/list',
// params:{
// kw : keyword
// }
// })
//保存搜索记录
if(keyword){
this.saveHistory(keyword)
}
},
saveHistory(keyword){
if(this.historyList.includes(keyword)){
let index = this.historyList.indexOf(keyword)
this.historyList.splice(index,1)
this.historyList.unshift(keyword)
}else{
this.historyList.unshift(keyword)
}
if(keyword){
//更新到本地
localStorage.historyList = JSON.stringify(this.historyList)
}
},
clearHistory(){
this.$dialog.confirm({
title: '',
message:'确定要清空吗',
closeOnClickOverlay:'true',
width:'360px',
className:'confiButton',
theme:'round'
})
.then(() => {
this.historyList = []
localStorage.historyList = JSON.stringify(this.historyList)
})
.catch(() => {
// on cancel
})
}
}
}
</script>
<style>
.search-history{
height: 50px;
width: 100%;
border-top: 1px solid #E5E5E5;
}
.search-history-title{
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 10px;
}
.search-tag-list{
padding-left: 15px;
padding-right: 15px;
}
.search-tag{
color: #686868;
margin-top: 10px;
margin-right: 10px;
}
.showList{
background: #fff;
position: absolute;
width: 100%;
top: 67px;
min-height: 150px;
}
.confiButton{
font-size: 22px;
}
</style>
⑨Classify.vue(分类页面)
<template>
<div>
<div class="navBox">
<ul class="firstNav">
<li v-for="(item) in nav" :key="item.cid" @click="clickNavOne(item)">
<img :src="item.cpic" alt="" srcset="" width="30px">
{{item.cname}}
</li>
</ul>
<ul class="secondNav">
<li v-for="(item) in secondData" :key="item.subcid" @click="toListPage">
<img :src="item.scpic" alt="" srcset="" width="50px">
{{item.subcname}}
</li>
</ul>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data(){
return {
nav:[],
secondData:[]
}
},
created(){
this.$axios.get('/data/goods.json').then((res)=>{
console.log(res.data.data.data)
this.nav = res.data.data.data
this.secondData = this.nav[0].subcategories
})
},
methods:{
clickNavOne(item){
this.secondData = item.subcategories
},
toListPage(){
this.$router.push({
path:'/list'
})
}
}
}
</script>
<style scoped>
.navBox{
display: flex;
}
.firstNav{
margin: 0 20px;
flex: 1.5;
margin-bottom: 50px;
overflow-y: scroll;
}
::-webkit-scrollbar{
display: none;
}
.secondNav{
flex: 3;
display: flex;
align-items: center;
flex-wrap: wrap;
margin-bottom: 50px;
height: 600px;
overflow-y: scroll;
margin-top: 10px;
}
::-webkit-scrollbar{
display: none;
}
.firstNav li{
display: flex;
flex-direction: column;
justify-content: center;
margin: 20px 10px;
}
.secondNav li{
display: flex;
flex-direction: column;
justify-content: center;
width: 50%;
}
</style>
⑩Goodlist.vue(商品列表页面)
<template>
<div>
<!-- 导航栏 -->
<van-nav-bar
:title="`购物车(${this.cartList.length})`"
left-text="返回"
right-text="购物车"
left-arrow
fixed
@click-left="onClickLeft"
@click-right="onClickRight"
style="height:50px;font-size:26px"
>
</van-nav-bar>
<div class="goods-card-box">
<!-- 商品列表 -->
<goods-card v-for="(item) in goods"
:key="item.id"
:img="item.mainPic"
:title="item.title"
:price="item.actualPrice"
@click="addCart(item)"
class="goodlist-li"
>
</goods-card>
</div>
</div>
</template>
<script>
import Goodscard from '@/components/Goodscard'
export default {
components:{
'goods-card' : Goodscard
},
data(){
return {
goods:[],
cartList:[]
}
},
watch:{
cartList : {
handler(list){
localStorage.cartList = JSON.stringify(list)
},
deep:true
}
},
created(){
//获取数据
this.$axios.get('/data/list.json').then((res)=>{
console.log(res.data.data.data.list)
this.goods = res.data.data.data.list
})
//将内存展示到页面上
if(localStorage.cartList){
this.cartList = JSON.parse(localStorage.cartList)
}
},
methods:{
onClickLeft() {
window.history.back()shiyu
},
onClickRight() {
this.$router.push({
path:'/carts'
})
},
//加入购物车
addCart(item){
console.log(item)
let double = false
this.cartList.map((cart)=>{
if(cart.good.id == item.id){
cart.num++
double = true
return
}
})
if(!double){
this.cartList.push({
good:item,
num:1
})
}
}
}
}
</script>
<style scoped>
.goods-card-box{
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 50px;
}
.goodlist-li{
margin: 10px 1px;
border: 1px solid #eee;
border-radius: 5px;
}
</style>
11.Carts.vue(购物车)
<template>
<div>
<!-- 导航栏 -->
<van-nav-bar
title="购物车"
left-text="返回"
fixed
left-arrow
@click-left="onClickLeft"
/>
<!-- 商品卡片 -->
<van-checkbox-group v-model="result" style="margin-bottom:120px;margin-top:60px">
<div v-for="item in cartList" :key="item.good.id">
<van-checkbox :name="item"></van-checkbox>
<van-swipe-cell>
<van-card
tag="标签"
:price="item.good.actualPrice"
:desc="item.good.desc"
:title="item.good.title"
:thumb="item.good.mainPic"
:origin-price="item.good.originalPrice"
style="margin:10px 5px"
>
<template #num>
<van-stepper v-model="item.num" />
</template>
</van-card>
<template #right>
<van-button square text="删除" type="danger" class="delete-button" @click="del(item)" />
</template>
</van-swipe-cell>
</div>
</van-checkbox-group>
<!-- 提交订单栏 -->
<van-submit-bar :price="totalPrice" button-text="提交订单">
<van-checkbox v-model="sellAll" @click="handlSellAll">全选</van-checkbox>
<template #tip>
你的收货地址不支持同城送, <span>修改地址</span>
</template>
</van-submit-bar>
</div>
</template>
<script>
export default {
data(){
return {
sellAll:false,
cartList:[],
result:[],
totalPrice:0
}
},
watch:{
cartList:{
handler(list){
localStorage.cartList = JSON.stringify(list)
},
deep:true
},
result:{
handler(list){
if(list.length == this.cartList.length){
this.sellAll = true
}else{
this.sellAll = false
}
this.comtalPrice()
},
deep:true
}
},
methods:{
del(item){
console.log(item)
console.log(item.good)
this.cartList.splice(item.good,1)
},
onClickLeft(){
window.history.back()
},
handlSellAll(){
if(this.sellAll){
this.result = this.cartList
}else{
this.result = []
}
},
comtalPrice(){
let totalPrice = 0
this.result.map((item)=>{
totalPrice += item.good.actualPrice * item.num
})
this.totalPrice = totalPrice * 100
}
},
created(){
if(localStorage.cartList){
this.cartList = JSON.parse(localStorage.cartList)
}
},
}
</script>
<style scoped>
.delete-button {
height: 100%;
}
</style>
12.Myself.vue(我的)
<template>
<div>
我的
</div>
</template>
<script>
export default {
}
</script>
<style>
</style>
上一篇: 7-2 将数组中的数逆序存放 (10分)
下一篇: vaserv.exe是什么进程