vue2+vant 简易实现京东app商城(附源码)

这篇具有很好参考价值的文章主要介绍了vue2+vant 简易实现京东app商城(附源码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现效果

首页

vue2+vant 简易实现京东app商城(附源码)

分类页面

vue2+vant 简易实现京东app商城(附源码)

购物车

vue2+vant 简易实现京东app商城(附源码)

用户中心

vue2+vant 简易实现京东app商城(附源码)

项目说明

利用vue2+vant模仿京东app商城,实现首页商品分类页面购物车简易商品详情页登录页

创建项目

一、创建vue项目、安装模块

①、创建vue2项目mobile

$ vue create "mobile"

②、安装路由模块,vant组件

$ npm i vue-router@3 vant@latest-v2 -S

二、创建路由,创建页面组件、引入vant与样式

①、在src目录下创建views文件夹,存放页面组件
views结构如图
vue2+vant 简易实现京东app商城(附源码)
②、在src目录下创建router文件夹,新建index.js文件

import Vue from "vue";
import VueRouter from "vue-router"

Vue.use(VueRouter);

import Login from "../views/Login/index"

const routes = [
    {
        path: "/",
        redirect: "/login"
    },
    {
        name: "login",
        path: "/login",
        component: Login,
        meta: {
            title: "登录"
        }
    },
    {
        name: "main",
        path: "/main",
        component: () => import("../views/Main/index"),
        redirect: "/main/home",
        children: [
            {
                name: "home",
                path: "home",
                component: () => import("../views/Home/index"),
                meta: {
                    title: "商城首页"
                }
            },
            {
                name: "cates",
                path: "cates",
                component: () => import("../views/Cates/index"),
                meta: {
                    title: "商品分类"
                },
                children: [
                    {
                        name: "list",
                        path: "list",
                        component: () => import("../views/Cates/catelist"),
                    },
                ]
            },
            {
                name: "scar",
                path: "scar",
                component: () => import("../views/ShopCar/index"),
                meta: {
                    title: "购物车"
                }
            },
            {
                name: "mine",
                path: "mine",
                component: () => import("../views/Mine/index"),
                meta: {
                    title: "我的"
                }
            },
            {
                name: "goodsdetail",
                path: "goodsdetail",
                component: () => import("../views/Goods/index"),
                meta: {
                    title: "商品详情"
                }
            },
        ]
    }
]
const router = new VueRouter({
    mode: "history",
    linkActiveClass: "active",
    routes,

})
// 全局前置守卫
router.beforeEach((to, from, next) => {
    console.log(to, from)
    next()
})

export default router;

③、在src目录下创建utils文件夹,新建vant.js文件

import Vue from 'vue';
import Vant from 'vant';
import 'vant/lib/index.css';

Vue.use(Vant);

④、main.js中引入vant,注册路由

import Vue from 'vue'
import App from './App.vue'
// 引入vant
import "./utils/vant"
// 引入路由模块
import router from "./router/index"


Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App),
}).$mount('#app')

三、编写页面

①、App.vue一级路由

<template>
  <div id="app">
    <div class="content">
      <router-view />
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

<style>
#app,
html,
body {
  width: 100%;
  height: 100%;
}
</style>

②、Login文件夹下index.vue登录页面

<template>
  <div class="box">
    <!-- 导航头 -->
    <navbar></navbar>
    <van-form @submit="onSubmit">
      <van-field
        v-model="username"
        name="username"
        placeholder="账号名/邮箱/手机号"
        :rules="[{ required: true, message: '账号名/邮箱/手机号' }]"
      />
      <van-field
        v-model="password"
        type="password"
        name="password"
        placeholder="请输入密码"
        :rules="[{ required: true, message: '请填写密码' }]"
      ></van-field>
      <div style="margin: 16px">
        <van-button round block type="danger" native-type="submit"
          >登录</van-button
        >
      </div>
      <img src="@/assets/img/login/d.png" alt="" width="150px" />
    </van-form>
  </div>
</template>

<script>
import navbar from "@/components/navbar.vue";
import { Toast } from "vant";
export default {
  data() {
    return {
      username: "",
      password: "",
    };
  },
  methods: {
    onSubmit(values) {
      console.log("submit", values);
      if (values.username === "douzi" && values.password === "123123") {
        this.$router.push({ name: "main" });
      } else {
        Toast.fail("密码错误");
      }
    },
  },
  components: {
    navbar,
  },
};
</script>

