wuheng 1 vuosi sitten
vanhempi
commit
005796f088

+ 1 - 0
.env

@@ -0,0 +1 @@
+VUE_APP_URL=http://shop-api.edu.koobietech.com

+ 7 - 0
babel.config.js

@@ -1,5 +1,12 @@
 module.exports = {
   presets: [
     '@vue/cli-plugin-babel/preset'
+  ],
+  plugins: [
+    ['import', {
+      libraryName: 'vant',
+      libraryDirectory: 'es',
+      style: true
+    }, 'vant']
   ]
 }

+ 122 - 13
package-lock.json

@@ -8,7 +8,12 @@
       "name": "shop-mobile",
       "version": "0.1.0",
       "dependencies": {
+        "axios": "^1.4.0",
+        "axios-retry": "^3.5.1",
+        "babel-plugin-import": "^1.13.6",
         "core-js": "^3.8.3",
+        "crypto-js": "^4.1.1",
+        "vant": "^2.12.54",
         "vue": "^2.6.14",
         "vue-router": "^3.5.1",
         "vuex": "^3.6.2"
@@ -261,7 +266,6 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz",
       "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==",
-      "dev": true,
       "dependencies": {
         "@babel/types": "^7.22.5"
       },
@@ -383,7 +387,6 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
       "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
-      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -392,7 +395,6 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
       "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
-      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -1731,7 +1733,6 @@
       "version": "7.22.6",
       "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.22.6.tgz",
       "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
-      "dev": true,
       "dependencies": {
         "regenerator-runtime": "^0.13.11"
       },
@@ -1778,7 +1779,6 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.22.5.tgz",
       "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==",
-      "dev": true,
       "dependencies": {
         "@babel/helper-string-parser": "^7.22.5",
         "@babel/helper-validator-identifier": "^7.22.5",
@@ -2273,11 +2273,20 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@vant/icons": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/@vant/icons/-/icons-1.8.0.tgz",
+      "integrity": "sha512-sKfEUo2/CkQFuERxvkuF6mGQZDKu3IQdj5rV9Fm0weJXtchDSSQ+zt8qPCNUEhh9Y8shy5PzxbvAfOOkCwlCXg=="
+    },
+    "node_modules/@vant/popperjs": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/@vant/popperjs/-/popperjs-1.3.0.tgz",
+      "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
+    },
     "node_modules/@vue/babel-helper-vue-jsx-merge-props": {
       "version": "1.4.0",
       "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz",
-      "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==",
-      "dev": true
+      "integrity": "sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA=="
     },
     "node_modules/@vue/babel-helper-vue-transform-on": {
       "version": "1.1.5",
@@ -3257,6 +3266,11 @@
         "lodash": "^4.17.14"
       }
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
     "node_modules/at-least-node": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
@@ -3289,6 +3303,25 @@
         "postcss": "^8.1.0"
       }
     },
+    "node_modules/axios": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+      "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+      "dependencies": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
+    "node_modules/axios-retry": {
+      "version": "3.5.1",
+      "resolved": "https://registry.npmjs.org/axios-retry/-/axios-retry-3.5.1.tgz",
+      "integrity": "sha512-mQRJ4IyAUnYig14BQ4MnnNHHuH1cNH7NW4JxEUD6mNJwK6pwOY66wKLCwZ6Y0o3POpfStalqRC+J4+Hnn6Om7w==",
+      "dependencies": {
+        "@babel/runtime": "^7.15.4",
+        "is-retry-allowed": "^2.2.0"
+      }
+    },
     "node_modules/babel-loader": {
       "version": "8.3.0",
       "resolved": "https://registry.npmmirror.com/babel-loader/-/babel-loader-8.3.0.tgz",
@@ -3331,6 +3364,14 @@
         "object.assign": "^4.1.0"
       }
     },
+    "node_modules/babel-plugin-import": {
+      "version": "1.13.6",
+      "resolved": "https://registry.npmjs.org/babel-plugin-import/-/babel-plugin-import-1.13.6.tgz",
+      "integrity": "sha512-N7FYnGh0DFsvDRkAPsvFq/metVfVD7P2h1rokOPpEH4cZbdRHCW+2jbXt0nnuqowkm/xhh2ww1anIdEpfYa7ZA==",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.0.0"
+      }
+    },
     "node_modules/babel-plugin-polyfill-corejs2": {
       "version": "0.4.4",
       "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz",
@@ -3868,6 +3909,17 @@
       "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
       "dev": true
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/commander": {
       "version": "8.3.0",
       "resolved": "https://registry.npmmirror.com/commander/-/commander-8.3.0.tgz",
@@ -4109,6 +4161,11 @@
         "semver": "bin/semver"
       }
     },
