5.项目代码

5.1.前端代码

5.1.1.Index组件

注意点:

  1. 修改图片路径,包括css中背景图片路径
  2. style中添加scoped。
  3. 将静态工程中的 icon.css内容添加到style中。
  1. <template>
  2. <div class="wrapper">
  3. <!-- header部分 -->
  4. <header>
  5. <div class="icon-location-box">
  6. <div class="icon-location"></div>
  7. </div>
  8. <div class="location-text">沈阳市规划大厦<i class="fa fa-caret-down"></i></div>
  9. </header>
  10. <!-- search部分 -->
  11. <!--
  12. 搜索框部分(此块与search-fixed-top块宽度高度一致,用于当
  13. search-fixed-top块固定后,挡住下面块不要窜上去)
  14. -->
  15. <div class="search">
  16. <!-- 当滚动条超过上面的定位块时,search-fixed-top块变成固定在顶部。 -->
  17. <div class="search-fixed-top" ref="fixedBox">
  18. <!-- 搜索框部分中间的白框 -->
  19. <div class="search-box">
  20. <i class="fa fa-search"></i>搜索饿了么商家、商品名称
  21. </div>
  22. </div>
  23. </div>
  24. <!-- 点餐分类部分 -->
  25. <ul class="foodtype">
  26. <li @click="toBusinessList(1)">
  27. <img src="../assets/dcfl01.png">
  28. <p>美食</p>
  29. </li>
  30. <li @click="toBusinessList(2)">
  31. <img src="../assets/dcfl02.png">
  32. <p>早餐</p>
  33. </li>
  34. <li @click="toBusinessList(3)">
  35. <img src="../assets/dcfl03.png">
  36. <p>跑腿代购</p>
  37. </li>
  38. <li @click="toBusinessList(4)">
  39. <img src="../assets/dcfl04.png">
  40. <p>汉堡披萨</p>
  41. </li>
  42. <li @click="toBusinessList(5)">
  43. <img src="../assets/dcfl05.png">
  44. <p>甜品饮品</p>
  45. </li>
  46. <li @click="toBusinessList(6)">
  47. <img src="../assets/dcfl06.png">
  48. <p>速食简餐</p>
  49. </li>
  50. <li @click="toBusinessList(7)">
  51. <img src="../assets/dcfl07.png">
  52. <p>地方小吃</p>
  53. </li>
  54. <li @click="toBusinessList(8)">
  55. <img src="../assets/dcfl08.png">
  56. <p>米粉面馆</p>
  57. </li>
  58. <li @click="toBusinessList(9)">
  59. <img src="../assets/dcfl09.png">
  60. <p>包子粥铺</p>
  61. </li>
  62. <li @click="toBusinessList(10)">
  63. <img src="../assets/dcfl10.png">
  64. <p>炸鸡炸串</p>
  65. </li>
  66. </ul>
  67. <!-- 横幅广告部分(注意:此处有背景图片) -->
  68. <div class="banner">
  69. <h3>品质套餐</h3>
  70. <p>搭配齐全吃得好</p>
  71. <a>立即抢购 &gt;</a>
  72. </div>
  73. <!-- 超级会员部分 -->
  74. <div class="supermember">
  75. <div class="left">
  76. <img src="../assets/super_member.png">
  77. <h3>超级会员</h3>
  78. <p>&#8226; 每月享超值权益</p>
  79. </div>
  80. <div class="right">
  81. 立即开通 &gt;
  82. </div>
  83. </div>
  84. <!-- 推荐商家部分 -->
  85. <div class="recommend">
  86. <div class="recommend-line"></div>
  87. <p>推荐商家</p>
  88. <div class="recommend-line"></div>
  89. </div>
  90. <!-- 推荐方式部分 -->
  91. <ul class="recommendtype">
  92. <li>综合排序<i class="fa fa-caret-down"></i></li>
  93. <li>距离最近</li>
  94. <li>销量最高</li>
  95. <li>筛选<i class="fa fa-filter"></i></li>
  96. </ul>
  97. <!-- 推荐商家列表部分 -->
  98. <ul class="business">
  99. <li>
  100. <img src="../assets/sj01.png">
  101. <div class="business-info">
  102. <div class="business-info-h">
  103. <h3>万家饺子(软件园E18店)</h3>
  104. <div class="business-info-like">&#8226;</div>
  105. </div>
  106. <div class="business-info-star">
  107. <div class="business-info-star-left">
  108. <i class="fa fa-star"></i>
  109. <i class="fa fa-star"></i>
  110. <i class="fa fa-star"></i>
  111. <i class="fa fa-star"></i>
  112. <i class="fa fa-star"></i>
  113. <p>4.9 月售345单</p>
  114. </div>
  115. <div class="business-info-star-right">
  116. 蜂鸟专送
  117. </div>
  118. </div>
  119. <div class="business-info-delivery">
  120. <p>&#165;15起送 | &#165;3配送</p>
  121. <p>3.22km | 30分钟</p>
  122. </div>
  123. <div class="business-info-explain">
  124. <div>各种饺子</div>
  125. </div>
  126. <div class="business-info-promotion">
  127. <div class="business-info-promotion-left">
  128. <div class="business-info-promotion-left-incon"></div>
  129. <p>饿了么新用户首单立减9元</p>
  130. </div>
  131. <div class="business-info-promotion-right">
  132. <p>2个活动</p>
  133. <i class="fa fa-caret-down"></i>
  134. </div>
  135. </div>
  136. <div class="business-info-promotion">
  137. <div class="business-info-promotion-left">
  138. <div class="business-info-promotion-left-incon" style="background-color: #F1884F;"></div>
  139. <p>特价商品5元起</p>
  140. </div>
  141. </div>
  142. </div>
  143. </li>
  144. <li>
  145. <img src="../assets/sj02.png">
  146. <div class="business-info">
  147. <div class="business-info-h">
  148. <h3>小锅饭豆腐馆(全运店)</h3>
  149. <div class="business-info-like">&#8226;</div>
  150. </div>
  151. <div class="business-info-star">
  152. <div class="business-info-star-left">
  153. <i class="fa fa-star"></i>
  154. <i class="fa fa-star"></i>
  155. <i class="fa fa-star"></i>
  156. <i class="fa fa-star"></i>
  157. <i class="fa fa-star"></i>
  158. <p>4.9 月售345单</p>
  159. </div>
  160. <div class="business-info-star-right">
  161. 蜂鸟专送
  162. </div>
  163. </div>
  164. <div class="business-info-delivery">
  165. <p>&#165;15起送 | &#165;3配送</p>
  166. <p>3.22km | 30分钟</p>
  167. </div>
  168. <div class="business-info-explain">
  169. <div>各种饺子</div>
  170. </div>
  171. <div class="business-info-promotion">
  172. <div class="business-info-promotion-left">
  173. <div class="business-info-promotion-left-incon"></div>
  174. <p>饿了么新用户首单立减9元</p>
  175. </div>
  176. <div class="business-info-promotion-right">
  177. <p>2个活动</p>
  178. <i class="fa fa-caret-down"></i>
  179. </div>
  180. </div>
  181. <div class="business-info-promotion">
  182. <div class="business-info-promotion-left">
  183. <div class="business-info-promotion-left-incon"></div>
  184. <p>特价商品5元起</p>
  185. </div>
  186. </div>
  187. </div>
  188. </li>
  189. <li>
  190. <img src="../assets/sj03.png">
  191. <div class="business-info">
  192. <div class="business-info-h">
  193. <h3>麦当劳麦乐送(全运路店)</h3>
  194. <div class="business-info-like">&#8226;</div>
  195. </div>
  196. <div class="business-info-star">
  197. <div class="business-info-star-left">
  198. <i class="fa fa-star"></i>
  199. <i class="fa fa-star"></i>
  200. <i class="fa fa-star"></i>
  201. <i class="fa fa-star"></i>
  202. <i class="fa fa-star"></i>
  203. <p>4.9 月售345单</p>
  204. </div>
  205. <div class="business-info-star-right">
  206. 蜂鸟专送
  207. </div>
  208. </div>
  209. <div class="business-info-delivery">
  210. <p>&#165;15起送 | &#165;3配送</p>
  211. <p>3.22km | 30分钟</p>
  212. </div>
  213. <div class="business-info-explain">
  214. <div>各种饺子</div>
  215. </div>
  216. <div class="business-info-promotion">
  217. <div class="business-info-promotion-left">
  218. <div class="business-info-promotion-left-incon"></div>
  219. <p>饿了么新用户首单立减9元</p>
  220. </div>
  221. <div class="business-info-promotion-right">
  222. <p>2个活动</p>
  223. <i class="fa fa-caret-down"></i>
  224. </div>
  225. </div>
  226. <div class="business-info-promotion">
  227. <div class="business-info-promotion-left">
  228. <div class="business-info-promotion-left-incon"></div>
  229. <p>特价商品5元起</p>
  230. </div>
  231. </div>
  232. </div>
  233. </li>
  234. <li>
  235. <img src="../assets/sj04.png">
  236. <div class="business-info">
  237. <div class="business-info-h">
  238. <h3>米村拌饭(浑南店)</h3>
  239. <div class="business-info-like">&#8226;</div>
  240. </div>
  241. <div class="business-info-star">
  242. <div class="business-info-star-left">
  243. <i class="fa fa-star"></i>
  244. <i class="fa fa-star"></i>
  245. <i class="fa fa-star"></i>
  246. <i class="fa fa-star"></i>
  247. <i class="fa fa-star"></i>
  248. <p>4.9 月售345单</p>
  249. </div>
  250. <div class="business-info-star-right">
  251. 蜂鸟专送
  252. </div>
  253. </div>
  254. <div class="business-info-delivery">
  255. <p>&#165;15起送 | &#165;3配送</p>
  256. <p>3.22km | 30分钟</p>
  257. </div>
  258. <div class="business-info-explain">
  259. <div>各种饺子</div>
  260. </div>
  261. <div class="business-info-promotion">
  262. <div class="business-info-promotion-left">
  263. <div class="business-info-promotion-left-incon"></div>
  264. <p>饿了么新用户首单立减9元</p>
  265. </div>
  266. <div class="business-info-promotion-right">
  267. <p>2个活动</p>
  268. <i class="fa fa-caret-down"></i>
  269. </div>
  270. </div>
  271. <div class="business-info-promotion">
  272. <div class="business-info-promotion-left">
  273. <div class="business-info-promotion-left-incon"></div>
  274. <p>特价商品5元起</p>
  275. </div>
  276. </div>
  277. </div>
  278. </li>
  279. <li>
  280. <img src="../assets/sj05.png">
  281. <div class="business-info">
  282. <div class="business-info-h">
  283. <h3>申记串道(中海康城店)</h3>
  284. <div class="business-info-like">&#8226;</div>
  285. </div>
  286. <div class="business-info-star">
  287. <div class="business-info-star-left">
  288. <i class="fa fa-star"></i>
  289. <i class="fa fa-star"></i>
  290. <i class="fa fa-star"></i>
  291. <i class="fa fa-star"></i>
  292. <i class="fa fa-star"></i>
  293. <p>4.9 月售345单</p>
  294. </div>
  295. <div class="business-info-star-right">
  296. 蜂鸟专送
  297. </div>
  298. </div>
  299. <div class="business-info-delivery">
  300. <p>&#165;15起送 | &#165;3配送</p>
  301. <p>3.22km | 30分钟</p>
  302. </div>
  303. <div class="business-info-explain">
  304. <div>各种饺子</div>
  305. </div>
  306. <div class="business-info-promotion">
  307. <div class="business-info-promotion-left">
  308. <div class="business-info-promotion-left-incon"></div>
  309. <p>饿了么新用户首单立减9元</p>
  310. </div>
  311. <div class="business-info-promotion-right">
  312. <p>2个活动</p>
  313. <i class="fa fa-caret-down"></i>
  314. </div>
  315. </div>
  316. <div class="business-info-promotion">
  317. <div class="business-info-promotion-left">
  318. <div class="business-info-promotion-left-incon"></div>
  319. <p>特价商品5元起</p>
  320. </div>
  321. </div>
  322. </div>
  323. </li>
  324. </ul>
  325. <!-- 底部菜单部分 -->
  326. <Footer></Footer>
  327. </div>
  328. </template>
  329. <script>
  330. //导入共通组件
  331. import Footer from '../components/Footer.vue';
  332. export default {
  333. name: 'Index',
  334. mounted() {
  335. document.onscroll = ()=> {
  336. //获取滚动条位置
  337. let s1 = document.documentElement.scrollTop;
  338. let s2 = document.body.scrollTop;
  339. let scroll = s1 == 0 ? s2 : s1;
  340. //获取视口宽度
  341. let width = document.documentElement.clientWidth;
  342. //获取顶部固定块
  343. let search = this.$refs.fixedBox;
  344. //判断滚动条超过视口宽度的12%时,搜索块变固定定位
  345. if (scroll > width * 0.12) {
  346. search.style.position = 'fixed';
  347. search.style.left = '0';
  348. search.style.top = '0';
  349. } else {
  350. search.style.position = 'static';
  351. }
  352. }
  353. },
  354. destroyed() {
  355. //当切换到其他组件时,就不需要document滚动条事件,所以将此事件去掉
  356. document.onscroll = null;
  357. },
  358. components:{
  359. Footer
  360. },
  361. methods:{
  362. toBusinessList(orderTypeId){
  363. this.$router.push({path:'/businessList',query:{orderTypeId:orderTypeId}});
  364. }
  365. }
  366. }
  367. </script>
  368. <style scoped>
  369. /****************** 总容器 ******************/
  370. .wrapper {
  371. width: 100%;
  372. height: 100%;
  373. }
  374. /****************** header ******************/
  375. .wrapper header {
  376. width: 100%;
  377. height: 12vw;
  378. background-color: #0097FF;
  379. display: flex;
  380. align-items: center;
  381. }
  382. .wrapper header .icon-location-box {
  383. width: 3.5vw;
  384. height: 3.5vw;
  385. margin: 0 1vw 0 3vw;
  386. }
  387. .wrapper header .location-text {
  388. font-size: 4.5vw;
  389. font-weight: 700;
  390. color: #fff;
  391. }
  392. .wrapper header .location-text .fa-caret-down {
  393. margin-left: 1vw;
  394. }
  395. /****************** search ******************/
  396. .wrapper .search {
  397. width: 100%;
  398. height: 13vw;
  399. }
  400. .wrapper .search .search-fixed-top {
  401. width: 100%;
  402. height: 13vw;
  403. background-color: #0097FF;
  404. display: flex;
  405. justify-content: center;
  406. align-items: center;
  407. }
  408. .wrapper .search .search-fixed-top .search-box {
  409. width: 90%;
  410. height: 9vw;
  411. background-color: #fff;
  412. border-radius: 2px;
  413. display: flex;
  414. justify-content: center;
  415. align-items: center;
  416. font-size: 3.5vw;
  417. color: #AEAEAE;
  418. font-family: "宋体";
  419. /*此样式是让文本选中状态无效*/
  420. user-select: none;
  421. }
  422. .wrapper .search .search-fixed-top .search-box .fa-search {
  423. margin-right: 1vw;
  424. }
  425. /****************** 点餐分类部分 ******************/
  426. .wrapper .foodtype {
  427. width: 100%;
  428. height: 48vw;
  429. display: flex;
  430. flex-wrap: wrap;
  431. justify-content: space-around;
  432. /*要使用align-content。10个子元素将自动换行为两行,而且两行作为一个整体垂直居中*/
  433. align-content: center;
  434. }
  435. .wrapper .foodtype li {
  436. /*一共10个子元素,通过计算,子元素宽度在16.7 ~ 20 之间,才能保证换两行*/
  437. width: 18vw;
  438. height: 20vw;
  439. display: flex;
  440. /*弹性盒子主轴方向设为column,然后仍然是垂直水平方向居中*/
  441. flex-direction: column;
  442. justify-content: center;
  443. align-items: center;
  444. user-select: none;
  445. cursor: pointer;
  446. }
  447. .wrapper .foodtype li img {
  448. width: 12vw;
  449. /*视频讲解时高度设置为12vw,实际上设置为10.3vw更佳*/
  450. height: 10.3vw;
  451. }
  452. .wrapper .foodtype li p {
  453. font-size: 3.2vw;
  454. color: #666;
  455. }
  456. /****************** 横幅广告部分 ******************/
  457. .wrapper .banner {
  458. /**
  459. * 设置容器宽度95%,然后水平居中,这样两边留白;
  460. * 这里不能用padding,因为背景图片也会覆盖padding
  461. */
  462. width: 95%;
  463. margin: 0 auto;
  464. height: 29vw;
  465. /*此三个样式组合,可以保证背景图片充满整个容器*/
  466. background-image: url(../assets/index_banner.png);
  467. background-repeat: no-repeat;
  468. background-size: cover;
  469. box-sizing: border-box;
  470. padding: 2vw 6vw;
  471. }
  472. .wrapper .banner h3 {
  473. font-size: 4.2vw;
  474. margin-bottom: 1.2vw;
  475. }
  476. .wrapper .banner p {
  477. font-size: 3.4vw;
  478. color: #666;
  479. margin-bottom: 2.4vw;
  480. }
  481. .wrapper .banner a {
  482. font-size: 3vw;
  483. color: #C79060;
  484. font-weight: 700;
  485. }
  486. /****************** 超级会员部分 ******************/
  487. .wrapper .supermember {
  488. /*这里也设置容器宽度95%,不能用padding,因为背景色也会充满padding*/
  489. width: 95%;
  490. margin: 0 auto;
  491. height: 11.5vw;
  492. background-color: #FEEDC1;
  493. margin-top: 1.3vw;
  494. border-radius: 2px;
  495. color: #644F1B;
  496. display: flex;
  497. justify-content: space-between;
  498. align-items: center;
  499. }
  500. .wrapper .supermember .left {
  501. display: flex;
  502. align-items: center;
  503. margin-left: 4vw;
  504. user-select: none;
  505. }
  506. .wrapper .supermember .left img {
  507. width: 6vw;
  508. height: 6vw;
  509. margin-right: 2vw;
  510. }
  511. .wrapper .supermember .left h3 {
  512. font-size: 4vw;
  513. margin-right: 2vw;
  514. }
  515. .wrapper .supermember .left p {
  516. font-size: 3vw;
  517. }
  518. .wrapper .supermember .right {
  519. font-size: 3vw;
  520. margin-right: 4vw;
  521. cursor: pointer;
  522. }
  523. /****************** 推荐商家部分 ******************/
  524. .wrapper .recommend {
  525. width: 100%;
  526. height: 14vw;
  527. display: flex;
  528. justify-content: center;
  529. align-items: center;
  530. }
  531. .wrapper .recommend .recommend-line {
  532. width: 6vw;
  533. height: 0.2vw;
  534. background-color: #888;
  535. }
  536. .wrapper .recommend p {
  537. font-size: 4vw;
  538. margin: 0 4vw;
  539. }
  540. /****************** 推荐方式部分 ******************/
  541. .wrapper .recommendtype {
  542. width: 100%;
  543. height: 5vw;
  544. margin-bottom: 5vw;
  545. display: flex;
  546. justify-content: space-around;
  547. align-items: center;
  548. }
  549. .wrapper .recommendtype li {
  550. font-size: 3.5vw;
  551. color: #555;
  552. }
  553. /****************** 推荐商家列表部分 ******************/
  554. .wrapper .business {
  555. width: 100%;
  556. margin-bottom: 14vw;
  557. }
  558. .wrapper .business li {
  559. width: 100%;
  560. box-sizing: border-box;
  561. padding: 2.5vw;
  562. user-select: none;
  563. border-bottom: solid 1px #DDD;
  564. display: flex;
  565. }
  566. .wrapper .business li img {
  567. width: 18vw;
  568. height: 18vw;
  569. }
  570. .wrapper .business li .business-info {
  571. width: 100%;
  572. box-sizing: border-box;
  573. padding-left: 3vw;
  574. }
  575. .wrapper .business li .business-info .business-info-h {
  576. display: flex;
  577. justify-content: space-between;
  578. align-items: center;
  579. margin-bottom: 2vw;
  580. }
  581. .wrapper .business li .business-info .business-info-h h3 {
  582. font-size: 4vw;
  583. color: #333;
  584. }
  585. .wrapper .business li .business-info .business-info-h .business-info-like {
  586. width: 1.6vw;
  587. height: 3.4vw;
  588. background-color: #666;
  589. color: #fff;
  590. font-size: 4vw;
  591. margin-right: 4vw;
  592. display: flex;
  593. justify-content: center;
  594. align-items: center;
  595. }
  596. .wrapper .business li .business-info .business-info-star {
  597. display: flex;
  598. justify-content: space-between;
  599. align-items: center;
  600. margin-bottom: 2vw;
  601. font-size: 3.1vw;
  602. }
  603. .wrapper .business li .business-info .business-info-star .business-info-star-left {
  604. display: flex;
  605. align-items: center;
  606. }
  607. .wrapper .business li .business-info .business-info-star .business-info-star-left .fa-star {
  608. color: #FEC80E;
  609. margin-right: 0.5vw;
  610. }
  611. .wrapper .business li .business-info .business-info-star .business-info-star-left p {
  612. color: #666;
  613. margin-left: 1vw;
  614. }
  615. .wrapper .business li .business-info .business-info-star .business-info-star-right {
  616. background-color: #0097FF;
  617. color: #fff;
  618. font-size: 2.4vw;
  619. border-radius: 2px;
  620. padding: 0 0.6vw;
  621. }
  622. .wrapper .business li .business-info .business-info-delivery {
  623. display: flex;
  624. justify-content: space-between;
  625. align-items: center;
  626. margin-bottom: 2vw;
  627. color: #666;
  628. font-size: 3.1vw;
  629. }
  630. .wrapper .business li .business-info .business-info-explain {
  631. display: flex;
  632. align-items: center;
  633. margin-bottom: 3vw;
  634. }
  635. .wrapper .business li .business-info .business-info-explain div {
  636. border: solid 1px #DDD;
  637. font-size: 2.8vw;
  638. color: #666;
  639. border-radius: 3px;
  640. padding: 0 0.1vw;
  641. }
  642. .wrapper .business li .business-info .business-info-promotion {
  643. display: flex;
  644. justify-content: space-between;
  645. align-items: center;
  646. margin-bottom: 1.8vw;
  647. }
  648. .wrapper .business li .business-info .business-info-promotion .business-info-promotion-left {
  649. display: flex;
  650. align-items: center;
  651. }
  652. .wrapper .business li .business-info .business-info-promotion .business-info-promotion-left .business-info-promotion-left-incon {
  653. width: 4vw;
  654. height: 4vw;
  655. background-color: #70BC46;
  656. border-radius: 3px;
  657. font-size: 3vw;
  658. color: #fff;
  659. display: flex;
  660. justify-content: center;
  661. align-items: center;
  662. }
  663. .wrapper .business li .business-info .business-info-promotion .business-info-promotion-left p {
  664. color: #666;
  665. font-size: 3vw;
  666. margin-left: 2vw;
  667. }
  668. .wrapper .business li .business-info .business-info-promotion .business-info-promotion-right {
  669. display: flex;
  670. align-items: center;
  671. font-size: 2.5vw;
  672. color: #999;
  673. }
  674. .wrapper .business li .business-info .business-info-promotion .business-info-promotion-right p {
  675. margin-right: 2vw;
  676. }
  677. </style>