<style  scoped>
.van-field {
  margin-top: 20px;
  padding-left: 30px;
  font-size: 16px;
}
.van-button {
  background-image: -webkit-gradient(
    linear,
    left top,
    right top,
    color-stop(0, #fab3b3),
    color-stop(73%, #ffbcb3),
    to(#ffcaba)
  );
  border: none;
}
img {
  margin: 120px;
}
</style>

③、Main文件夹下index.vue(布局页面) (包含二级路由)

<template>
  <div class="box">
    <div class="content">
      <!-- <h2>主页页面-布局</h2> -->
      <!-- 二级路由 -->
      <router-view />
    </div>
    <van-tabbar v-model="active" route>
      <van-tabbar-item to="/main/home" icon="home-o">首页</van-tabbar-item>
      <van-tabbar-item to="/main/cates" icon="apps-o">分类</van-tabbar-item>
      <van-tabbar-item to="/main/scar" icon="shopping-cart-o"
        >购物车</van-tabbar-item
      >
      <van-tabbar-item to="/main/mine" icon="contact">我的</van-tabbar-item>
    </van-tabbar>
  </div>
</template>

<script>
export default {
  data() {
    return {
      active: 0,
    };
  },
};
</script>

<style scoped>
.content {
  width: 100%;
  height: 100%;
}
</style>

④、Home文件夹下index.vue(首页页面)

<template>
  <div class="box">
    <!-- <h2>首页页面</h2> -->
    <navbar></navbar>
    <div class="head">
      <!-- 输入搜索框      @focus="searchFocus" @cancel="onCancel"   -->
      <van-search
        v-model="value"
        show-action
        shape="round"
        placeholder="请输入搜索关键词"
        background="#c52519"
        @search="onSearch"
      >
        <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>
    <!-- lu轮播图-------- -->
    <div class="lunbo">
      <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
        <van-swipe-item>
          <img src="@/assets/img/home/1.jpg" alt=""
        /></van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/img/home/2.jpg" alt=""
        /></van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/img/home/3.jpg" alt=""
        /></van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/img/home/4.jpg" alt=""
        /></van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/img/home/5.jpg" alt=""
        /></van-swipe-item>
        <van-swipe-item>
          <img src="@/assets/img/home/6.jpg" alt=""
        /></van-swipe-item>
      </van-swipe>
    </div>
    <!-- 导航 -->
    <div class="nav">
      <van-swipe class="my-swipe1" autoplay="false" indicator-color="white">
        <van-swipe-item
          ><van-grid :column-num="5" :border="false">
            <van-grid-item
              v-for="value in navinfo"
              :key="value.id"
              :icon="value.src"
              :text="value.text"
            /> </van-grid
        ></van-swipe-item>
        <van-swipe-item
          ><van-grid :column-num="5" :border="false">
            <van-grid-item
              v-for="value in navinfo2"
              :key="value.id"
              :icon="value.src"
              :text="value.text"
            /> </van-grid
        ></van-swipe-item>
      </van-swipe>
    </div>
    <!-- 活动秒杀 -->
    <div class="active">
      <div class="more">
        <span>京东秒杀</span>
        <span>16</span>
        <!-- <span><a>00</a>:<a>00</a>:<a>00</a></span> -->
        <van-count-down :time="time">
          <template #default="timeData">
            <a class="block">{{ timeData.hours }}</a>
            <a class="colon">:</a>
            <a class="block">{{ timeData.minutes }}</a>
            <a class="colon">:</a>
            <a class="block">{{ timeData.seconds }}</a>
          </template>
        </van-count-down>
        <span>爆款轮番秒<van-icon name="arrow" /></span>
      </div>

      <van-swipe class="my-swipe3" autoplay="false" indicator-color="white">
        <van-swipe-item
          ><van-grid :column-num="5">
            <van-grid-item
              :border="false"
              v-for="value in activeinfo"
              :key="value.id"
              :icon="value.src"
              :text="value.price"
            /> </van-grid
        ></van-swipe-item>
        <van-swipe-item
          ><van-grid :column-num="5">
            <van-grid-item
              :border="false"
              v-for="value in activeinfo2"
              :key="value.id"
              :icon="value.src"
              :text="value.price"
            /> </van-grid
        ></van-swipe-item>
      </van-swipe>
    </div>
    <!-- 商品卡片 -->
    <!-- 商品卡片 -->
    <div class="card-list">
      <GoodsItem></GoodsItem>
    </div>
  </div>
</template>

<script>
import navbar from "@/components/navbar.vue";
import { Toast } from "vant";
import GoodsItem from "./goodItem.vue";
export default {
  data() {
    return {
      // 倒计时
      time: 30 * 60 * 60 * 1000,
      value: "",
      navinfo: [
        { id: 1, src: require("@/assets/img/bar/1.png"), text: "京东超市" },
        { id: 2, src: require("@/assets/img/bar/2.png"), text: "数码电器" },
        { id: 3, src: require("@/assets/img/bar/3.png"), text: "京东新百货" },
        { id: 4, src: require("@/assets/img/bar/4.png"), text: "京东生鲜" },
        { id: 5, src: require("@/assets/img/bar/5.png"), text: "京东到家" },
        { id: 6, src: require("@/assets/img/bar/6.png"), text: "充值缴费" },
        { id: 7, src: require("@/assets/img/bar/7.png"), text: "附近好店" },
        { id: 8, src: require("@/assets/img/bar/8.png"), text: "领券" },
        { id: 9, src: require("@/assets/img/bar/9.png"), text: "PLUS会员" },
        { id: 10, src: require("@/assets/img/bar/10.png"), text: "京东国际" },
      ],
      navinfo2: [
        { id: 1, src: require("@/assets/img/bar/11.png"), text: "京东拍卖" },
        { id: 2, src: require("@/assets/img/bar/12.png"), text: "玩3C" },
        { id: 3, src: require("@/assets/img/bar/13.png"), text: "沃尔玛" },
        { id: 4, src: require("@/assets/img/bar/14.png"), text: "美妆馆" },
        { id: 5, src: require("@/assets/img/bar/15.png"), text: "京东旅行" },
        { id: 6, src: require("@/assets/img/bar/16.png"), text: "拍拍二手" },
        { id: 7, src: require("@/assets/img/bar/17.png"), text: "全部" },
      ],
      // 活动秒杀
      active: 8,
      // 活动秒杀信息
      activeinfo: [
        { id: 1, src: require("@/assets/img/active/1.jpg"), price: "¥46" },
        { id: 2, src: require("@/assets/img/active/2.jpg"), price: "¥2379" },
        { id: 3, src: require("@/assets/img/active/3.jpg"), price: "¥62" },
        { id: 4, src: require("@/assets/img/active/4.jpg"), price: "¥698" },
        { id: 5, src: require("@/assets/img/active/5.jpg"), price: "¥459" },
      ],
      activeinfo2: [
        { id: 1, src: require("@/assets/img/active/6.jpg"), price: "¥248" },
        { id: 2, src: require("@/assets/img/active/7.jpg"), price: "¥1399" },
        { id: 3, src: require("@/assets/img/active/8.jpg"), price: "¥297" },
        { id: 4, src: require("@/assets/img/active/9.jpg"), price: "¥2894" },
      ],
    };
  },
  methods: {
    onSearch(val) {
      Toast(val);
    },
    onCancel() {
      Toast("取消");
    },
  },
  components: {
    GoodsItem,
    navbar,
  },
};
</script>

<style scoped>
.box {
  /* background-color: rgb(233, 233, 233); */
}
.search-logo {
  color: #e93c3e;
  font-weight: bold;
  font-size: 20px;
}
.van-search__content--round {
  width: 300px;
}
.lunbo {
  /* background: #c52519; */
  background-image: linear-gradient(0deg, #f1503b, #c82519 50%);
  border-bottom-left-radius: 100%;
  border-bottom-right-radius: 100%;
}
.my-swipe {
  margin: 0 auto 0;
  border-radius: 15px;
  width: 360px;
  height: 150px;
}
.my-swipe .van-swipe-item {
  color: #fff;
  padding: 0;
  text-align: center;
  background-color: #ffffff;
}
.my-swipe .van-swipe-item img {
  width: 100%;
  height: 100%;
}
.my-swipe1 .van-swipe-item {
  color: #fff;
  text-align: center;
  background-color: #ffffff;
}
::v-deep .van-swipe__indicator--active {
  background-color: red;
}
/* --------------------- */
.active {
  background-color: #fff;
  border-radius: 5px;
  height: 140px;
  width: 369px;
  overflow: hidden;
  margin: auto;
  border: 1px solid rgb(189, 189, 189);
}
.active .more {
  width: 100%;
  height: 35px;
  background: url("../../assets/img/active/bgccc.png") no-repeat center/cover;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.active .more span {
  display: inline-block;
  height: 18px;
  line-height: 18px;
  font-size: 12px;
  color: #333;
}
.active .more span:nth-of-type(2) {
  width: 10%;
  color: red;
  background: url("../../assets/img/active/bgc.png") no-repeat top 0 right 0 /21px
    18px;
}
/* .active > .more span:nth-of-type(3) {
  width: 40%;
  color: red;
}
.active > .more span:nth-of-type(3) a {
  display: inline-block;
  padding: 1px;
  border-radius: 5px;
  background-color: red;
  color: #fff;
  font-size: 14px;
} */
.active .more span:nth-of-type(3) {
  color: red;
}
.active .more span:nth-of-type(3) .van-icon-arrow {
  display: inline-block;
  background-color: red;
  color: white;
  border-radius: 50%;
}
.active ::v-deep .van-tabs__content {
  display: flex;
}
.active ::v-deep .van-tabs__content .van-tab__pane span {
  color: red;
}
/* ------------ogo0ds */
.card-list {
  margin: 15px auto 0;
  width: 369px;
  border-radius: 5px;
}

.van-count-down {
  width: 40%;
  height: 18px;
}
.van-count-down .colon {
  display: inline-block;
  /* margin: 0 4px; */
  color: #ee0a24;
}
.van-count-down .block {
  display: inline-block;
  width: 20px;
  color: #fff;
  border-radius: 5px;
  font-size: 12px;
  text-align: center;
  background-color: #ee0a24;
}
.my-swipe3 {
  height: 105px;
}
.my-swipe3 ::v-deep i.van-icon.van-grid-item__icon {
  font-size: 55px;
}
.my-swipe3 ::v-deep .van-grid-item__text {
  font-size: 15px;
  color: #f2270c;
  font-weight: 550;
  /* font-family: JDZhengHT-EN-Regular; */
}
.my-swipe3 .van-swipe-item {
  color: #fff;
  text-align: center;
}
</style>

⑤、Home文件夹下goodItem.vue(商品组件)

<template>
  <div class="goods-item">
    <div
      class="item"
      v-for="item in goods"
      :key="item.id"
      @click="showGood(item)"
    >
      <div class="item-detail">
        <img :src="item.src" alt="" />
        <div class="desc">
          <template><span v-if="item.status === 1">京东超市</span></template
          >{{ item.text }}
        </div>
        <div class="price">
          <span class="new-price">{{ item.price }}.00</span>
          <!-- <span class="old-price">
            <del>{{ item.GoodPriceaftersale }}</del>
          </span> -->
        </div>
        <p class="same">
          <span>{{ item.count }}条评论</span><span>看相似</span>
        </p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      goods: [
        {
          id: 1,
          src: require("@/assets/img/goods/1.webp"),
          text: "CGVS睡衣女士棉春秋季薄款套头家居服可爱少sadsadas女卡通学生居家长袖套装 YS5251 M(建议身高150-156 体重80-100)",
          price: 188,
          count: "17",
          status: 1,
        },
        {
          id: 2,
          src: require("@/assets/img/goods/2.webp"),
          text: "云米(VIOMI)1.5匹智能家电 变频冷暖Space E AI全域风 新一级以旧换新 壁挂式挂机空调KFRd-35GW/Y2QX2-A1",
          price: 4888,
          count: "18万",
        },
        {
          id: 3,
          src: require("@/assets/img/goods/3.webp"),
          text: "红毛丹罐头 泰双象 2罐 新鲜毛荔枝双象红毛丹糖水果罐头儿时记忆 红毛丹2罐",
          price: 288,
          count: "1万+",
          status: 1,
        },
        {
          id: 4,
          src: require("@/assets/img/goods/4.webp"),
          text: "海尔(Haier)冰箱 467升一级能效双变频风冷无霜十字对开门四开门多门家用超薄省电大容量电冰箱",
          price: 6999,
          count: "1000+",
        },
        {
          id: 5,
          src: require("@/assets/img/goods/5.webp"),
          text: "omto托特包女包小众单肩大容量上课通勤大包百搭手提包女 松露黑中号【底托一起发】",
          price: 2586,
          count: "50万+",
          status: 1,
        },
        {
          id: 6,
          src: require("@/assets/img/goods/6.webp"),
          text: "华凌冰箱 549升白色对开门双开门家用超薄冰箱 一级能效双变频风冷无霜WiFi智能家用大容量冰箱BCD-549WKPZH",
          price: 5999,
          count: "500+",
        },
        {
          id: 7,
          src: require("@/assets/img/goods/7.webp"),
          text: "罗技(Logitech)MX Master 3S 鼠标 无线蓝牙鼠标 办公鼠标 右手鼠标  石墨黑  带Logi Bolt无线接收器",
          price: 499,
          count: "1万+",
          status: 1,
        },
        {
          id: 8,
          src: require("@/assets/img/goods/8.webp"),
          text: "蒙牛 特仑苏 纯牛奶250ml*16每100ml含3.6g优质蛋白质 礼盒装 品质好礼",
          price: 49,
          count: "900+",
          status: 1,
        },
        {
          id: 9,
          src: require("@/assets/img/goods/9.webp"),
          text: "良品铺子 黑麦全麦面包1000g/箱 早餐粗粮低脂健身代餐全麦面包膳食纤维零蔗糖面包点心吐司零食整箱装",
          price: 39,
          count: "100+",
          status: 1,
        },
        {
          id: 10,
          src: require("@/assets/img/goods/10.webp"),
          text: "闪魔 苹果14钢化膜 iphone14手机膜 22年新款苹果高清抗指纹防刮保护抗蓝光防窥贴膜 【14^加强版】2片+神器 无黑边",
          price: 18,
          count: "300+",
        },
      ],
    };
  },
  methods: {
    showGood(item) {
      this.$router.push({
        name: "goodsdetail",
        query: {
          id: item.id,
          src: item.src,
          price: item.price,
          text: item.text,
        },
      });
    },
  },
};
</script>

<style scoped>
.goods-item {
  width: 369px;
  display: flex;
  align-content: flex-start;
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
}
.goods-item .item {
  width: 170px;
  /* height: 280px; */
  border: 1px solid rgb(218, 218, 218);
  border-radius: 5px;
  margin-bottom: 10px;
}
.goods-item .item .item-detail {
  width: 100%;
}
.goods-item .item .item-detail img {
  width: 170px;
  height: 170px;
}
.desc {
  width: 95%;
  margin: auto;
  /* height: 20px;
  line-height: 20px;
  text-overflow: ellipsis;
  overflow: hidden;
  width: 100px; */
  padding: 3px;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.desc span {
  font-size: 10px;
  padding: 1px 2px 1px 2px;
  background-color: rgb(13, 128, 13);
  color: #ffff;
}
.new-price {
  font-size: 20px;
  color: red;
}
.same {
  display: flex;
  justify-content: space-between;
  padding-right: 5px;
}
.same span:nth-of-type(1) {
  padding: 4px 8px 4px 8px;
  font-size: 10px;
  color: rgb(126, 126, 126);
}
.same span:nth-of-type(2) {
  padding: 4px 8px 4px 8px;
  /* display: inline-block; */
  background-color: rgba(202, 202, 202, 0.295);
  font-size: 12px;
  border-radius: 26px;
}
</style>

⑥、Cates文件夹下index.vue(商品分类页面)

<template>
  <div class="box">
    <div class="head">
      <!-- 搜索框 -->
      <van-search
        v-model="value"
        shape="round"
        background="#fff"
        placeholder="请输入搜索关键词"
      >
        <template #left>
          <van-icon
            name="arrow-left"
            color="#333"
            size="25px"
            style="margin-right: 10px"
          />
        </template>
      </van-search>
    </div>
    <!-- 商品分类 -->
    <div class="cates">
      <van-tree-select
        height="100%"
        :items="items"
        :main-active-index.sync="active"
      >
        <template #content>
          <!-- <van-image
            v-if="active === 0"
            src="https://img01.yzcdn.cn/vant/apple-1.jpg"
          /> -->
          <div class="list-item" v-if="active === 0">
            <p>热门分类</p>
            <van-grid :column-num="3">
              <van-grid-item
                :border="false"
                icon-size="70px"
                v-for="item in hotList"
                :key="item.id"
                :icon="item.src"
                :text="item.name"
              />
            </van-grid>
          </div>
          <div class="list-item" v-if="active === 1">
            <p>热门品牌</p>
            <van-grid :column-num="3">
              <van-grid-item
                :border="false"
                icon-size="70px"
                v-for="item in phoneList"
                :key="item.id"
                :icon="item.src"
                :text="item.name"
              />
            </van-grid>
            <p>手机通讯</p>
            <van-grid :column-num="3">
              <van-grid-item
                :border="false"
                icon-size="70px"
                v-for="item in phoneList"
                :key="item.id"
                :icon="item.src"
                :text="item.name"
              />
            </van-grid>
          </div>
          <!--....... -->
        </template>
      </van-tree-select>
    </div>
  </div>
</template>

<script>
// import { Notify } from "vant";
import listInfo from "./listinfo.js";
export default {
  data() {
    return {
      value: "",
      // 热门导航栏
      hotNav: listInfo.goodsHot,
      // 热门推荐图片
      hotList: listInfo.goodsHotInfo,
      // 手机
      phoneList: listInfo.phoneInfo,

      active: 0,
      items: [
        { text: "热门推荐" },
        { text: "手机数码" },
        { text: "京东超市" },
        { text: "家用电器" },
        { text: "电脑办公" },
        { text: "玩具乐器" },
        { text: "家居厨具" },
        { text: "家具家装" },
        { text: "男装" },
        { text: "男鞋" },
        { text: "女装" },
        { text: "女鞋" },
        { text: "美妆护肤" },
        { text: "医药保健" },
        { text: "酒水饮料" },
        { text: "运动户外" },
      ],
    };
  },
};
</script>

<style scoped>
.van-search {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 99;
  width: 100%;
}
.box {
  position: relative;
  overflow: hidden;
}
.cates {
  height: 80%;
}
.van-sidebar {
  margin-top: 54px;
}
.van-tree-select__nav {
  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: 100px;
  overflow-y: auto;
  background-color: #f7f8fa;
  -webkit-overflow-scrolling: touch;
}
.van-tree-select__content {
  position: absolute;
  width: 310px;
  height: 100%;
  top: 54px;
  right: 0;
}
.list-item p {
  margin: 10px;
  font-size: 14px;
  color: #333;
  padding-left: 5px;
}
.list-item ::v-deep i.van-icon.van-grid-item__icon {
  font-size: 70px;
}
</style>

⑦、Shopcar文件夹下index.vue(购物车页面)

<template>
  <div class="box">
    <!-- 导航栏 -->
    <van-nav-bar
      title="购物车"
      left-text="返回"
      fixed
      left-arrow
      @click-left="onClickLeft"
    />
    <div class="content">
      <!-- <h2>购物车</h2> -->
      <!-- 购物车 -->
      <van-checkbox-group
        v-model="result"
        style="margin-bottom: 120px; margin-top: 20px"
      >
        <div v-for="(item, index) in goods" :key="item.id">
          <van-checkbox :name="item"></van-checkbox>
          <van-swipe-cell>
            <van-card
              tag="折扣"
              :price="item.price"
              :desc="item.text"
              :title="item.title"
              :thumb="item.src"
              style="margin: 10px 5px"
            >
              <template #tags>
                <van-tag plain type="success" v-if="item.status === 1"
                  >京东超市</van-tag
                >
                <van-tag plain type="danger">双十一促销</van-tag>
              </template>
              <template #num>
                <van-stepper v-model="item.num" />
              </template>
            </van-card>
            <template #right>
              <van-button
                square
                text="删除"
                type="danger"
                class="delete-button"
                @click="del(index)"
              />
            </template>
          </van-swipe-cell>
        </div>
      </van-checkbox-group>

      <!-- <van-card
        num="2"
        price="2.00"
        desc="描述信息"
        title="商品标题"
        thumb="https://img01.yzcdn.cn/vant/ipad.jpeg"
      >
        <template #tags>
          <van-tag plain type="danger">标签</van-tag>
          <van-tag plain type="danger">标签</van-tag>
        </template>
        <template #num>
          <van-stepper v-model="num" />
        </template>
      </van-card> -->

      <!-- 提交订单栏 -->
      <van-submit-bar
        :price="totalPrice"
        button-text="提交订单"
        @submit="onSubmit"
      >
        <van-checkbox v-model="sellAll" @click="handlSellAll"
          >全选</van-checkbox
        >
        <template #tip>
          你的收货地址暂时不支持配送, <span>请修改您的地址</span>
        </template>
      </van-submit-bar>
    </div>
  </div>
</template>

<script>
import { Dialog, Toast } from "vant";
export default {
  data() {
    return {
      sellAll: false,
      cartList: [],
      result: [],
      totalPrice: 0,
      num: 0,
      goods: [
        {
          id: 1,
          src: require("@/assets/img/goods/1.webp"),
          text: "CGVS睡衣女士棉春秋季薄款套头家居服可爱少sadsadas女卡通学生居家长袖套装 YS5251 M(建议身高150-156 体重80-100)",
          price: 98.8,
          count: "17",
          title: "学生居家长袖套装",
          status: 1,
          num: 0,
        },
        {
          id: 2,
          src: require("@/assets/img/goods/2.webp"),
          text: "云米(VIOMI)1.5匹智能家电 变频冷暖Space E AI全域风 新一级以旧换新 壁挂式挂机空调KFRd-35GW/Y2QX2-A1",
          price: 3888.8,
          title: "智能家电",
          count: "18万",
          num: 0,
        },
        {
          id: 3,
          src: require("@/assets/img/goods/3.webp"),
          text: "红毛丹罐头 泰双象 2罐 新鲜毛荔枝双象红毛丹糖水果罐头儿时记忆 红毛丹2罐",
          price: 58.88,
          count: "1万+",
          title: "水果罐头",
          status: 1,
          num: 0,
        },
        {
          id: 4,
          src: require("@/assets/img/goods/7.webp"),
          text: "罗技(Logitech)MX Master 3S 鼠标 无线蓝牙鼠标 办公鼠标 右手鼠标  石墨黑  带Logi Bolt无线接收器",
          price: 499.3,
          count: "1万+",
          title: "罗技(Logitech)MX Master 3S 鼠标",
          status: 1,
          num: 0,
        },
      ],
    };
  },
  watch: {
    result: {
      // 监听商品选择状态
      handler(list) {
        if (list.length == this.goods.length) {
          this.sellAll = true;
        } else {
          this.sellAll = false;
        }
        // 调用价格计算函数
        this.comtalPrice();
      },
      deep: true, //深度监听
    },
  },
  methods: {
    onClickLeft() {
      // this.$router.push({ name: "home" });
      window.history.back();
    },
    // 删除商品
    del(index) {
      Dialog.confirm({
        title: "删除商品",
        message: "确认删除此商品吗",
      })
        .then(() => {
          // on confirm
          console.log(index);
          this.goods.splice(index, 1);
        })
        .catch(() => {
          // on cancel
          return;
        });
    },
    // 全选
    handlSellAll() {
      if (this.sellAll) {
        this.result = this.goods;
      } else {
        this.result = [];
      }
    },
    // 计算总价格
    comtalPrice() {
      let totalPrice = 0;
      this.result.map((item) => {
        totalPrice += item.price * item.num;
      });
      this.totalPrice = parseFloat(totalPrice) * 100;
    },
    // 提交商品订单
    onSubmit() {
      if (this.result.length === 0) {
        Toast.fail("请选择商品再提交");
      } else {
        // Toast.success("成功文案");
        const toast = Toast.loading({
          duration: 0, // 持续展示 toast
          forbidClick: true,
          message: "正在提交 3 秒",
        });

        let second = 3;
        const timer = setInterval(() => {
          second--;
          if (second) {
            toast.message = `正在提交 ${second}`;
          } else {
            clearInterval(timer);
            // // 手动清除 Toast
            Toast.clear();
            Toast.success(`成功!,您花费了${this.totalPrice / 100}`);
            this.result = [];
          }
        }, 1000);
      }
    },
  },
};
</script>

<style scoped>
.box {
  padding-top: 46px;
}
.content {
  /* margin-top: 46px; */
}
.van-submit-bar {
  position: fixed;
  bottom: 50px;
}
.van-checkbox-group .van-button--danger {
  width: 100%;
  height: 100%;
}
</style>

⑧、Mine文件夹下index.vue(用户中心页面)

<template>
  <div class="box">
    <!-- <h2>我的</h2> -->
    <div class="head">
      <van-icon name="user-circle-o" /><a @click="login">京东用户</a>
    </div>
    <div class="user">
      <div class="user-dist">
        <span>商品收藏</span><span>店铺收藏</span><span>我的足迹</span>
      </div>
      <div class="user-dist-icon">
        <van-grid :column-num="4" :border="false">
          <van-grid-item
            v-for="value in icon01"
            :key="value.id"
            :icon="value.icon"
            :text="value.text"
          />
        </van-grid>
      </div>
    </div>
    <div class="user2">
      <div class="user-dist-icon">
        <van-grid :column-num="5" :border="false">
          <van-grid-item
            v-for="value in icon02"
            :key="value.id"
            :icon="value.icon"
            :text="value.text"
          />
        </van-grid>
      </div>
    </div>
    <div class="user3">
      <div class="user-dist-icon">
        <van-grid :column-num="4" :border="false">
          <van-grid-item
            v-for="value in icon03"
            :key="value.id"
            :icon="value.icon"
            :text="value.text"
          />
        </van-grid>
      </div>
    </div>
    <div class="logo"><img src="@/assets/img/mine/logo.png" alt="" /></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      icon01: [
        { id: 1, icon: "credit-pay", text: "待付款" },
        { id: 2, icon: "send-gift-o", text: "待收货" },
        { id: 3, icon: "after-sale", text: "退换/售后" },
        { id: 4, icon: "records", text: "全部订单" },
      ],
      icon02: [
        { id: 1, icon: "discount", text: "优惠券" },
        { id: 2, icon: "balance-list-o", text: "白条额度" },
        { id: 3, icon: "smile-o", text: "京豆" },
        { id: 4, icon: "bill-o", text: "红包" },
        { id: 5, icon: "paid", text: "全部资产" },
      ],
      icon03: [
        { id: 1, icon: "smile-comment-o", text: "客服服务" },
        { id: 2, icon: "todo-list-o", text: "我的预约" },
        { id: 3, icon: "balance-pay", text: "闲置换钱" },
        { id: 4, icon: "replay", text: "高价回收" },
      ],
    };
  },
  methods: {
    login() {
      this.$router.push({ name: "login" });
    },
  },
};
</script>

