# Spring Boot + Vue 开发移动端商城

转载于:楠哥教你学Java (opens new window)

# 前言

最近有不少小伙伴留言希望楠哥出一套 Spring Boot + Vue 项目实战教程,大家有需求,楠哥就会尽量满足大家,所以专程为大家做了一个教程,非常适合希望快速上手 Spring Boot + Vue 项目实战的同学。话不多说,直接来看项目。

项目名称: 基于移动端的手机商城 PhoneStore

前端技术: Vue + Vant UI + less + axios

后端技术: Spring Boot + Spring Data JPA + MySQL

项目截图:

接下来楠哥就带领大家来完成代码的开发。

# 创建 Vue 工程

1、 创建 Vue 工程,安装 Vant UI 和 less,命令如下。

安装 Vant UI

npm i vant -S

安装 less

cnpm install less less-loader --save

2、创建首页 Home.vue。

这里我们使用 Vant UI 提供的组件来完成,主要包括两个组件:Card 商品卡片和 Sku 商品规格,大家可以参考 Vant UI 官方文档:https://youzan.github.io/vant/#/zh-CN

我们这里简单说一下这两个组件的使用,Card 代码如下所示。

<van-card v-for="(item,index) in phones"
          :price="item.price"
          :desc="item.desc"
          :title="item.title"
          :thumb="item.thumb"
>
  <template #tags>
    <van-tag v-for="tag in item.tag" color="#f2826a" style="margin-left: 5px;">{{tag.name}}</van-tag>
  </template>
  <template #footer>
    <van-button round type="info" size="mini" @click="buy(index)">购买</van-button>
  </template>
</van-card>

phones: [
    {
      id: 1,
      title: "Honor 8A",
      price: "2800.00",
      desc: "魅焰红",
      tag: [
        {
          name: "720P珍珠屏"
        },
        {
          name: "Micro USB接口"
        }
      ],
      thumb: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg"
    },
    {
      id: 5,
      title: "HUAWEI nova 5 Pro",
      price: "5450.00",
      desc: "魅焰红",
      tag: [
        {
          name: "内存3GB"
        },
        {
          name: "Micro USB接口"
        }
      ],
      thumb: "../static/8a0f5be0-3c78-4f23-b58b-dc2a92f1f95a.jpg"
    },
    {
      id: 9,
      title: "SAMSUNG G S10",
      price: "7254.00",
      desc: "魅焰红",
      tag: [
        {
          name: "720P珍珠屏"
        },
        {
          name: "存储32GB"
        }
      ],
      thumb: "../static/a4f0cef8-59da-4f7c-abfa-d373f6648035.jpg"
    },
    {
      id: 13,
      title: "VIVO X27",
      price: "2888.00",
      desc: "魅焰红",
      tag: [
        {
          name: "F/1.8光圈"
        },
        {
          name: "Micro USB接口"
        }
      ],
      thumb: "../static/cdf065ec-e409-4204-93e6-600e172e461a.jpg"
    },
    {
      id: 17,
      title: "Meizu 16s",
      price: "1220.00",
      desc: "魅焰红",
      tag: [
        {
          name: "720P珍珠屏"
        },
        {
          name: "Micro USB接口"
        }
      ],
      thumb: "../static/1a2b8e30-6e98-405f-9a18-9cd31ff96c35.jpg"
    }
]

num 表示商品数量,price 表示商品价格,desc 表示商品的描述信息,title 表示商品标题,thumb 是商品图片的链接,运行结果如下图所示。

Card 组件的使用较为简单,Sku 组件的使用会稍微复杂一些,具体代码如下所示。

<van-sku
        v-model="show"
        :sku="sku"
        :goods="goods"
        :hide-stock="sku.hide_stock"
        @buy-clicked="onBuyClicked"
>
  <template #sku-actions="props">
    <div class="van-sku-actions">
      <!-- 直接触发 sku 内部事件,通过内部事件执行 onBuyClicked 回调 -->
      <van-button
              square
              size="large"
              type="danger"
              @click="props.skuEventBus.$emit('sku:buy')"
      >
        买买买
      </van-button>
    </div>
  </template>
