欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

在vue脚手架环境利用vant组件简单实现移动端购物商城系统

程序员文章站 2022-04-21 20:13:44
...

在vue脚手架环境利用vant组件简单实现移动端购物商城系统

用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 (首页)
在vue脚手架环境利用vant组件简单实现移动端购物商城系统

<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(搜索页面)
在vue脚手架环境利用vant组件简单实现移动端购物商城系统

<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(分类页面)
在vue脚手架环境利用vant组件简单实现移动端购物商城系统

<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(商品列表页面)
在vue脚手架环境利用vant组件简单实现移动端购物商城系统

<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(购物车)
在vue脚手架环境利用vant组件简单实现移动端购物商城系统

<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(我的)
在vue脚手架环境利用vant组件简单实现移动端购物商城系统

<template>
  <div>
      我的
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>