+    "node_modules/crypto-js": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
+      "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
+    },
     "node_modules/css-declaration-sorter": {
       "version": "6.4.1",
       "resolved": "https://registry.npmmirror.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz",
@@ -4575,6 +4632,14 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/depd": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
@@ -5159,7 +5224,6 @@
       "version": "1.15.2",
       "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz",
       "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
-      "dev": true,
       "engines": {
         "node": ">=4.0"
       },
@@ -5169,6 +5233,19 @@
         }
       }
     },
+    "node_modules/form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/forwarded": {
       "version": "0.2.0",
       "resolved": "https://registry.npmmirror.com/forwarded/-/forwarded-0.2.0.tgz",
@@ -5839,6 +5916,17 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/is-retry-allowed": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz",
+      "integrity": "sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-stream": {
       "version": "1.1.0",
       "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-1.1.0.tgz",
@@ -6544,7 +6632,6 @@
       "version": "1.52.0",
       "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
       "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "dev": true,
       "engines": {
         "node": ">= 0.6"
       }
@@ -6553,7 +6640,6 @@
       "version": "2.1.35",
       "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
       "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dev": true,
       "dependencies": {
         "mime-db": "1.52.0"
       },
@@ -7973,6 +8059,11 @@
         "node": ">= 0.10"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
     "node_modules/prr": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
@@ -8150,8 +8241,7 @@
     "node_modules/regenerator-runtime": {
       "version": "0.13.11",
       "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
-      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
-      "dev": true
+      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
     },
     "node_modules/regenerator-transform": {
       "version": "0.15.1",
@@ -9028,7 +9118,6 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
       "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
-      "dev": true,
       "engines": {
         "node": ">=4"
       }
@@ -9220,6 +9309,21 @@
         "spdx-expression-parse": "^3.0.0"
       }
     },
+    "node_modules/vant": {
+      "version": "2.12.54",
+      "resolved": "https://registry.npmjs.org/vant/-/vant-2.12.54.tgz",
+      "integrity": "sha512-t7DCiLxNosDrg0Jm5EY9p0A5cAMo5OadmizbYtPEc0ru+OJKEa3kcfxtKIK5on7ZPqoOkyYJt8e6BQ1VDMPsrg==",
+      "dependencies": {
+        "@babel/runtime": "7.x",
+        "@vant/icons": "^1.7.1",
+        "@vant/popperjs": "^1.1.0",
+        "@vue/babel-helper-vue-jsx-merge-props": "^1.0.0",
+        "vue-lazyload": "1.2.3"
+      },
+      "peerDependencies": {
+        "vue": ">= 2.6.0"
+      }
+    },
     "node_modules/vary": {
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz",
@@ -9244,6 +9348,11 @@
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
       "dev": true
     },
+    "node_modules/vue-lazyload": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.2.3.tgz",
+      "integrity": "sha512-DC0ZwxanbRhx79tlA3zY5OYJkH8FYp3WBAnAJbrcuoS8eye1P73rcgAZhyxFSPUluJUTelMB+i/+VkNU/qVm7g=="
+    },
     "node_modules/vue-loader": {
       "version": "17.2.2",
       "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.2.2.tgz",

+ 5 - 0
package.json

@@ -7,7 +7,12 @@
     "build": "vue-cli-service build"
   },
   "dependencies": {
+    "axios": "^1.4.0",
+    "axios-retry": "^3.5.1",
+    "babel-plugin-import": "^1.13.6",
     "core-js": "^3.8.3",
+    "crypto-js": "^4.1.1",
+    "vant": "^2.12.54",
     "vue": "^2.6.14",
     "vue-router": "^3.5.1",
     "vuex": "^3.6.2"

+ 3 - 16
src/App.vue

@@ -1,9 +1,5 @@
 <template>
   <div id="app">
-    <nav>
-      <router-link to="/">Home</router-link> |
-      <router-link to="/about">About</router-link>
-    </nav>
     <router-view/>
   </div>
 </template>
@@ -16,17 +12,8 @@
   text-align: center;
   color: #2c3e50;
 }