</van-sku>sku = {
  tree: [
    {
      k: "规格",
      v: [
        {
          id: 1,
          name: "32GB",
          imgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg",
          previewImgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg"
        },
        {
          id: 2,
          name: "64GB",
          imgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg",
          previewImgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg"
        }
      ],
      k_s: "s1"
    }
  ],
  list: [
    {
      s1: 1,
      price: 280000,
      stock_num: 5
    },
    {
      s1: 2,
      price: 320000,
      stock_num: 5
    }
  ],
  price: "2800.00",
  stock_num: 10,
  none_sku: false,
  hide_stock: false
}

v-model 表示是否显示 Sku 组件,sku 表示绑定的规格对象,goods 表示绑定的商品对象,hide-stock 表示是否隐藏库存。使用 Sku 组件的关键在于搞清楚 skugoods 的对象结构。

其中 tree 表示具体规格数据,k 为规格名称,v 为规格选项,如下所示。

{
  k: "规格",
  v: [
    {
      id: 1,
      name: "32GB",
      imgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg",
      previewImgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg"
    },
    {
      id: 2,
      name: "64GB",
      imgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg",
      previewImgUrl: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg"
    }
  ],
  k_s: "s1"
}

我们可以看到 v 对象中的属性,id 为规格编号,name 为规格名称,imgUrl 为规格图片,previewImgUrl 为规格预览图片。

需要注意的是,v 中的规格参数只是一部分,像规格价格,规格库存等信息没有体现,那么这部分数据在哪里呢?它们存放在另一个对象 list 中,如下所示。

list: [
  {
    s1: 1,
    price: 280000,
    stock_num: 5
  },
  {
    s1: 2,
    price: 320000,
    stock_num: 5
  }
]

那么问题来了,list 中的对象如何跟 v 中的对象进行关联呢?这就需要用到 k_s,它的作用就是映射 listv 的,我们可以看到 k_s 的值为 s1,那么映射关系就是 v 中的 idlist 中的 s1 进行关联,相等则认为是同一组数据,搞清楚这个关系之后,再使用 Sku 组件就得心应手了,这里需要注意的是 listprice 属性的单位为分,我们在使用时需要注意单位转换,把分转换成元,具体结果如下图所示。

3、创建地址列表 AddressList.vue

这里我们使用 AddressList 组件来完成,代码如下所示。

<van-address-list
        v-model="chosenAddressId"
        :list="list"
        default-tag-text="默认"
        @add="onAdd"
        @edit="onEdit"
        @select="onselect"
/>

list: [
    {
        areaCode: "440303",
        id: 21,
        name: "张三",
        tel: "13678787878",
        address: "广东省深圳市罗湖区科技路123号456室"
    },
    {
        areaCode: "330104",
        id: 22,
        name: "小明",
        tel: "13636363636",
        address: "浙江省杭州市江干区789号"
    }
]

v-model 表示选中的地址编号,list 表示要遍历的数据集合,default-tag-text 表示默认地址标签文字,@add 表示添加按钮绑定的方法,@edit 表示编辑按钮绑定的方法,@select 表示选中按钮绑定的方法,结果如下图所示。

4、创建新增地址 AddressNew.vue

这里我们使用 AddressEdit 组件,代码如下所示。

<van-address-edit
        :area-list="areaList"
        show-delete
        @save="onSave"
        @delete="onDelete"
/>

show-delete 表示是否添加删除按钮,ture 表示添加,false 表示不添加,默认值为 true@save@delete 分别为保存按钮和删除按钮所绑定的函数。

area-list 为绑定的省市区数据集合,官网提供了完整的数据,直接使用即可,网址:https://github.com/youzan/vant/blob/dev/src/area/demo/area.js (opens new window),具体结果如下图所示。

5、创建修改地址 AddressEdit.vue

修改地址和新增地址使用同一个组件,唯一区别在于修改地址需要有默认数据,代码如下所示。

<van-address-edit
        :area-list="areaList"
        show-delete
        :address-info="addressInfo"
        save-button-text="修改"
        @save="onSave"
        @delete="onDelete"
/>

addressInfo: {
    name: '张三',
    tel: '13333333333',
    areaCode: '130105',
    addressDetail: '浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室'
}

address-info 为默认回填的数据,save-button-text 表示保存按钮所显示的文本,这里我们设置为“修改”即可。

6、创建订单详情 Detail.vue

这里需要结合 van-cellvan-cardvan-submit-bar 等多个组件来完成,具体代码如下所示。

