Просмотр исходного кода

Add package: axios; refined login page and register page; add some backend communication logic; todo: dashboard

Nivek 2 лет назад
Родитель
Сommit
e10882c36f
8 измененных файлов с 212 добавлено и 56 удалено
  1. 85 0
      package-lock.json
  2. 1 0
      package.json
  3. 1 0
      src/App.vue
  4. 50 32
      src/components/Login.vue
  5. 61 22
      src/components/Register.vue
  6. 2 2
      src/router/index.ts
  7. 12 0
      src/style.css
  8. 0 0
      src/views/HomePage.vue

+ 85 - 0
package-lock.json

@@ -8,6 +8,7 @@
       "name": "bluewhale-frontend",
       "version": "0.0.0",
       "dependencies": {
+        "axios": "^1.6.2",
         "element-plus": "^2.4.2",
         "tailwindcss": "^3.3.5",
         "vue": "^3.3.8",
@@ -999,6 +1000,21 @@
       "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
       "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+    },
+    "node_modules/axios": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.6.2.tgz",
+      "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==",
+      "dependencies": {
+        "follow-redirects": "^1.15.0",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -1060,6 +1076,17 @@
         "fsevents": "~2.3.2"
       }
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/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": "4.1.1",
       "resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz",
@@ -1123,6 +1150,14 @@
         }
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/didyoumean": {
       "version": "1.2.2",
       "resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz",
@@ -1248,6 +1283,32 @@
         "node": ">=8"
       }
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.3",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.3.tgz",
+      "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/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/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1506,6 +1567,25 @@
         "node": ">=8.6"
       }
     },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/minimatch": {
       "version": "9.0.3",
       "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz",
@@ -1771,6 +1851,11 @@
       "resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
       "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+    },
     "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",

+ 1 - 0
package.json