-
-nav {
-  padding: 30px;
-
-  a {
-    font-weight: bold;
-    color: #2c3e50;
-
-    &.router-link-exact-active {
-      color: #42b983;
-    }
-  }
+html, body {
+  padding: 0;
+  margin: 0;
 }
 </style>

+ 15 - 0
src/api/user.js

@@ -0,0 +1,15 @@
+import {post, get} from '../utils/request'
+
+/**
+ * 所有的 URL地址 必须封装在 API 里面
+ * 不允许在 把URL字符串 写在 页面逻辑里面
+ */
+
+/**
+ * 登录接口
+ * @param {*} data 
+ * @returns 
+ */
+export const login = (data)=> post("/login", data)
+
+export const register = (data) => post("/user/register", data)

BIN
src/assets/logo.jpg


+ 0 - 59
src/components/HelloWorld.vue

@@ -1,59 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <p>
-      For a guide and recipes on how to configure / customize this project,<br>
-      check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
-    </p>
-    <h3>Installed CLI Plugins</h3>
-    <ul>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
-    </ul>
-    <h3>Essential Links</h3>
-    <ul>
-      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
-      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
-      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
-      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
-      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
-    </ul>
-    <h3>Ecosystem</h3>
-    <ul>
-      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
-      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
-      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
-      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'HelloWorld',
-  props: {
-    msg: String
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped lang="less">
-h3 {
-  margin: 40px 0 0;
-}
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-a {
-  color: #42b983;
-}
-</style>

+ 25 - 0
src/components/Logo.vue

@@ -0,0 +1,25 @@
+<template>
+    <div class="logo">
+        <van-image fit="cover" :src="logo" />
+    </div>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            logo: require("../assets/logo.jpg")
+        }
+    }
+}
+</script>
+<style lang="less">
+.logo {
+    .van-image {
+        img {
+            width: 40vw;
+            padding-bottom: 8vh;
+            padding-top: 20vh;
+        }
+    }
+}
+</style>

+ 18 - 0
src/components/Tabber.vue

@@ -0,0 +1,18 @@
+<template>
+    <van-tabbar v-model="active">
+        <van-tabbar-item replace to="/home" icon="wap-home">主页</van-tabbar-item>
+        <van-tabbar-item replace to="/cateGory" icon="expand">分类</van-tabbar-item>
+        <van-tabbar-item replace to="/shopCart" icon="shopping-cart">购物车</van-tabbar-item>
+        <van-tabbar-item replace to="/me" icon="manager">我的</van-tabbar-item>
+    </van-tabbar>
+</template>
+<script>
+export default {
+    data() {
+        return {
+            active: 0,
+        }
+    },
+}
+</script>
+<style lang="less"></style>

+ 9 - 1
src/main.js

@@ -2,9 +2,17 @@ import Vue from 'vue'
 import App from './App.vue'
 import router from './router'
 import store from './store'
-
 Vue.config.productionTip = false
 