<style scoped>
.box {
  padding: 46px 30px;
  background-image: linear-gradient(
    60deg,
    rgba(243, 146, 142, 0.151),
    rgba(235, 50, 136, 0.151)
  );
}
.box .head {
  font-size: 23px;
  letter-spacing: 3px;
  color: #333;
}
.box .head .van-icon-user-circle-o {
  font-size: 60px;
  color: red;
  vertical-align: middle;
}
.user,
.user2,
.user3 {
  /* border: 1px solid red; */
  /* padding: 55px; */
  margin-top: 15px;
  border-radius: 8px;
  border: 1px solid rgb(214, 214, 214);
  overflow: hidden;
}
.logo {
  padding: 55px;
  margin-top: 15px;
  border-radius: 8px;
  border: 1px solid rgb(214, 214, 214);
  overflow: hidden;
  background-color: #fff;
  text-align: center;
}
.user .user-dist {
  height: 30px;
  display: flex;
  justify-content: space-around;
  background-color: rgba(236, 236, 236, 0.651);
  align-items: center;
}
.user .user-dist-icon .van-grid-item ::v-deep i.van-icon.van-grid-item__icon,
.user2 .user-dist-icon .van-grid-item ::v-deep i.van-icon.van-grid-item__icon,
.user3 .user-dist-icon .van-grid-item ::v-deep i.van-icon.van-grid-item__icon {
  font-size: 32px;
}
.user
  .user-dist-icon
  .van-grid
  .van-grid-item:nth-of-type(4)
  ::v-deep
  i.van-icon.van-grid-item__icon {
  color: red;
}
.user2
  .user-dist-icon
  .van-grid
  .van-grid-item:nth-of-type(5)
  ::v-deep
  i.van-icon.van-grid-item__icon {
  color: red;
}
</style>