@@ -9,6 +9,7 @@
     "preview": "vite preview"
   },
   "dependencies": {
+    "axios": "^1.6.2",
     "element-plus": "^2.4.2",
     "tailwindcss": "^3.3.5",
     "vue": "^3.3.8",

+ 1 - 0
src/App.vue

@@ -1,4 +1,5 @@
 <script setup lang="ts">
+
 </script>
 
 <template>

+ 50 - 32
src/components/Login.vue

@@ -1,74 +1,92 @@
 <script setup lang="ts">
-  import {ElButton, ElForm, ElFormItem} from "element-plus";
-  import { ref } from 'vue';
-
-  const loginForm = ref({
-    username: '',
-    password: '',
+  import {ElForm, ElFormItem} from "element-plus";
+  import { ref, computed } from 'vue';
+  import axios from "axios";
+  import {router} from '../router'
+
+  // 输入框的ref
+  const account = ref('')
+  const password = ref('')
+
+  // 用于计算
+  const loginDisabled = computed(() => {
+    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+    return !(emailRegex.test(account.value) && password.value.trim() !== '');
   });
 
   function handleLogin() {
-  // do nothing
+    axios.post(
+
+    )
+    console.log(account.value)
+    router.push({ path: "/home" })
   }
 
 </script>
 
 
-
 <template>
 
-  <div class="flex flex-col items-center justify-center px-6 mx-auto md:min-h-screen">
+  <div class="flex flex-col items-center justify-center px-6 py-6 space-y-10 min-h-screen">
 
-    <a href="#" class="flex items-center mb-16 text-3xl font-semibold text-gray-900">
+    <span class="flex items-center text-2xl font-semibold text-gray-900">
       Blue Whale Shopping Online
-    </a>
+    </span>
 
-    <el-card class="w-full bg-white rounded-lg shadow-md dark:border md:mt-0 sm:max-w-md xl:p-0">
+    <el-card class="w-full bg-white rounded-lg shadow-md md:mt-0 sm:max-w-md xl:p-0">
 
       <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
 
-        <h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
+        <h1 class="text-2xl font-bold leading-tight tracking-tight text-gray-900">
           登入您的账户
         </h1>
 
         <el-form class="space-y-4 md:space-y-6">
 
           <el-form-item>
-            <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">注册邮箱</label>
-            <input type="email" name="email" id="email"
+            <label for="email" class="block mb-2 text-sm font-medium text-gray-900">注册邮箱</label>
+            <input id="email" type="email" v-model="account"
+                   required
                    class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5"
                    placeholder="name@company.com">
           </el-form-item>
 
           <el-form-item>
-            <label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">账户密码</label>
-            <input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5" >
+            <label for="password" class="block mb-2 text-sm font-medium text-gray-900">账户密码</label>
+            <input id="password" type="password" v-model="password"
+                   required
+                   placeholder="••••••••"
+                   class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5" >
           </el-form-item>
 
-          <el-form-item class="pb-2">
-            <a href="#" class="text-sm font-medium text-primary-600 hover:underline dark:text-primary-500">
-              忘记密码?
-            </a>
-          </el-form-item>
+<!--          <el-form-item class="pb-2">-->
+<!--            <a href="#" class="text-sm font-medium text-primary-600 hover:underline">-->
+<!--              忘记密码?-->
+<!--            </a>-->
+<!--          </el-form-item>-->
 
-          <router-link to="/home" v-slot="{navigate}">
-            <el-button @click="navigate" class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
-              登入
-            </el-button>
-          </router-link>
+          <el-form-item>
+              <button @click.prevent="handleLogin"
+                      :disabled="loginDisabled"
+                      class="block my-3 w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-3 text-center disabled:bg-primary-100">
+                登入
+              </button>
+          </el-form-item>
 
-          <p class="text-sm font-light text-gray-500 dark:text-gray-400">
+          <p class="text-sm font-light text-gray-5000">
             还没有账户?
             <router-link to="/register" v-slot="{navigate}">
-              <a @click="navigate" class="font-medium text-primary-600 hover:underline dark:text-primary-500">
+              <span @click="navigate" class="font-medium text-primary-600 hover:underline">
                 点击注册
-              </a>
-            </router-link>
- 开启国货购物新体验
+              </span>
+            </router-link> 开启国货购物新体验
           </p>
+
         </el-form>
+
       </div>
 
+
     </el-card>
   </div>
 </template>

+ 61 - 22
src/components/Register.vue

@@ -1,59 +1,98 @@
 <script setup lang="ts">
+  import { ref, computed } from 'vue';
 
+  const email = ref('')
+  const tel = ref('')
+  const password = ref('')
+  const confirmPassword = ref('')
+
+  const registerDisabled = computed(() => {
+    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+    const chinaMobileRegex = /^1(3[0-9]|4[579]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[189])\d{8}$/;
+
+    return !(emailRegex.test(email.value) && chinaMobileRegex.test(tel.value) && password.value.trim() !== '' && (password.value == confirmPassword.value))
+  });
+
+  function handleRegister() {
+    console.log(email.value)
+  }
 </script>
 
 <template>
-  <div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen">
+  <div class="flex flex-col items-center justify-center px-6 py-6 space-y-10 min-h-screen">
 
-    <a href="#" class="flex items-center mb-16 text-3xl font-semibold text-gray-900">
+    <span class="flex items-center text-2xl font-semibold text-gray-900">
       Blue Whale Shopping Online
-    </a>
+    </span>
 
     <el-card class="w-full bg-white rounded-lg shadow-md md:mt-0 sm:max-w-md xl:p-0">
 
+
       <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
-        <h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
+
+        <h1 class="text-2xl font-bold leading-tight tracking-tight text-gray-900">
           创建一个新的账户
         </h1>
-        <el-form class="space-y-4 md:space-y-6" action="#">
+
+        <el-form class="space-y-4 md:space-y-6">
 
           <el-form-item>
             <label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">邮箱</label>
-            <input type="email"  class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+            <input id="email" type="email"
+                   v-model="email"
+                   class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5"
                    placeholder="name@company.com">
           </el-form-item>
 
           <el-form-item>
-            <label for="phone" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">手机号</label>
-            <input type="tel" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+            <label for="tel" class="block mb-2 text-sm font-medium text-gray-900">手机号</label>
+            <input type="tel" id="tel"
+                   v-model="tel"
+                   class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5"
                    placeholder="+86•••••••••••">
           </el-form-item>
 
           <el-form-item>
-            <label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">密码</label>
-            <input type="password" name="password" id="password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
+            <label for="password" class="block mb-2 text-sm font-medium text-gray-900">密码</label>
+            <input type="password" id="password"
+                   v-model="password"
+                   class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5"
+                   placeholder="••••••••">
           </el-form-item>
 
           <el-form-item>
-            <label class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">确认密码</label>
-            <input type="password" name="confirm-password" id="confirm-password" placeholder="••••••••" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
+            <label class="block mb-2 text-sm font-medium text-gray-900">确认密码</label>
+            <input type="password" id="confirm-password"
+                   v-model="confirmPassword"
+                   class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5"
+                   placeholder="••••••••">
           </el-form-item>
 
-          <el-form-item class="flex items-start">
+<!--          <el-form-item class="flex items-start">-->
+
+<!--            <div class="flex items-center h-5">-->
+<!--              <input id="terms" aria-describedby="terms" type="checkbox" class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300"-->
+<!--                     required>-->
+<!--            </div>-->
 
-            <div class="flex items-center h-5">
-              <input id="terms" aria-describedby="terms" type="checkbox" class="w-4 h-4 border border-gray-300 rounded bg-gray-50 focus:ring-3 focus:ring-primary-300 dark:bg-gray-700 dark:border-gray-600 dark:focus:ring-primary-600 dark:ring-offset-gray-800" required="">
-            </div>
+<!--            <div class="ml-3 text-sm">-->
+<!--              <label for="terms" class="font-light text-gray-500">-->
+<!--                我接受-->
+<!--                <a class="font-medium text-primary-600 hover:underline dark:text-primary-500" href="#">恶魔的条款</a>-->
+<!--              </label>-->
+<!--            </div>-->
 
-            <div class="ml-3 text-sm">
-              <label for="terms" class="font-light text-gray-500 dark:text-gray-300">我接受 <a class="font-medium text-primary-600 hover:underline dark:text-primary-500" href="#">恶魔的条款</a></label>
-            </div>
+<!--          </el-form-item>-->
 
+
+          <el-form-item>
+            <button @click.prevent="handleRegister"
+                    :disabled="registerDisabled"
+                    class="my-3 w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center disabled:bg-primary-100">
+              创建账户
+            </button>
           </el-form-item>
 
-          <button type="submit" class="w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800">
-            创建账户
-          </button>
 
           <p class="text-sm font-light text-gray-500 dark:text-gray-400">
             已经有账户了?

+ 2 - 2
src/router/index.ts

@@ -4,7 +4,7 @@ const router = createRouter({
     history: createWebHistory(),
     routes: [{
         path: '/',
-        component: () => import('../components/Login.vue'),
+        redirect: '/login',
     },{
         path: '/login',
         component: () => import('../components/Login.vue'),
@@ -13,7 +13,7 @@ const router = createRouter({
         component: () => import('../components/Register.vue'),
     }, {
         path: '/home',
-        component: () => import('../pages/HomePage.vue'),
+        component: () => import('../views/HomePage.vue'),
     }]
 })
 

+ 12 - 0
src/style.css

@@ -7,3 +7,15 @@
   line-height: 1.5;
   font-weight: 400;
 }
+
+html, body {
+  margin: 0;
+  padding: 0;
+  height: 100%;
+}
+
+#app {
+  margin: 0;
+  padding: 0;
+  height: 100%;
+}

+ 0 - 0
src/pages/HomePage.vue → src/views/HomePage.vue