+import { Image as VanImage, Form, Field, Button, Tabbar, TabbarItem } from 'vant';
+
+Vue.use(VanImage)
+Vue.use(Form)
+Vue.use(Field)
+Vue.use(Button)
+Vue.use(Tabbar)
+Vue.use(TabbarItem)
+
 new Vue({
   router,
   store,

+ 31 - 9
src/router/index.js

@@ -1,22 +1,44 @@
 import Vue from 'vue'
 import VueRouter from 'vue-router'
-import HomeView from '../views/HomeView.vue'
+import Login from '../views/Login.vue'
+import Register from '../views/Register.vue'
+import Me from '../views/Me.vue'
+import Home from '../views/Home.vue'
+import Category from '../views/Category.vue'
+import ShopCart from '../views/ShopCart.vue'
 
 Vue.use(VueRouter)
 
 const routes = [
   {
-    path: '/',
+    path: '/me',
+    name: 'me',
+    component: Me
+  },
+  {
+    path: '/home',
     name: 'home',
-    component: HomeView
+    component: Home
+  },
+  {
+    path: '/category',
+    name: 'category',
+    component: Category
+  },
+  {
+    path: '/shopCart',
+    name: 'shopCart',
+    component: ShopCart
+  },
+  {
+    path: '/login',
+    name: 'login',
+    component: Login
   },
   {
-    path: '/about',
-    name: 'about',
-    // route level code-splitting
-    // this generates a separate chunk (about.[hash].js) for this route
-    // which is lazy-loaded when the route is visited.
-    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
+    path: '/register',
+    name: 'register',
+    component: Register
   }
 ]
 

+ 26 - 0
src/utils/cryptojs.js

@@ -0,0 +1,26 @@
+import CryptoJS from "crypto-js"
+
+const keyword = "shopkey-password"
+
+export const encrypto = (word) => {
+    const time = Date.now()
+    //转码
+    const wordStr  = CryptoJS.enc.Utf8.parse( time + "" + word)  
+    const key = CryptoJS.enc.Utf8.parse(keyword)
+    //加密操作
+    const cryptoStr = CryptoJS.AES.encrypt( wordStr, key, {
+        mode: CryptoJS.mode.ECB,    //加密模式
+        padding: CryptoJS.pad.Pkcs7 //如何补零
+    })
+    return cryptoStr.toString() 
+}
+
+export const decrypto = (word) => { 
+    const key = CryptoJS.enc.Utf8.parse(keyword)
+    //加密操作
+    const cryptoStr = CryptoJS.AES.decrypt( word, key, {
+        mode: CryptoJS.mode.ECB,    //加密模式
+        padding: CryptoJS.pad.Pkcs7 //如何补零
+    })
+    return CryptoJS.enc.Utf8.stringify(cryptoStr).toString()
+}

+ 65 - 0
src/utils/request.js

@@ -0,0 +1,65 @@
+import axios from "axios"
+import axiosRetry from "axios-retry"
+import { Promise } from "core-js"
+import { Notify } from 'vant'
+
+
+/**
+ * 发生异常的情况
+ * 自动再次发送请求
+ */
+axiosRetry(axios, {
+    retries: 3, //请求失败重试次数
+    retryDelay: (retryCount) => {
+        return retryCount * 2000  //延迟请求  防止短时间内发送过于频繁
+    },
+    shouldResetTimeout: true
+})
+
+const config = {
+    headers: {
+        "Context-type": "application/json",
+        "Accept": "application/json"
+    },
+    baseURL : process.env.VUE_APP_URL
+}
+
+const ajax = axios.create(config)
+
+/**
+ * 前后端基本都是 JWT鉴权
+ * 所以我们需要在 发送请求的时候在 Header里携带 Token
+ */
+ajax.interceptors.request.use(config=>{
+    const token = sessionStorage.getItem("token")
+    if ( token ) {
+        config.headers["Authorization"] = token
+    }
+    return config
+}, error=>{
+    return Promise.reject( error )
+})
+
+/**
+ * 相应拦截器 返回页面数据
+ * 把Ajax 其他的不相关的数据 过滤掉
+ */
+ajax.interceptors.response.use(response=>{
+    const data = response.data
+    if ( data.code === "00000" ) {
+        return data.data
+    }
+    if ( data.code === "A00004" ) {
+        Notify('请登录后操作!')
+        return Promise.reject( "当前页面需要登录!" ) 
+    }
+    Notify( data.msg )
+    return Promise.reject( "数据格式错误" )
+}, error => {
+    return Promise.reject( error )
+})
+
+const post = ( url, data ) => ajax.post( url, data)
+const get = ( url, data ) => ajax.get( url, {params: data} )
+
+export { post, get }

+ 0 - 5
src/views/AboutView.vue

@@ -1,5 +0,0 @@
-<template>
-  <div class="about">
-    <h1>This is an about page</h1>
-  </div>
-</template>

+ 19 - 0
src/views/Category.vue

@@ -0,0 +1,19 @@
+<template>
+    <div>
+        <h1>分类</h1>
+        <Tabber />
+    </div>
+</template>
+<script>
+import Tabber from '@/components/Tabber.vue';
+export default {
+    data(){
+        return {}
+    },
+    components:{
+        Tabber
+    }
+}
+</script>
+<style lang="less">
+</style>

+ 19 - 0
src/views/Home.vue

@@ -0,0 +1,19 @@
+<template>
+    <div>
+        <h1>主页</h1>
+        <Tabber />
+    </div>
+</template>
+<script>
+import Tabber from '@/components/Tabber.vue';
+export default {
+    data(){
+        return {}
+    },
+    components:{
+        Tabber
+    }
+}
+</script>
+<style lang="less">
+</style>

+ 0 - 18
src/views/HomeView.vue

@@ -1,18 +0,0 @@
-<template>
-  <div class="home">
-    <img alt="Vue logo" src="../assets/logo.png">
-    <HelloWorld msg="Welcome to Your Vue.js App"/>
-  </div>
-</template>
-
-<script>
-// @ is an alias to /src
-import HelloWorld from '@/components/HelloWorld.vue'
-
-export default {
-  name: 'HomeView',
-  components: {
-    HelloWorld
-  }
-}
-</script>

+ 51 - 0
src/views/Login.vue

@@ -0,0 +1,51 @@
+<template>
+    <div class="login">
+        <logo />
+        <van-form @submit="onSubmit">
+            <van-field v-model="username" name="用户名" label="用户名" placeholder="用户名"
+                :rules="[{ required: true, message: '请填写用户名' }]" />
+            <van-field v-model="password" type="password" name="密码" label="密码" placeholder="密码"
+                :rules="[{ required: true, message: '请填写密码' }]" />
+            <div style="margin: 16px;">
+                <van-button square block type="danger" native-type="submit">登录</van-button>
+            </div>
+        </van-form>
+        <span>
+            <router-link to="/register">没有账号去注册</router-link>
+        </span>
+    </div>
+</template>
+<script>
+import Vue from 'vue'
+import { login } from '../api/user'
+import { encrypto } from '../utils/cryptojs'
+import Logo from '@/components/Logo.vue'
+export default {
+    data() {
+        return {
+            username: "",
+            password: ""
+        };
+    },
+    methods: {
+        async onSubmit() {
+            const result = await login({
+                userName: this.username,
+                passWord: encrypto(this.password)
+            })
+            if ( result.accessToken ) {
+                sessionStorage.setItem("token", result.accessToken)
+                this.$router.push("/home")
+            }
+        }
+    },
+    components:{
+        Logo
+    }
+}
+</script>
+<style lang="less">
+.login {
+    padding: 2rem;
+}
+</style>../utils/cryptojs

+ 22 - 0
src/views/Me.vue

@@ -0,0 +1,22 @@
+<template>
+    <div class="me">
+        <h1>我的</h1>
+        <Tabber />
+    </div>
+</template>
+<script>
+import Tabber from '@/components/Tabber.vue';
+export default {
+    data(){
+        return {}
+    },
+    components:{
+        Tabber
+    }
+}
+</script>
+<style lang="less">
+.me{
+
+}
+</style>

+ 48 - 0
src/views/Register.vue

@@ -0,0 +1,48 @@
+<template>
+    <div class="register">
+        <logo />
+        <van-form @submit="register">
+            <van-field v-model="form.username" name="用户名" label="用户名" placeholder="用户名"
+                :rules="[{ required: true, message: '请填写用户名' }]" />
+            <van-field v-model="form.password" type="password" name="密码" label="密码" placeholder="密码"
+                :rules="[{ required: true, message: '请填写密码' }]" />
+            <div style="margin: 16px;">
+                <van-button square block type="danger" native-type="submit">注册用户</van-button>
+            </div>
+        </van-form>
+    </div>
+</template>
+<script>
+import { register } from '@/api/user'
+import { encrypto } from '@/utils/cryptojs'
+import Logo from '@/components/Logo.vue'
+export default {
+    data(){
+        return {
+            form: {
+                username: "",
+                password: ""
+            }
+        }
+    },
+    methods : {
+        async register(){
+            const result = await register({
+                userName: this.form.username,
+                passWord: encrypto( this.form.password )
+            })
+            if ( result.accessToken ) {
+                this.$router.push("/login")
+            }
+        }
+    },
+    components: {
+        Logo
+    }
+}
+</script>
+<style lang="less">
+.register{
+    padding: 2rem;
+}
+</style>

+ 19 - 0
src/views/ShopCart.vue

@@ -0,0 +1,19 @@
+<template>
+    <div>
+        <h1>购物车</h1>
+        <Tabber />
+    </div>
+</template>
+<script>
+import Tabber from '@/components/Tabber.vue';
+export default {
+    data(){
+        return {}
+    },
+    components:{
+        Tabber
+    }
+}
+</script>
+<style lang="less">
+</style>