<van-cell-group class="goods-cell-group">
    <van-cell>
        <van-col span="16"><van-icon name="location-o" style="margin-right: 30px;" />收货人:{{data.buyerName}}</van-col>
        <van-col>{{data.tel}}</van-col>
        <van-col span="21" style="padding-left: 43px;font-size: 13px">收货地址:{{data.address}}</van-col>
    </van-cell>
</van-cell-group>
<van-card
        :num="data.num"
        :price="data.price"
        :desc="data.specs"
        :title="data.phoneName"
        :thumb="data.icon"
/>
<van-cell-group class="goods-cell-group">
    <van-cell class="goods-express">
        <van-col span="21">配送方式</van-col>
        <van-col>快递</van-col>
    </van-cell>
</van-cell-group>
<van-cell-group class="goods-cell-group">
    <van-cell class="goods-express" style="font-weight: bold">
        <van-col span="20">商品金额</van-col>
        <van-col style="color: red">¥{{data.amount}}</van-col>
    </van-cell>
</van-cell-group>
<van-cell-group>
    <van-cell class="goods-express" style="font-weight: bold">
        <van-col span="20">运费</van-col>
        <van-col style="color: red">¥{{data.freight}}</van-col>
    </van-cell>
</van-cell-group>
<van-submit-bar
        :price="data.amount*100+data.freight*100"
        button-text="确认付款"
        @submit="onSubmit"
/>
data:{
    orderId: "1586242977480760998",
    buyerName: "小明",
    phoneName: "Honor 8A",
    payStatus: 0,
    freight: 10,
    tel: "13636363636",
    address: "浙江省杭州市江干区789号",
    num: 1,
    specs: "32GB",
    price: "2800.00",
    icon: "../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg",
    amount: 2800
}

这里需要说明的是 van-submit-bar 组件 price 属性的单位为分,所以我们在使用时需要注意单位的换算(分换算成元),否则会出现价格错误的问题,结果如下所示。

以上就是 Vue 工程中几个核心页面的搭建方式,其他页面搭建方式与之类似,这里我们就不再赘述,搞定了 Vue 工程,接下来咱们学习 Spring Boot 工程的搭建。

# 创建 Spring Boot 工程

1、我们是基于最新版 Spring Boot 2.2.6,在 IDEA 中使用 Spring Initializr 组件来创建工程,分别选择自动导入 LombokSpring WebSpring Data JPAMySQL Driver 依赖,如下图所示。

2、创建数据表,SQL 如下所示。

DROP TABLE IF EXISTS `buyer_address`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `buyer_address` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `buyer_name` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '买家名字',
  `buyer_phone` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '买家电话',
  `buyer_address` varchar(128) COLLATE utf8mb4_general_ci NOT NULL COMMENT '买家地址',
  `area_code` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '地址编码',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='收货地址表';