总结

此项目利用vue2+vant,实现京东app商城的首页,商品分类,购物车,用户页面,用户登录,简易商品详情展示,完整代码在此文档中并未展示完全。
项目源码:https://gitee.com/Mr-doudou/simple-imitation-Jingdong-Mall.git

源码说明:克隆到本地电脑之后,进入项目文件,执行npm i 安装相关依赖,npm run serve启动项目。文章来源地址https://www.toymoban.com/news/detail-508543.html

到了这里,关于vue2+vant 简易实现京东app商城(附源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue2+three.js实现类似VR、3D全景效果

    效果图: 俩图标是我自己加的前进后退按钮,也是百度了好久,再加上GPT的帮助,才给搞出来。因为需求急,都不看官方文档,百度到一个能跑的demo之后改吧改吧,就先用着了。 下面是代码: 这里 代码有很多用不到的地方和需要优化的地方,我是来不及改了,就先这样吧

    2024年02月15日
    浏览(54)
  • 微信小程序——仿写京东购物商城带源码

    《微信小程序 》 实验三报告 1. 实验名称: 仿京东购物商城 2. 实验目的: 熟悉使用微信小程序开发工具,开发微信小程序项目。仿京东购物商城。首页按分块显示商品。点击“分类”tab,跳转到商品的分类页面。 3. 实验要求: 手工编写的项目。 具体要求:根据列表式布局、多

    2024年02月11日
    浏览(62)
  • vue2+three.js+blender(实现3d 模型引入并可点击效果)

    2023.9.13今天我学习了如何把3d建模里面的模型引入到vue中,并可以实现拖动,点击的效果: 首先安装: npm install three 相关代码如下:  如果没有图片可以去 Three.js--》建模软件如何加载外部3D模型?_threejs加载3d模型_亦世凡华、的博客-CSDN博客

    2024年02月03日
    浏览(64)
  • uni-app基于vue实现商城小程序

    目录 一、前言 二、功能效果图 1.首页 2.分类 ​3.活动 4.我的 ​5.商品详情 6.购物车 三、代码实现 1.项目结构截图 uni-app,Hbuilder 2.首页源码 3.数据模拟通讯 四、总结 参考“网易严选”小程序 项目采用传统vue项目结构,即uni-app打包和运行成小程序,使用HBuilder开发工具开发项

    2024年02月03日
    浏览(54)
  • 【vue2】element-ui el-transfer扩展 实现多列效果一对多

    vue2 el-transfer 穿梭框实现多类别 template 复制Transfer源码中的template,并拓展我们需要的列表2和button script 这里重写了Transfer的addToLeft方法,按着element-ui的逻辑写出第二个列表的逻辑即可。源码就不做解释了,这个组件比较简单,感兴趣的朋友可以去看看 style GitHub地址

    2024年02月08日
    浏览(64)
  • vue+elementui实现app布局小米商城,样式美观大方,功能完整

    目录 一、项目效果在线预览 二、效果图 1.首页效果图 2.分类,动态分类+商品数据根据所属分类动态切换 3.购物车,动态添加购物车(增、删、改、查) 4.我的 5.登录注册 6.商品详情 7.搜索(动态模糊搜索、搜索历史记录) 8.提交订单-商品详情(单个商品) 9.提交订单-购物

    2024年02月15日
    浏览(87)
  • Vue2源码梳理:update的整体实现流程

    update 回到之间 $mount时,mountComponent 函数的过程,vm._render 是如何创建了一个 VNode 接下来就是要把这个 VNode 渲染成一个真实的 DOM 并渲染出来,这个过程是通过 vm._update 完成的 _update 它是一个vue 的私有方法,它把我们的 vnode 渲染成真实的 dom _update的方法,也是原型上的一个方

    2024年02月20日
    浏览(42)
  • vue2+vant2+rem+axios+钉钉自动登录 h5模板

    请轻轻的点一下这里~ Vue CLI 需要 Node.js 8.9 或更高版本 (推荐 8.11.0+)。你可以使用 nvm 或 nvm-windows 在同一台电脑中管理多个 Node 版本。 本示例 Node.js 14.17.0 对应配置 .env.staging config/env.staging.js 对应配置 .env.production config/env.production.js package.json 里的 scripts 配置 serve stage build ,通

    2024年02月03日
    浏览(34)
  • 项目实战:《智慧线上购物商城》:基于vue3+vite+vant4组件(一)

    本项目主要是基于vue3和vite以及vant4组件所开发的移动端购物商城。项目没有接口,所运用的存储数据为json数据通过axios请求,以及Localstorage等技术实现数据。 开发的模型参考以下的网站,感兴趣的小伙伴可以去看看。 AxureShop原型演示 AxureShop原型演示 https://demo.axureshop.com/?

    2024年02月02日
    浏览(97)
  • 使用vue3 + TS + Pinia + Vant4 + vite搭建商城H5项目框架

    本文主要将如何利用搭建一个初始化的商城H5项目框架。初始化阶段使用的技术栈有:vue3.2、vue-router、 TS 、 Pinia 、 Vant4、Less、vite                         node -v 检测是否有安装node.js,未安装请先去官网安装node.js         终端输入: npm init vite         自定

    2024年02月12日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包