5.1.2.BusinessList组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>商家列表</p>
        </header>

        <!-- 商家列表部分 -->
        <ul class="business">
            <li v-for="item in businessArr" @click="toBusinessInfo(item.businessId)">
                <div class="business-img">
                    <img :src="item.businessImg">
                    <div class="business-img-quantity" v-show="item.quantity>0">{{item.quantity}}</div>
                </div>
                <div class="business-info">
                    <h3>{{item.businessName}}</h3>
                    <p>&#165;{{item.starPrice}}起送 | &#165;{{item.deliveryPrice}}配送</p>
                    <p>{{item.businessExplain}}</p>
                </div>
            </li>
        </ul>

        <!-- 底部菜单部分 -->
        <Footer></Footer>

    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default{
        name:'BusinessList',
        data(){
            return {
                orderTypeId: this.$route.query.orderTypeId,
                businessArr:[],
                user:{}
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');

            //根据orderTypeId查询商家信息
            this.$axios.post('BusinessController/listBusinessByOrderTypeId',this.$qs.stringify({
                orderTypeId:this.orderTypeId
            })).then(response=>{
                this.businessArr = response.data;
                //判断是否登录
                if(this.user!=null){
                    this.listCart();
                }
            }).catch(error=>{
                console.error(error);
            });
        },
        components:{
            Footer
        },
        methods:{
            listCart(){
                this.$axios.post('CartController/listCart',this.$qs.stringify({
                    userId:this.user.userId
                })).then(response=>{
                    let cartArr = response.data;
                    //遍历所有食品列表
                    for(let businessItem of this.businessArr){
                        businessItem.quantity = 0;
                        for(let cartItem of cartArr){
                            if(cartItem.businessId==businessItem.businessId){
                                businessItem.quantity += cartItem.quantity;
                            }
                        }
                    }
                    this.businessArr.sort();
                }).catch(error=>{
                    console.error(error);
                });
            },
            toBusinessInfo(businessId){
                this.$router.push({path:'/businessInfo',query:{businessId:businessId}});
            }
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 商家列表部分 ******************/
    .wrapper .business {
        width: 100%;
        margin-top: 12vw;
        margin-bottom: 14vw;
    }

    .wrapper .business li {
        width: 100%;
        box-sizing: border-box;
        padding: 2.5vw;
        border-bottom: solid 1px #DDD;
        user-select: none;
        cursor: pointer;

        display: flex;
        align-items: center;
    }

    .wrapper .business li .business-img {
        /*这里设置为相当定位,成为business-img-quantity元素的父元素*/
        position: relative;
    }

    .wrapper .business li .business-img img {
        width: 20vw;
        height: 20vw;
    }

    .wrapper .business li .business-img .business-img-quantity {
        width: 5vw;
        height: 5vw;
        background-color: red;
        color: #fff;
        font-size: 3.6vw;
        border-radius: 2.5vw;

        display: flex;
        justify-content: center;
        align-items: center;

        /*设置成绝对定位,不占文档流空间*/
        position: absolute;
        right: -1.5vw;
        top: -1.5vw;
    }

    .wrapper .business li .business-info {
        margin-left: 3vw;
    }

    .wrapper .business li .business-info h3 {
        font-size: 3.8vw;
        color: #555;
    }

    .wrapper .business li .business-info p {
        font-size: 3vw;
        color: #888;
        margin-top: 2vw;
    }
</style>

5.1.3.BusinessInfo组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>商家信息</p>
        </header>

        <!-- 商家logo部分 -->
        <div class="business-logo">
            <img :src="business.businessImg">
        </div>

        <!-- 商家信息部分 -->
        <div class="business-info">
            <h1>{{business.businessName}}</h1>
            <p>&#165;{{business.starPrice}}起送 &#165;{{business.deliveryPrice}}配送</p>
            <p>{{business.businessExplain}}</p>
        </div>

        <!-- 食品列表部分 -->
        <ul class="food">
            <li v-for="(item,index) in foodArr">
                <div class="food-left">
                    <img :src="item.foodImg">
                    <div class="food-left-info">
                        <h3>{{item.foodName}}</h3>
                        <p>{{item.foodExplain}}</p>
                        <p>&#165;{{item.foodPrice}}</p>
                    </div>
                </div>
                <div class="food-right">
                    <div>
                        <i class="fa fa-minus-circle" @click="minus(index)" v-show="item.quantity!=0"></i>
                    </div>
                    <p><span v-show="item.quantity!=0">{{item.quantity}}</span></p>
                    <div>
                        <i class="fa fa-plus-circle" @click="add(index)"></i>
                    </div>
                </div>
            </li>
        </ul>

        <!-- 购物车部分 -->
        <div class="cart">
            <div class="cart-left">
                <div class="cart-left-icon" :style="totalQuantity==0?'background-color:#505051;':'background-color:#3190E8;'">
                    <i class="fa fa-shopping-cart"></i>
                    <div class="cart-left-icon-quantity" v-show="totalQuantity!=0">{{totalQuantity}}</div>
                </div>
                <div class="cart-left-info">
                    <p>&#165;{{totalPrice}}</p>
                    <p>另需配送费{{business.deliveryPrice}}元</p>
                </div>
            </div>
            <div class="cart-right">
                <!-- 不够起送费 -->
                <div class="cart-right-item" v-show="totalSettle<business.starPrice" style="background-color: #535356;cursor: default;">
                    &#165;{{business.starPrice}}起送
                </div>
                <!-- 达到起送费 -->
                <div class="cart-right-item" @click="toOrder" v-show="totalSettle>=business.starPrice">
                    去结算
                </div>
            </div>
        </div>

    </div>
</template>

<script>
    export default {
        name: 'BusinessInfo',
        data() {
            return {
                businessId: this.$route.query.businessId,
                business: {},
                foodArr: [],
                user: {}
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');

            //根据businessId查询商家信息
            this.$axios.post('BusinessController/getBusinessById', this.$qs.stringify({
                businessId: this.businessId
            })).then(response => {
                this.business = response.data;
            }).catch(error => {
                console.error(error);
            });

            //根据businessId查询所属食品信息
            this.$axios.post('FoodController/listFoodByBusinessId', this.$qs.stringify({
                businessId: this.businessId
            })).then(response => {
                this.foodArr = response.data;
                for (let i = 0; i < this.foodArr.length; i++) {
                    this.foodArr[i].quantity = 0;
                }

                //如果已登录,那么需要去查询购物车中是否已经选购了某个食品
                if (this.user != null) {
                    this.listCart();
                }
            }).catch(error => {
                console.error(error);
            });
        },
        methods: {
            listCart() {
                this.$axios.post('CartController/listCart', this.$qs.stringify({
                    businessId: this.businessId,
                    userId: this.user.userId
                })).then(response => {
                    let cartArr = response.data;
                    //遍历所有食品列表
                    for (let foodItem of this.foodArr) {
                        foodItem.quantity = 0;
                        for (let cartItem of cartArr) {
                            if (cartItem.foodId == foodItem.foodId) {
                                foodItem.quantity = cartItem.quantity;
                            }
                        }
                    }
                    this.foodArr.sort();
                }).catch(error => {
                    console.error(error);
                });
            },
            add(index) {
                //首先做登录验证
                if (this.user == null) {
                    this.$router.push({
                        path: '/login'
                    });
                    return;
                }

                if (this.foodArr[index].quantity == 0) {
                    //做insert
                    this.savaCart(index);
                } else {
                    //做update
                    this.updateCart(index, 1);
                }
            },
            minus(index) {
                //首先做登录验证
                if (this.user == null) {
                    this.$router.push({
                        path: '/login'
                    });
                    return;
                }

                if (this.foodArr[index].quantity > 1) {
                    //做update
                    this.updateCart(index, -1);
                } else {
                    //做delete
                    this.removeCart(index);
                }
            },
            savaCart(index) {
                this.$axios.post('CartController/saveCart', this.$qs.stringify({
                    businessId: this.businessId,
                    userId: this.user.userId,
                    foodId: this.foodArr[index].foodId
                })).then(response => {
                    if (response.data == 1) {
                        //此食品数量要更新为1;
                        this.foodArr[index].quantity = 1;
                        this.foodArr.sort();
                    } else {
                        alert('向购物车中添加食品失败!');
                    }
                }).catch(error => {
                    console.error(error);
                });
            },
            updateCart(index, num) {
                this.$axios.post('CartController/updateCart', this.$qs.stringify({
                    businessId: this.businessId,
                    userId: this.user.userId,
                    foodId: this.foodArr[index].foodId,
                    quantity: this.foodArr[index].quantity + num
                })).then(response => {
                    if (response.data == 1) {
                        //此食品数量要更新为1或-1;
                        this.foodArr[index].quantity += num;
                        this.foodArr.sort();
                    } else {
                        alert('向购物车中更新食品失败!');
                    }
                }).catch(error => {
                    console.error(error);
                });
            },
            removeCart(index) {
                this.$axios.post('CartController/removeCart', this.$qs.stringify({
                    businessId: this.businessId,
                    userId: this.user.userId,
                    foodId: this.foodArr[index].foodId
                })).then(response => {
                    if (response.data == 1) {
                        //此食品数量要更新为0;视图的减号和数量要消失
                        this.foodArr[index].quantity = 0;
                        this.foodArr.sort();
                    } else {
                        alert('从购物车中删除食品失败!');
                    }
                }).catch(error => {
                    console.error(error);
                });
            },
            toOrder() {
                this.$router.push({
                    path: '/orders',
                    query: {
                        businessId: this.business.businessId
                    }
                });
            }
        },
        computed: {
            //食品总价格
            totalPrice() {
                let total = 0;
                for (let item of this.foodArr) {
                    total += item.foodPrice * item.quantity;
                }
                return total;
            },
            //食品总数量
            totalQuantity() {
                let quantity = 0;
                for (let item of this.foodArr) {
                    quantity += item.quantity;
                }
                return quantity;
            },
            //结算总价格
            totalSettle() {
                return this.totalPrice + this.business.deliveryPrice;
            }
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 商家logo部分 ******************/
    .wrapper .business-logo {
        width: 100%;
        height: 35vw;
        /*使用上外边距避开header部分*/
        margin-top: 12vw;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    .wrapper .business-logo img {
        width: 40vw;
        height: 30vw;
        border-radius: 5px;
    }

    /****************** 商家信息部分 ******************/
    .wrapper .business-info {
        width: 100%;
        height: 20vw;

        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
    }

    .wrapper .business-info h1 {
        font-size: 5vw;
    }

    .wrapper .business-info p {
        font-size: 3vw;
        color: #666;
        margin-top: 1vw;
    }

    /****************** 食品列表部分 ******************/
    .wrapper .food {
        width: 100%;
        /*使用下外边距避开footer部分*/
        margin-bottom: 14vw;
    }

    .wrapper .food li {
        width: 100%;
        box-sizing: border-box;
        padding: 2.5vw;
        user-select: none;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .food li .food-left {
        display: flex;
        align-items: center;
    }

    .wrapper .food li .food-left img {
        width: 20vw;
        height: 20vw;
    }

    .wrapper .food li .food-left .food-left-info {
        margin-left: 3vw;
    }

    .wrapper .food li .food-left .food-left-info h3 {
        font-size: 3.8vw;
        color: #555;
    }

    .wrapper .food li .food-left .food-left-info p {
        font-size: 3vw;
        color: #888;
        margin-top: 2vw;
    }

    .wrapper .food li .food-right {
        width: 16vw;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .food li .food-right .fa-minus-circle {
        font-size: 5.5vw;
        color: #999;
        cursor: pointer;
    }

    .wrapper .food li .food-right p {
        font-size: 3.6vw;
        color: #333;
    }

    .wrapper .food li .food-right .fa-plus-circle {
        font-size: 5.5vw;
        color: #0097EF;
        cursor: pointer;
    }

    /****************** 购物车部分 ******************/
    .wrapper .cart {
        width: 100%;
        height: 14vw;

        position: fixed;
        left: 0;
        bottom: 0;

        display: flex;
    }

    .wrapper .cart .cart-left {
        flex: 2;
        background-color: #505051;
        display: flex;
    }

    .wrapper .cart .cart-left .cart-left-icon {
        width: 16vw;
        height: 16vw;
        box-sizing: border-box;
        border: solid 1.6vw #444;
        border-radius: 8vw;
        background-color: #3190E8;
        font-size: 7vw;
        color: #fff;

        display: flex;
        justify-content: center;
        align-items: center;

        margin-top: -4vw;
        margin-left: 3vw;

        position: relative;
    }

    .wrapper .cart .cart-left .cart-left-icon-quantity {
        width: 5vw;
        height: 5vw;
        border-radius: 2.5vw;
        background-color: red;
        color: #fff;
        font-size: 3.6vw;

        display: flex;
        justify-content: center;
        align-items: center;

        position: absolute;
        right: -1.5vw;
        top: -1.5vw;
    }

    .wrapper .cart .cart-left .cart-left-info p:first-child {
        font-size: 4.5vw;
        color: #fff;
        margin-top: 1vw;
    }

    .wrapper .cart .cart-left .cart-left-info p:last-child {
        font-size: 2.8vw;
        color: #AAA;
    }

    .wrapper .cart .cart-right {
        flex: 1;
    }

    /*达到起送费时的样式*/
    .wrapper .cart .cart-right .cart-right-item {
        width: 100%;
        height: 100%;
        background-color: #38CA73;
        color: #fff;
        font-size: 4.5vw;
        font-weight: 700;
        user-select: none;
        cursor: pointer;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /*不够起送费时的样式(只有背景色和鼠标样式的区别)*/
    /*
    .wrapper .cart .cart-right .cart-right-item{
        width: 100%;
        height: 100%;
        background-color: #535356;
        color: #fff;
        font-size: 4.5vw;
        font-weight: 700;
        user-select: none;

        display: flex;
        justify-content: center;
        align-items: center;
    }
    */
</style>

5.1.4.Order组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>确认订单</p>
        </header>

        <!-- 订单信息部分 -->
        <div class="order-info">
            <h5>订单配送至:</h5>
            <div class="order-info-address" @click="toUserAddress">
                <p>{{deliveryaddress!=null?deliveryaddress.address:'请选择送货地址'}}</p>
                <i class="fa fa-angle-right"></i>
            </div>
            <p>{{user.userName}}{{user.userSex | sexFilter}} {{user.userId}}</p>
        </div>

        <h3>{{business.businessName}}</h3>

        <!-- 订单明细部分 -->
        <ul class="order-detailed">
            <li v-for="item in cartArr">
                <div class="order-detailed-left">
                    <img :src="item.food.foodImg">
                    <p>{{item.food.foodName}} x {{item.quantity}}</p>
                </div>
                <p>&#165;{{item.food.foodPrice*item.quantity}}</p>
            </li>
        </ul>
        <div class="order-deliveryfee">
            <p>配送费</p>
            <p>&#165;{{business.deliveryPrice}}</p>
        </div>

        <!-- 合计部分 -->
        <div class="total">
            <div class="total-left">
                &#165;{{totalPrice}}
            </div>
            <div class="total-right" @click="toPayment">
                去支付
            </div>
        </div>
    </div>
</template>

<script>
    export default{
        name:'Orders',
        data(){
            return {
                businessId:this.$route.query.businessId,
                business:{},
                user:{},
                cartArr:[],
                deliveryaddress:{}
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');
            this.deliveryaddress = this.$getLocalStorage(this.user.userId);

            //查询当前商家
            this.$axios.post('BusinessController/getBusinessById',this.$qs.stringify({
                businessId:this.businessId
            })).then(response=>{
                this.business = response.data;
            }).catch(error=>{
                console.error(error);
            });

            //查询当前用户在购物车中的当前商家食品列表
            this.$axios.post('CartController/listCart',this.$qs.stringify({
                userId:this.user.userId,
                businessId:this.businessId
            })).then(response=>{
                this.cartArr = response.data;
            }).catch(error=>{
                console.error(error);
            });
        },
        computed:{
            totalPrice(){
                let totalPrice = 0;
                for(let cartItem of this.cartArr){
                    totalPrice += cartItem.food.foodPrice*cartItem.quantity;
                }
                totalPrice += this.business.deliveryPrice;
                return totalPrice;
            }
        },
        filters:{
            sexFilter(value){
                return value==1?'先生':'女士';
            }
        },
        methods:{
            toUserAddress(){
                this.$router.push({path:'/userAddress',query:{businessId:this.businessId}});
            },
            toPayment(){
                if(this.deliveryaddress==null){
                    alert('请选择送货地址!');
                    return;
                }

                //创建订单
                this.$axios.post('OrdersController/createOrders',this.$qs.stringify({
                    userId:this.user.userId,
                    businessId:this.businessId,
                    daId:this.deliveryaddress.daId,
                    orderTotal:this.totalPrice
                })).then(response=>{
                    let orderId = response.data;
                    if(orderId>0){
                        this.$router.push({path:'/payment',query:{orderId:orderId}});
                    }else{
                        alert('创建订单失败!');
                    }
                }).catch(error=>{
                    console.error(error);
                });
            }
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 订单信息部分 ******************/
    .wrapper .order-info {
        /*注意这里,不设置高,靠内容撑开。因为地址有可能折行*/
        width: 100%;
        margin-top: 12vw;
        background-color: #0097EF;
        box-sizing: border-box;
        padding: 2vw;
        color: #fff;
    }

    .wrapper .order-info h5 {
        font-size: 3vw;
        font-weight: 300;
    }

    .wrapper .order-info .order-info-address {
        width: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;

        font-weight: 700;
        user-select: none;
        cursor: pointer;
        margin: 1vw 0;
    }

    .wrapper .order-info .order-info-address p {
        width: 90%;
        font-size: 5vw;
    }

    .wrapper .order-info .order-info-address i {
        font-size: 6vw;
    }

    .wrapper .order-info p {
        font-size: 3vw;
    }

    .wrapper h3 {
        box-sizing: border-box;
        padding: 3vw;
        font-size: 4vw;
        color: #666;
        border-bottom: solid 1px #DDD;
    }

    /****************** 订单明细部分 ******************/
    .wrapper .order-detailed {
        width: 100%;
    }

    .wrapper .order-detailed li {
        width: 100%;
        height: 16vw;
        box-sizing: border-box;
        padding: 3vw;
        color: #666;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .order-detailed li .order-detailed-left {
        display: flex;
        align-items: center;
    }

    .wrapper .order-detailed li .order-detailed-left img {
        width: 10vw;
        height: 10vw;
    }

    .wrapper .order-detailed li .order-detailed-left p {
        font-size: 3.5vw;
        margin-left: 3vw;
    }

    .wrapper .order-detailed li p {
        font-size: 3.5vw;
    }

    .wrapper .order-deliveryfee {
        width: 100%;
        height: 16vw;
        box-sizing: border-box;
        padding: 3vw;
        color: #666;
        display: flex;
        justify-content: space-between;
        align-items: center;
        font-size: 3.5vw;
    }

    /****************** 订单合计部分 ******************/
    .wrapper .total {
        width: 100%;
        height: 14vw;

        position: fixed;
        left: 0;
        bottom: 0;

        display: flex;
    }

    .wrapper .total .total-left {
        flex: 2;
        background-color: #505051;
        color: #fff;
        font-size: 4.5vw;
        font-weight: 700;
        user-select: none;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    .wrapper .total .total-right {
        flex: 1;
        background-color: #38CA73;
        color: #fff;
        font-size: 4.5vw;
        font-weight: 700;
        user-select: none;
        cursor: pointer;

        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>

5.1.5.Payment组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>在线支付</p>
        </header>

        <!-- 订单信息部分 -->
        <h3>订单信息:</h3>
        <div class="order-info">
            <p>
                {{orders.business.businessName}}
                <i class="fa fa-caret-down" @click="detailetShow"></i>
            </p>
            <p>&#165;{{orders.orderTotal}}</p>
        </div>

        <!-- 订单明细部分 -->
        <ul class="order-detailet" v-show="isShowDetailet">
            <li v-for="item in orders.list">
                <p>{{item.food.foodName}} x {{item.quantity}}</p>
                <p>&#165;{{item.food.foodPrice*item.quantity}}</p>
            </li>
            <li>
                <p>配送费</p>
                <p>&#165;{{orders.business.deliveryPrice}}</p>
            </li>
        </ul>

        <!-- 支付方式部分 -->
        <ul class="payment-type">
            <li>
                <img src="../assets/alipay.png">
                <i class="fa fa-check-circle"></i>
            </li>
            <li>
                <img src="../assets/wechat.png">
            </li>
        </ul>
        <div class="payment-button">
            <button>确认支付</button>
        </div>

        <!-- 底部菜单部分 -->
        <Footer></Footer>
    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default {
        name: 'Payment',
        data(){
            return {
                orderId:this.$route.query.orderId,
                orders:{
                    business:{}
                },
                isShowDetailet:false
            }
        },
        created() {
            this.$axios.post('OrdersController/getOrdersById',this.$qs.stringify({
                orderId:this.orderId
            })).then(response=>{
                this.orders = response.data;
            }).catch(error=>{
                console.error(error);
            });
        },
        mounted() {
            //这里的代码是实现:一旦路由到在线支付组件,就不能回到订单确认组件。
            //先将当前url添加到history对象中
            history.pushState(null,null,document.URL);
            //popstate事件能够监听history对象的变化
            window.onpopstate = () => {
                this.$router.push({path:'/index'});
            }
        },
        destroyed() {
            window.onpopstate = null;
        },
        methods:{
            detailetShow(){
                this.isShowDetailet = !this.isShowDetailet;
            }
        },
        components: {
            Footer
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 订单信息部分 ******************/
    .wrapper h3 {
        margin-top: 12vw;
        box-sizing: border-box;
        padding: 4vw 4vw 0;

        font-size: 4vw;
        font-weight: 300;
        color: #999;
    }

    .wrapper .order-info {
        box-sizing: border-box;
        padding: 4vw;
        font-size: 4vw;
        color: #666;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .order-info p:last-child {
        color: orangered;
    }

    /****************** 订单明细部分 ******************/
    .wrapper .order-detailet {
        width: 100%;
    }

    .wrapper .order-detailet li {
        width: 100%;
        box-sizing: border-box;
        padding: 1vw 4vw;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .order-detailet li p {
        font-size: 3vw;
        color: #666;
    }

    /****************** 支付方式部分 ******************/
    .wrapper .payment-type {
        width: 100%;
    }

    .wrapper .payment-type li {
        width: 100%;
        box-sizing: border-box;
        padding: 4vw;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .payment-type li img {
        width: 33vw;
        height: 8.9vw;
    }

    .wrapper .payment-type li .fa-check-circle {
        font-size: 5vw;
        color: #38CA73;
    }

    .wrapper .payment-button {
        width: 100%;
        box-sizing: border-box;
        padding: 4vw;
    }

    .wrapper .payment-button button {
        width: 100%;
        height: 10vw;
        border: none;
        /*去掉外轮廓线*/
        outline: none;
        border-radius: 4px;
        background-color: #38CA73;
        color: #fff;
    }
</style>

5.1.6.UserAddress组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>地址管理</p>
        </header>

        <!-- 地址列表部分 -->
        <ul class="addresslist">
            <li v-for="item in deliveryAddressArr">
                <div class="addresslist-left" @click="setDeliveryAddress(item)">
                    <h3>{{item.contactName}}{{item.contactSex | sexFilter}} {{item.contactTel}}</h3>
                    <p>{{item.address}}</p>
                </div>
                <div class="addresslist-right">
                    <i class="fa fa-edit" @click="editUserAddress(item.daId)"></i>
                    <i class="fa fa-remove" @click="removeUserAddress(item.daId)"></i>
                </div>
            </li>
        </ul>

        <!-- 新增地址部分 -->
        <div class="addbtn" @click="toAddUserAddress">
            <i class="fa fa-plus-circle"></i>
            <p>新增收货地址</p>
        </div>

        <!-- 底部菜单部分 -->
        <Footer></Footer>
    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default{
        name:'UserAddress',
        data(){
            return {
                businessId:this.$route.query.businessId,
                user:{},
                deliveryAddressArr:[]
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');

            this.listDeliveryAddressByUserId();
        },
        components:{
            Footer
        },
        filters:{
            sexFilter(value){
                return value==1?'先生':'女士';
            }
        },
        methods:{
            listDeliveryAddressByUserId(){
                //查询送货地址
                this.$axios.post('DeliveryAddressController/listDeliveryAddressByUserId',this.$qs.stringify({
                    userId:this.user.userId
                })).then(response=>{
                    this.deliveryAddressArr = response.data;
                }).catch(error=>{
                    console.error(error);
                });
            },
            setDeliveryAddress(deliveryAddress){
                //把用户选择的默认送货地址存储到localStorage中
                this.$setLocalStorage(this.user.userId,deliveryAddress);
                this.$router.push({path:'/orders',query:{businessId:this.businessId}});
            },
            toAddUserAddress(){
                this.$router.push({path:'/addUserAddress',query:{businessId:this.businessId}});
            },
            editUserAddress(daId){
                this.$router.push({path:'/editUserAddress',query:{businessId:this.businessId,daId:daId}});
            },
            removeUserAddress(daId){
                if(!confirm('确认要删除此送货地址吗?')){
                    return;
                }

                this.$axios.post('DeliveryAddressController/removeDeliveryAddress',this.$qs.stringify({
                    daId:daId
                })).then(response=>{
                    if(response.data>0){
                        let deliveryAddress = this.$getLocalStorage(this.user.userId);
                        if(deliveryAddress!=null&&deliveryAddress.daId==daId){
                            this.$removeLocalStorage(this.user.userId);
                        }
                        this.listDeliveryAddressByUserId();
                    }else{
                        alert('删除地址失败!');
                    }
                }).catch(error=>{
                    console.error(error);
                });
            }
        }
    }
</script>

<style scoped>
    /*************** 总容器 ***************/
    .wrapper {
        width: 100%;
        height: 100%;
        background-color: #F5F5F5;
    }

    /*************** header ***************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        display: flex;
        justify-content: space-around;
        align-items: center;
        color: #fff;
        font-size: 4.8vw;
        position: fixed;
        left: 0;
        top: 0;
        /*保证在最上层*/
        z-index: 1000;
    }

    /*************** addresslist ***************/
    .wrapper .addresslist {
        width: 100%;
        margin-top: 12vw;
        background-color: #fff;
    }

    .wrapper .addresslist li {
        width: 100%;
        box-sizing: border-box;
        border-bottom: solid 1px #DDD;
        padding: 3vw;

        display: flex;
    }

    .wrapper .addresslist li .addresslist-left {
        flex: 5;
        /*左边这块区域是可以点击的*/
        user-select: none;
        cursor: pointer;
    }

    .wrapper .addresslist li .addresslist-left h3 {
        font-size: 4.6vw;
        font-weight: 300;
        color: #666;
    }

    .wrapper .addresslist li .addresslist-left p {
        font-size: 4vw;
        color: #666;
    }

    .wrapper .addresslist li .addresslist-right {
        flex: 1;
        font-size: 5.6vw;
        color: #999;
        cursor: pointer;

        display: flex;
        justify-content: space-around;
        align-items: center;
    }

    /*************** 新增地址部分 ***************/
    .wrapper .addbtn {
        width: 100%;
        height: 14vw;
        border-top: solid 1px #DDD;
        border-bottom: solid 1px #DDD;
        background-color: #fff;
        margin-top: 4vw;

        display: flex;
        justify-content: center;
        align-items: center;

        font-size: 4.5vw;
        color: #0097FF;
        user-select: none;
        cursor: pointer;
    }

    .wrapper .addbtn p {
        margin-left: 2vw;
    }
</style>

5.1.7.AddUserAddress组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>新增送货地址</p>
        </header>

        <!-- 表单部分 -->
        <ul class="form-box">
            <li>
                <div class="title">
                    联系人:
                </div>
                <div class="content">
                    <input type="text" v-model="deliveryAddress.contactName" placeholder="联系人姓名">
                </div>
            </li>
            <li>
                <div class="title">
                    性别:
                </div>
                <div class="content" style="font-size: 3vw;">
                    <input type="radio" v-model="deliveryAddress.contactSex" value="1" style="width:6vw;height:3.2vw;">男
                    <input type="radio" v-model="deliveryAddress.contactSex" value="0" style="width:6vw;height:3.2vw;">女
                </div>
            </li>
            <li>
                <div class="title">
                    电话:
                </div>
                <div class="content">
                    <input type="tel" v-model="deliveryAddress.contactTel" placeholder="电话">
                </div>
            </li>
            <li>
                <div class="title">
                    收货地址:
                </div>
                <div class="content">
                    <input type="text" v-model="deliveryAddress.address" placeholder="收货地址">
                </div>
            </li>
        </ul>

        <div class="button-add">
            <button @click="addUserAddress">保存</button>
        </div>

        <!-- 底部菜单部分 -->
        <Footer></Footer>

    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default {
        name: 'AddUserAddress',
        data() {
            return {
                businessId:this.$route.query.businessId,
                user:{},
                deliveryAddress:{
                    contactName:'',
                    contactSex:1,
                    contactTel:'',
                    address:''
                }
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');
        },
        components: {
            Footer
        },
        methods: {
            addUserAddress(){
                if(this.deliveryAddress.contactName==''){
                    alert('联系人姓名不能为空!');
                    return;
                }
                if(this.deliveryAddress.contactTel==''){
                    alert('联系人电话不能为空!');
                    return;
                }
                if(this.deliveryAddress.address==''){
                    alert('联系人地址不能为空!');
                    return;
                }
                this.deliveryAddress.userId = this.user.userId;
                this.$axios.post('DeliveryAddressController/saveDeliveryAddress', this.$qs.stringify(
                    this.deliveryAddress
                )).then(response => {
                    if(response.data>0){
                        this.$router.push({path:'/userAddress',query:{businessId:this.businessId}});
                    }else{
                        alert('新增地址失败!');
                    }
                }).catch(error => {
                    console.error(error);
                });
            }
        }
    }
</script>

<style scoped>
    /*************** 总容器 ***************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /*************** header ***************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        display: flex;
        justify-content: space-around;
        align-items: center;
        color: #fff;
        font-size: 4.8vw;
        position: fixed;
        left: 0;
        top: 0;
        /*保证在最上层*/
        z-index: 1000;
    }

    /*************** (表单信息) ***************/
    .wrapper .form-box {
        width: 100%;
        margin-top: 12vw;
    }

    .wrapper .form-box li {
        box-sizing: border-box;
        padding: 4vw 3vw 0vw 3vw;
        display: flex;
    }

    .wrapper .form-box li .title {
        flex: 0 0 18vw;
        font-size: 3vw;
        font-weight: 700;
        color: #666;
    }

    .wrapper .form-box li .content {
        flex: 1;

        display: flex;
        align-items: center;
    }

    .wrapper .form-box li .content input {
        border: none;
        outline: none;
        width: 100%;
        height: 4vw;
        font-size: 3vw;
    }

    .wrapper .button-add {
        box-sizing: border-box;
        padding: 4vw 3vw 0vw 3vw;
    }

    .wrapper .button-add button {
        width: 100%;
        height: 10vw;
        font-size: 3.8vw;
        font-weight: 700;

        border: none;
        outline: none;
        border-radius: 4px;
        color: #fff;
        background-color: #38CA73;
    }

</style>

5.1.8.EditUserAddress组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>编辑送货地址</p>
        </header>

        <!-- 表单部分 -->
        <ul class="form-box">
            <li>
                <div class="title">
                    联系人:
                </div>
                <div class="content">
                    <input type="text" v-model="deliveryAddress.contactName" placeholder="联系人姓名">
                </div>
            </li>
            <li>
                <div class="title">
                    性别:
                </div>
                <div class="content" style="font-size: 3vw;">
                    <input type="radio" v-model="deliveryAddress.contactSex" value="1" style="width:6vw;height:3.2vw;" checked>男
                    <input type="radio" v-model="deliveryAddress.contactSex" value="0" style="width:6vw;height:3.2vw;">女
                </div>
            </li>
            <li>
                <div class="title">
                    电话:
                </div>
                <div class="content">
                    <input type="tel" v-model="deliveryAddress.contactTel" placeholder="电话">
                </div>
            </li>
            <li>
                <div class="title">
                    收货地址:
                </div>
                <div class="content">
                    <input type="text" v-model="deliveryAddress.address" placeholder="收货地址">
                </div>
            </li>
        </ul>

        <div class="button-add">
            <button @click="editUserAddress">更新</button>
        </div>

        <!-- 底部菜单部分 -->
        <Footer></Footer>
    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default {
        name: 'EditUserAddress',
        data() {
            return {
                businessId: this.$route.query.businessId,
                daId: this.$route.query.daId,
                user: {},
                deliveryAddress: {}
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');

            this.$axios.post('DeliveryAddressController/getDeliveryAddressById', this.$qs.stringify({
                daId:this.daId
            })).then(response => {
                this.deliveryAddress = response.data;
            }).catch(error => {
                console.error(error);
            });
        },
        components: {
            Footer
        },
        methods: {
            editUserAddress() {
                if (this.deliveryAddress.contactName == '') {
                    alert('联系人姓名不能为空!');
                    return;
                }
                if (this.deliveryAddress.contactTel == '') {
                    alert('联系人电话不能为空!');
                    return;
                }
                if (this.deliveryAddress.address == '') {
                    alert('联系人地址不能为空!');
                    return;
                }

                this.$axios.post('DeliveryAddressController/updateDeliveryAddress', this.$qs.stringify(
                    this.deliveryAddress
                )).then(response => {
                    if (response.data > 0) {
                        this.$router.push({
                            path: '/userAddress',
                            query: {
                                businessId: this.businessId
                            }
                        });
                    } else {
                        alert('更新地址失败!');
                    }
                }).catch(error => {
                    console.error(error);
                });
            }
        }
    }
</script>

<style scoped>
    /*************** 总容器 ***************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /*************** header ***************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        display: flex;
        justify-content: space-around;
        align-items: center;
        color: #fff;
        font-size: 4.8vw;
        position: fixed;
        left: 0;
        top: 0;
        /*保证在最上层*/
        z-index: 1000;
    }

    /*************** (表单信息) ***************/
    .wrapper .form-box {
        width: 100%;
        margin-top: 12vw;
    }

    .wrapper .form-box li {
        box-sizing: border-box;
        padding: 4vw 3vw 0vw 3vw;
        display: flex;
    }

    .wrapper .form-box li .title {
        flex: 0 0 18vw;
        font-size: 3vw;
        font-weight: 700;
        color: #666;
    }

    .wrapper .form-box li .content {
        flex: 1;

        display: flex;
        align-items: center;
    }

    .wrapper .form-box li .content input {
        border: none;
        outline: none;
        width: 100%;
        height: 4vw;
        font-size: 3vw;
    }

    .wrapper .button-add {
        box-sizing: border-box;
        padding: 4vw 3vw 0vw 3vw;
    }

    .wrapper .button-add button {
        width: 100%;
        height: 10vw;
        font-size: 3.8vw;
        font-weight: 700;

        border: none;
        outline: none;
        border-radius: 4px;
        color: #fff;
        background-color: #38CA73;
    }
</style>

5.1.9.OrderList组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>我的订单</p>
        </header>

        <!-- 订单列表部分 -->
        <h3>未支付订单信息:</h3>
        <ul class="order">
            <li v-for="item in orderArr" v-if="item.orderState==0">
                <div class="order-info">
                    <p>
                        {{item.business.businessName}}
                        <i class="fa fa-caret-down" @click="detailetShow(item)"></i>
                    </p>
                    <div class="order-info-right">
                        <p>&#165;{{item.orderTotal}}</p>
                        <div class="order-info-right-icon">去支付</div>
                    </div>
                </div>
                <ul class="order-detailet" v-show="item.isShowDetailet">
                    <li v-for="odItem in item.list">
                        <p>{{odItem.food.foodName}} x {{odItem.quantity}}</p>
                        <p>&#165;{{odItem.food.foodPrice*odItem.quantity}}</p>
                    </li>
                    <li>
                        <p>配送费</p>
                        <p>&#165;{{item.business.deliveryPrice}}</p>
                    </li>
                </ul>
            </li>
        </ul>

        <h3>已支付订单信息:</h3>
        <ul class="order">
            <li v-for="item in orderArr" v-if="item.orderState==1">
                <div class="order-info">
                    <p>
                        {{item.business.businessName}}
                        <i class="fa fa-caret-down" @click="detailetShow(item)"></i>
                    </p>
                    <div class="order-info-right">
                        <p>&#165;{{item.orderTotal}}</p>
                    </div>
                </div>
                <ul class="order-detailet" v-show="item.isShowDetailet">
                    <li v-for="odItem in item.list">
                        <p>{{odItem.food.foodName}} x {{odItem.quantity}}</p>
                        <p>&#165;{{odItem.food.foodPrice*odItem.quantity}}</p>
                    </li>
                    <li>
                        <p>配送费</p>
                        <p>&#165;{{item.business.deliveryPrice}}</p>
                    </li>
                </ul>
            </li>
        </ul>

        <!-- 底部菜单部分 -->
        <Footer></Footer>

    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default{
        name:'OrderList',
        data(){
            return {
                orderArr:[],
                user:{}
            }
        },
        created() {
            this.user = this.$getSessionStorage('user');

            this.$axios.post('OrdersController/listOrdersByUserId',this.$qs.stringify({
                userId:this.user.userId
            })).then(response=>{
                let result = response.data;
                for(let orders of result){
                    orders.isShowDetailet = false;
                }
                this.orderArr = result;
            }).catch(error=>{
                console.error(error);
            });
        },
        methods:{
            detailetShow(orders){
                orders.isShowDetailet = !orders.isShowDetailet;
            }
        },
        components:{
            Footer
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 历史订单列表部分 ******************/
    .wrapper h3 {
        margin-top: 12vw;
        box-sizing: border-box;
        padding: 4vw;
        font-size: 4vw;
        font-weight: 300;
        color: #999;
    }

    .wrapper .order {
        width: 100%;
    }

    .wrapper .order li {
        width: 100%;
    }

    .wrapper .order li .order-info {
        box-sizing: border-box;
        padding: 2vw 4vw;
        font-size: 4vw;
        color: #666;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .wrapper .order li .order-info .order-info-right {
        display: flex;
    }

    .wrapper .order li .order-info .order-info-right .order-info-right-icon {
        background-color: #f90;
        color: #fff;
        border-radius: 3px;
        margin-left: 2vw;
        user-select: none;
        cursor: pointer;
    }

    .wrapper .order li .order-detailet {
        width: 100%;
    }

    .wrapper .order li .order-detailet li {
        width: 100%;
        box-sizing: border-box;
        padding: 1vw 4vw;
        color: #666;
        font-size: 3vw;

        display: flex;
        justify-content: space-between;
        align-items: center;
    }
</style>

5.1.10.Login组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>用户登陆</p>
        </header>

        <!-- 表单部分 -->
        <ul class="form-box">
            <li>
                <div class="title">
                    手机号码:
                </div>
                <div class="content">
                    <input type="text" v-model="userId" placeholder="手机号码">
                </div>
            </li>
            <li>
                <div class="title">
                    密码:
                </div>
                <div class="content">
                    <input type="password" v-model="password" placeholder="密码">
                </div>
            </li>
        </ul>

        <div class="button-login">
            <button @click="login">登陆</button>
        </div>
        <div class="button-register">
            <button @click="register">去注册</button>
        </div>

        <!-- 底部菜单部分 -->
        <Footer></Footer>
    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default{
        name:'Login',
        data(){
            return {
                userId:'',
                password:''
            }
        },
        methods:{
            login(){
                if(this.userId==''){
                    alert('手机号码不能为空!');
                    return;
                }
                if(this.password==''){
                    alert('密码不能为空!');
                    return;
                }

                //登录请求
                this.$axios.post('UserController/getUserByIdByPass',this.$qs.stringify({
                    userId:this.userId,
                    password:this.password
                })).then(response=>{
                    let user = response.data;
                    if(user==null){
                        alert('用户名或密码不正确!');
                    }else{
                        //sessionstorage有容量限制,为了防止数据溢出,所以不将userImg数据放入session中
                        user.userImg = '';
                        this.$setSessionStorage('user',user);
                        this.$router.go(-1);
                    }
                }).catch(error=>{
                    console.error(error);
                });
            },
            register(){
                this.$router.push({path:'register'});
            }
        },
        components:{
            Footer
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 表单部分 ******************/
    .wrapper .form-box {
        width: 100%;
        margin-top: 12vw;
    }

    .wrapper .form-box li {
        box-sizing: border-box;
        padding: 4vw 3vw 0 3vw;
        display: flex;
        align-items: center;
    }

    .wrapper .form-box li .title {
        flex: 0 0 18vw;
        font-size: 3vw;
        font-weight: 700;
        color: #666;
    }

    .wrapper .form-box li .content {
        flex: 1;
    }

    .wrapper .form-box li .content input {
        border: none;
        outline: none;
        width: 100%;
        height: 4vw;
        font-size: 3vw;
    }

    .wrapper .button-login {
        width: 100%;
        box-sizing: border-box;
        padding: 4vw 3vw 0 3vw;
    }

    .wrapper .button-login button {
        width: 100%;
        height: 10vw;
        font-size: 3.8vw;
        font-weight: 700;
        color: #fff;
        background-color: #38CA73;
        border-radius: 4px;

        border: none;
        outline: none;
    }

    .wrapper .button-register {
        width: 100%;
        box-sizing: border-box;
        padding: 4vw 3vw 0 3vw;
    }

    .wrapper .button-register button {
        width: 100%;
        height: 10vw;
        font-size: 3.8vw;
        font-weight: 700;
        /*与上面登陆按钮不同的只有颜色、背景色、边框不同*/
        color: #666;
        background-color: #EEE;
        border: solid 1px #DDD;
        border-radius: 4px;

        border: none;
        outline: none;
    }

    /****************** 底部菜单部分 ******************/
    .wrapper .footer {
        width: 100%;
        height: 14vw;
        border-top: solid 1px #DDD;
        background-color: #fff;

        position: fixed;
        left: 0;
        bottom: 0;

        display: flex;
        justify-content: space-around;
        align-items: center;
    }

    .wrapper .footer li {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;

        color: #999;
        user-select: none;
        cursor: pointer;
    }

    .wrapper .footer li p {
        font-size: 2.8vw;
    }

    .wrapper .footer li i {
        font-size: 5vw;
    }
</style>

5.1.11.Register组件

<template>
    <div class="wrapper">

        <!-- header部分 -->
        <header>
            <p>用户注册</p>
        </header>

        <!-- 表单部分 -->
        <ul class="form-box">
            <li>
                <div class="title">
                    手机号码:
                </div>
                <div class="content">
                    <input type="text" @blur="checkUserId" v-model="user.userId" placeholder="手机号码">
                </div>
            </li>
            <li>
                <div class="title">
                    密码:
                </div>
                <div class="content">
                    <input type="password" v-model="user.password" placeholder="密码">
                </div>
            </li>
            <li>
                <div class="title">
                    确认密码:
                </div>
                <div class="content">
                    <input type="password" v-model="confirmPassword" placeholder="确认密码">
                </div>
            </li>
            <li>
                <div class="title">
                    用户名称:
                </div>
                <div class="content">
                    <input type="text" v-model="user.userName" placeholder="用户名称">
                </div>
            </li>
            <li>
                <div class="title">
                    性别:
                </div>
                <div class="content" style="font-size: 3vw;">
                    <input type="radio" v-model="user.userSex" value="1" style="width:6vw;height: 3.2vw;">男
                    <input type="radio" v-model="user.userSex" value="0" style="width:6vw;height: 3.2vw;">女
                </div>
            </li>
        </ul>

        <div class="button-login">
            <button @click="register">注册</button>
        </div>

        <!-- 底部菜单部分 -->
        <Footer></Footer>
    </div>
</template>

<script>
    import Footer from '../components/Footer.vue';

    export default {
        name: 'Register',
        data() {
            return {
                user:{
                    userId:'',
                    password:'',
                    userName:'',
                    userSex:1
                },
                confirmPassword:''
            }
        },
        methods: {
            checkUserId(){
                this.$axios.post('UserController/getUserById', this.$qs.stringify({
                    userId: this.user.userId,
                })).then(response => {
                    if(response.data==1){
                        this.user.userId = '';
                        alert('此手机号码已存在!')
                    }
                }).catch(error => {
                    console.error(error);
                });
            },
            register() {
                if (this.user.userId == '') {
                    alert('手机号码不能为空!');
                    return;
                }
                if (this.user.password == '') {
                    alert('密码不能为空!');
                    return;
                }
                if (this.user.password != this.confirmPassword) {
                    alert('两次输入的密码不一致!');
                    return;
                }
                if (this.user.userName == '') {
                    alert('用户名不能为空!');
                    return;
                }

                //注册请求
                this.$axios.post('UserController/saveUser', this.$qs.stringify(
                    this.user
                )).then(response => {
                    if(response.data>0){
                        alert('注册成功!');
                        this.$router.go(-1);
                    }else{
                        alert('注册失败!');
                    }
                }).catch(error => {
                    console.error(error);
                });
            }
        },
        components: {
            Footer
        }
    }
</script>

<style scoped>
    /****************** 总容器 ******************/
    .wrapper {
        width: 100%;
        height: 100%;
    }

    /****************** header部分 ******************/
    .wrapper header {
        width: 100%;
        height: 12vw;
        background-color: #0097FF;
        color: #fff;
        font-size: 4.8vw;

        position: fixed;
        left: 0;
        top: 0;
        z-index: 1000;

        display: flex;
        justify-content: center;
        align-items: center;
    }

    /****************** 表单部分 ******************/
    .wrapper .form-box {
        width: 100%;
        margin-top: 12vw;
    }

    .wrapper .form-box li {
        box-sizing: border-box;
        padding: 4vw 3vw 0 3vw;
        display: flex;
        align-items: center;
    }

    .wrapper .form-box li .title {
        flex: 0 0 18vw;
        font-size: 3vw;
        font-weight: 700;
        color: #666;
    }

    .wrapper .form-box li .content {
        flex: 1;
    }

    .wrapper .form-box li .content input {
        border: none;
        outline: none;
        width: 100%;
        height: 4vw;
        font-size: 3vw;
    }

    .wrapper .button-login {
        width: 100%;
        box-sizing: border-box;
        padding: 4vw 3vw 0 3vw;
    }

    .wrapper .button-login button {
        width: 100%;
        height: 10vw;
        font-size: 3.8vw;
        font-weight: 700;
        color: #fff;
        background-color: #38CA73;
        border-radius: 4px;

        border: none;
        outline: none;
    }

    .wrapper .button-register {
        width: 100%;
        box-sizing: border-box;
        padding: 4vw 3vw 0 3vw;
    }

    .wrapper .button-register button {
        width: 100%;
        height: 10vw;
        font-size: 3.8vw;
        font-weight: 700;
        color: #666;
        background-color: #EEE;
        border-radius: 4px;

        border: none;
        outline: none;
        border: solid 1px #DDD;
    }
</style>

5.1.12.Footer共通组件

<template>
    <ul class="footer">
        <li @click="toIndex">
            <i class="fa fa-home"></i>
            <p>首页</p>
        </li>
        <li>
            <i class="fa fa-compass"></i>
            <p>发现</p>
        </li>
        <li @click="toOrderList">
            <i class="fa fa-file-text-o"></i>
            <p>订单</p>
        </li>
        <li>
            <i class="fa fa-user-o"></i>
            <p>我的</p>
        </li>
    </ul>
</template>

<script>
    export default{
        name:'Footer',
        methods:{
            toIndex(){
                this.$router.push({path:'/index'});
            },
            toOrderList(){
                this.$router.push({path:'/orderList'});
            }
        }
    }
</script>

<style>
    .wrapper .footer {
        width: 100%;
        height: 14vw;
        border-top: solid 1px #DDD;
        background-color: #fff;

        position: fixed;
        left: 0;
        bottom: 0;

        display: flex;
        justify-content: space-around;
        align-items: center;
    }

    .wrapper .footer li {
        /*li本身的尺寸完全由内容撑起*/
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;

        color: #999;
        user-select: none;
        cursor: pointer;
    }

    .wrapper .footer li p {
        font-size: 2.8vw;
    }

    .wrapper .footer li i {
        font-size: 5vw;
    }
</style>