DROP TABLE IF EXISTS `order_master`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `order_master` (
  `order_id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL,
  `buyer_name` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '买家名字',
  `buyer_phone` varchar(32) COLLATE utf8mb4_general_ci NOT NULL COMMENT '买家电话',
  `buyer_address` varchar(128) COLLATE utf8mb4_general_ci NOT NULL COMMENT '买家地址',
  `phone_id` int(11) DEFAULT NULL COMMENT '商品编号',
  `phone_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品名称',
  `phone_quantity` int(11) DEFAULT NULL COMMENT '商品数量',
  `phone_icon` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '商品小图',
  `specs_id` int(11) DEFAULT NULL COMMENT '规格编号',
  `specs_name` varchar(32) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '规格名称',
  `specs_price` decimal(8,2) DEFAULT NULL COMMENT '规格单价',
  `order_amount` decimal(8,2) NOT NULL COMMENT '订单总金额',
  `pay_status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '支付状态,默认0未支付',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='订单表';

DROP TABLE IF EXISTS `phone_category`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `phone_category` (
  `category_id` int(11) NOT NULL AUTO_INCREMENT,
  `category_name` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '类目名称',
  `category_type` int(11) NOT NULL COMMENT '类目编号',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  PRIMARY KEY (`category_id`),
  UNIQUE KEY `uqe_category_type` (`category_type`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='类目表';

LOCK TABLES `phone_category` WRITE;
/*!40000 ALTER TABLE `phone_category` DISABLE KEYS */;
INSERT INTO `phone_category` VALUES (1,'魅焰红',1,'2020-04-01 10:39:43','2020-04-01 12:35:54'),(2,'极光蓝',2,'2020-04-01 10:39:43','2020-04-01 12:35:54'),(3,'铂光金',3,'2020-04-01 10:39:43','2020-04-01 12:35:54'),(4,'幻夜黑',4,'2020-04-01 10:39:43','2020-04-01 12:35:54');
/*!40000 ALTER TABLE `phone_category` ENABLE KEYS */;
UNLOCK TABLES;

DROP TABLE IF EXISTS `phone_info`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `phone_info` (
  `phone_id` int(11) NOT NULL AUTO_INCREMENT,
  `phone_name` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '商品名称',
  `phone_price` decimal(8,2) NOT NULL COMMENT '商品单价',
  `phone_description` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '描述',
  `phone_stock` int(11) NOT NULL COMMENT '库存',
  `phone_icon` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '小图',
  `category_type` int(11) NOT NULL COMMENT '类目编号',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `phone_tag` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标签',
  PRIMARY KEY (`phone_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='商品表';
/*!40101 SET character_set_client = @saved_cs_client */;

LOCK TABLES `phone_info` WRITE;
/*!40000 ALTER TABLE `phone_info` DISABLE KEYS */;
INSERT INTO `phone_info` VALUES (1,'Honor 8A',2800.00,'魅焰红',2,'../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg',1,'2020-04-01 10:03:08','2020-04-10 09:20:41','720P珍珠屏&Micro USB接口'),(2,'Honor 10 青春版',2800.00,'极光蓝',100,'../static/8f0bd0d0-a11e-4185-927e-04b54ff4a1bd.jpg',2,'2020-04-01 10:03:08','2020-04-01 14:30:42','720P珍珠屏&EMUI9 Lite'),(3,'Honor V20',3450.00,'铂光金',100,'../static/fd7fee3c-a35c-477b-b007-9fda6e9c589a.jpg',3,'2020-04-01 10:14:54','2020-04-01 14:30:42','2+1独立三卡槽'),(4,'HUAWEI Mate 20 Pro',4550.00,'幻夜黑',100,'../static/cb819ad9-ec6f-4123-a4e9-aa629e2f8224.jpg',4,'2020-04-01 10:14:54','2020-04-01 14:30:42','内存3GB&EMUI9 Lite'),(5,'HUAWEI nova 5 Pro',5450.00,'魅焰红',100,'../static/8a0f5be0-3c78-4f23-b58b-dc2a92f1f95a.jpg',1,'2020-04-01 10:14:54','2020-04-01 14:30:42','内存3GB&Micro USB接口'),(6,'HUAWEI P30',8700.00,'极光蓝',100,'../static/6dcad185-315f-40f0-87f2-52910f49c8b7.jpg',2,'2020-04-01 10:14:54','2020-04-01 14:30:42','720P珍珠屏&内存3GB'),(7,'HUAWEI P30 Pro',8988.00,'铂光金',100,'../static/b12a46a9-3738-49ab-ab3a-6878539bd76b.jpg',3,'2020-04-01 10:14:54','2020-04-01 14:30:42','720P珍珠屏&Micro USB接口'),(8,'HUAWEI 畅想9 Plus',2760.00,'幻夜黑',100,'../static/15a5dcf2-4b50-41a0-93e8-08df97c21341.jpg',4,'2020-04-01 10:14:54','2020-04-01 14:30:42','内存3GB&存储32GB'),(9,'SAMSUNG G S10',7254.00,'魅焰红',100,'../static/a4f0cef8-59da-4f7c-abfa-d373f6648035.jpg',1,'2020-04-01 10:14:54','2020-04-01 14:30:42','720P珍珠屏&存储32GB'),(10,'OPPO K3',2889.00,'极光蓝',100,'../static/efc31538-a1f0-4dba-a673-4369f17e5708.jpg',2,'2020-04-01 10:14:54','2020-04-01 14:30:42','存储32GB&Micro USB接口'),(11,'Iphone XR',9888.00,'铂光金',100,'../static/4ef5a3c0-ad88-495f-a6bc-a31c1dde667b.jpg',3,'2020-04-01 10:14:54','2020-04-01 14:30:42','1300万像素&Micro USB接口'),(12,'MI 8',5888.00,'幻夜黑',100,'../static/aff8224c-3196-42a9-ae9e-4f06e20555c4.jpg',4,'2020-04-01 10:14:54','2020-04-01 14:30:42','内存3GB&存储32GB'),(13,'VIVO X27',2888.00,'魅焰红',100,'../static/cdf065ec-e409-4204-93e6-600e172e461a.jpg',1,'2020-04-01 10:14:54','2020-04-01 14:30:42','F/1.8光圈&Micro USB接口'),(14,'Iphone 6',5678.00,'极光蓝',100,'../static/899a9c64-62d0-416d-b320-e730b4585cb0.jpg',2,'2020-04-01 10:14:54','2020-04-01 14:30:42','720P珍珠屏&F/1.8光圈'),(15,'Iphone 7',5576.00,'铂光金',100,'../static/67aa6e9b-681f-4a6f-aae4-97eb3ec51b08.jpg',3,'2020-04-01 10:14:54','2020-04-01 14:30:42','720P珍珠屏&1300万像素'),(16,'Iphone 8',6212.00,'幻夜黑',100,'../static/a8b5b846-7fbb-4e7b-abcf-01ae73979000.jpg',4,'2020-04-01 10:14:54','2020-04-01 14:30:42','内存3GB&F/1.8光圈'),(17,'Meizu 16s',1220.00,'魅焰红',100,'../static/1a2b8e30-6e98-405f-9a18-9cd31ff96c35.jpg',1,'2020-04-01 10:14:54','2020-04-01 14:30:42','720P珍珠屏&Micro USB接口'),(18,'Iphone X',6770.00,'极光蓝',100,'../static/39197368-aeaf-48ea-b399-5ad65f7b6c47.jpg',2,'2020-04-01 10:14:54','2020-04-01 14:30:42','F/1.8光圈&Micro USB接口'),(19,'HUAWEI P20',5580.00,'铂光金',100,'../static/f382351b-7fc8-4b34-bcce-162085e75191.jpg',3,'2020-04-01 10:14:54','2020-04-01 14:30:42','1300万像素&Micro USB接口');
/*!40000 ALTER TABLE `phone_info` ENABLE KEYS */;
UNLOCK TABLES;

DROP TABLE IF EXISTS `phone_specs`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
 SET character_set_client = utf8mb4 ;
CREATE TABLE `phone_specs` (
  `specs_id` int(11) NOT NULL AUTO_INCREMENT,
  `phone_id` varchar(32) COLLATE utf8mb4_general_ci NOT NULL,
  `specs_name` varchar(64) COLLATE utf8mb4_general_ci NOT NULL COMMENT '规格名称',
  `specs_stock` int(11) NOT NULL COMMENT '库存',
  `specs_price` decimal(8,2) NOT NULL COMMENT '单价',
  `specs_icon` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '小图',
  `specs_preview` varchar(512) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '预览图',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`specs_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='商品规格表';
/*!40101 SET character_set_client = @saved_cs_client */;

LOCK TABLES `phone_specs` WRITE;
/*!40000 ALTER TABLE `phone_specs` DISABLE KEYS */;
INSERT INTO `phone_specs` VALUES (1,'1','32GB',0,280000.00,'../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg','../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg','2020-04-10 09:20:36','2020-04-01 14:16:36'),(2,'1','64GB',2,320000.00,'../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg','../static/e84a2e03-7f19-41d2-98a5-a5c16b7e252d.jpg','2020-04-07 10:06:22','2020-04-01 14:16:36');
/*!40000 ALTER TABLE `phone_specs` ENABLE KEYS */;
UNLOCK TABLES;

3、配置文件 application.yml 如下所示

server:
  port: 8181
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/phone_store_demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    show-sql: true
    properties:
      hibernate:
        format_sql: true

4、根据接口文档编写业务代码,文档如下所示。

5、Vue 直接调用 Spring Boot 的业务接口会存在跨越问题,我们可以在 Spring Boot 中添加配置类来解决,代码如下所示。

package com.southwind.phone_store_demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
                .allowCredentials(true)
                .maxAge(3600)
                .allowedHeaders("*");
    }
}

6、源码链接

Vue

https://github.com/southwind9801/phone_store_demo_vue.git (opens new window)

Spring Boot

https://github.com/southwind9801/phone_store_demo_springboot.git (opens new window)

这样我们就完成了 Spring Boot + Vue 移动端商城的开发,配套视频教程已上传至 B 站,扫描下方二维码直接观看。