Browse Source

更新input组件

fxs 9 months ago
parent
commit
4f6f5f0f1c

+ 4 - 0
components.d.ts

@@ -35,10 +35,14 @@ declare module 'vue' {
     ElTooltip: typeof import('element-plus/es')['ElTooltip']
     FilterPopover: typeof import('./src/components/toolsBtn/FilterPopover.vue')['default']
     IconEpHistogram: typeof import('~icons/ep/histogram')['default']
+    IconEpMaterialSymbolsLightLogout: typeof import('~icons/ep/material-symbols-light-logout')['default']
     IconEpPieChart: typeof import('~icons/ep/pie-chart')['default']
+    IconMaterialSymbolsLightLogout: typeof import('~icons/material-symbols-light/logout')['default']
+    IconMaterialSymbolsLightLogoutLogout: typeof import('~icons/material-symbols-light/logout-logout')['default']
     RegreshBtn: typeof import('./src/components/toolsBtn/RegreshBtn.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     Table: typeof import('./src/components/Table.vue')['default']
+    TextInput: typeof import('./src/components/input/TextInput.vue')['default']
   }
 }

+ 11 - 0
package-lock.json

@@ -21,6 +21,7 @@
       },
       "devDependencies": {
         "@iconify-json/ep": "^1.1.16",
+        "@iconify-json/material-symbols-light": "^1.1.28",
         "@rushstack/eslint-patch": "^1.8.0",
         "@tsconfig/node20": "^20.1.4",
         "@types/node": "^20.14.5",
@@ -700,6 +701,16 @@
         "@iconify/types": "*"
       }
     },
+    "node_modules/@iconify-json/material-symbols-light": {
+      "version": "1.1.28",
+      "resolved": "https://registry.npmmirror.com/@iconify-json/material-symbols-light/-/material-symbols-light-1.1.28.tgz",
+      "integrity": "sha512-SoXeymM+JaORZ+6TdS6K6tx3avf3LghwYw8GI2zX/SdGbFLCOejMy491/0ucs1h4iIgELLFlyUGKeIRlbfmL8g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "@iconify/types": "*"
+      }
+    },
     "node_modules/@iconify/types": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/@iconify/types/-/types-2.0.0.tgz",

+ 1 - 0
package.json

@@ -26,6 +26,7 @@
   },
   "devDependencies": {
     "@iconify-json/ep": "^1.1.16",
+    "@iconify-json/material-symbols-light": "^1.1.28",
     "@rushstack/eslint-patch": "^1.8.0",
     "@tsconfig/node20": "^20.1.4",
     "@types/node": "^20.14.5",

+ 0 - 2
src/components/Table.vue

@@ -195,13 +195,11 @@ onMounted(() => {
         </el-button>
 
         <RegreshBtn @refresh-table="getData" :icon-size="toolsIconSize"></RegreshBtn>
-        <!-- <el-icon :size="toolsIconSize" class="rightToolsItem"><RefreshRight /></el-icon> -->
 
         <FilterPopover
           :table-fields-info="tableFieldsInfo"
           :icon-size="toolsIconSize"
         ></FilterPopover>
-        <!-- <el-icon :size="toolsIconSize" class="rightToolsItem"><Setting /></el-icon> -->
       </div>
     </div>
 

+ 78 - 0
src/components/input/TextInput.vue

@@ -0,0 +1,78 @@
+<script setup lang="ts">
+import { onMounted, ref } from 'vue'
+
+interface InputInfo {
+  inputObj: {
+    inputValue: string
+    inputType: string
+  }
+}
+// 不要传一个基本类型进来双向绑定会报错
+// 可以用definemodel或者直接传一个对象
+defineProps<InputInfo>()
+
+const inputDivRef = ref()
+
+const activeClass = ref(false)
+
+onMounted(() => {
+  document.addEventListener('click', (e) => {
+    // 如果点击的地方不在 div 内部,则移除 active-class
+    if (inputDivRef.value && !inputDivRef.value.contains(e.target)) {
+      activeClass.value = false
+    } else {
+      activeClass.value = true
+    }
+  })
+})
+</script>
+
+<template>
+  <div class="inputBox" ref="inputDivRef" :class="{ activeInput: activeClass }">
+    <div class="icon">
+      <el-icon><UserFilled /></el-icon>
+    </div>
+    <input :type="inputObj.inputType" v-model="inputObj.inputValue" />
+  </div>
+</template>
+
+<style scoped>
+.inputBox {
+  min-height: 32px;
+  width: 100%;
+  display: flex;
+  align-items: center;
+  background-color: #f2f3f5;
+  padding: 0 5px;
+  border-radius: 2px;
+}
+
+.inputBox:hover {
+  background-color: #dbdcdf;
+}
+
+.activeInput {
+  border: 1px solid #165dff;
+}
+
+.icon {
+  padding-right: 12px;
+}
+
+input {
+  width: 100%;
+  background: none;
+  outline: none;
+  border: none;
+}
+
+/* 如果input必须要有边框,但需要去掉选中时的蓝色框 ↓↓↓ */
+input {
+  background: none;
+  outline: none;
+  /* border: 1px solid #ccc; */
+}
+input:focus {
+  border: none;
+}
+</style>

+ 1 - 0
src/components/toolsBtn/FilterPopover.vue

@@ -18,6 +18,7 @@ defineProps<SettingInfo>()
         <template #reference>
           <el-icon :size="iconSize" class="rightToolsItem"><Setting /></el-icon>
         </template>
+        <!-- 这里不是使用vlue是v-model去绑定数据 -->
         <el-checkbox v-for="item in tableFieldsInfo" :label="item.cnName" v-model="item.isShow" />
       </el-popover>
     </span>

+ 3 - 3
src/views/Home/GameManageView.vue

@@ -275,10 +275,10 @@ const submiteGameChange = () => {
 
 <style scoped>
 .gameMangeBox {
-  width: 100%;
-  /* height: 100%; */
-  padding-top: 2%;
+  width: 98%;
+  margin: 1% auto;
   background-color: white;
+  border: 1px solid #e5e6eb;
 }
 
 .operationBtn {

+ 62 - 4
src/views/Home/HomeView.vue

@@ -1,6 +1,8 @@
 <script setup lang="ts">
 import { RouterView } from 'vue-router'
 import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import router from '@/router'
 
 const isCollapse = ref(false)
 const menuList = [
@@ -33,6 +35,17 @@ const menuList = [
 const changeCollapse = () => {
   isCollapse.value = !isCollapse.value
 }
+
+const logOut = () => {
+  ElMessage({
+    type: 'success',
+    message: '退出成功',
+    duration: 1000
+  })
+  localStorage.removeItem('token')
+  localStorage.removeItem('refreshToken')
+  router.push('/login')
+}
 </script>
 
 <template>
@@ -57,8 +70,17 @@ const changeCollapse = () => {
     </div>
     <div class="navBarBox">
       <div class="headPortraitBox">
-        <!-- <el-avatar :size="40" src="/src/assets/default/defaultHead.png" /> -->
-        <el-image class="headPortrait" src="/src/assets/default/defaultHead.png"></el-image>
+        <el-popover popper-class="headPopper" placement="bottom-end" trigger="click">
+          <template #reference>
+            <el-image class="headPortrait" src="/src/assets/default/defaultHead.png"></el-image>
+          </template>
+          <div class="userTools">
+            <span class="userToolsItem" @click="logOut">
+              <icon-material-symbols-light-logout></icon-material-symbols-light-logout>
+              <span> 退出登录</span>
+            </span>
+          </div>
+        </el-popover>
       </div>
     </div>
     <div class="content">
@@ -147,14 +169,40 @@ const changeCollapse = () => {
 }
 
 .headPortraitBox {
-  /* width: 5vw; */
-  /* height: 5vh; */
   position: absolute;
   right: 3%;
   top: 50%;
   transform: translateY(-50%);
 }
 
+.userTools {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-around;
+  align-items: center;
+}
+
+.userToolsItem {
+  cursor: pointer;
+  width: 100%;
+  height: 4vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  /* padding: 10px; */
+  margin: 2%;
+}
+
+.userToolsItem > span {
+  margin-left: 10%;
+}
+
+.userToolsItem:hover {
+  background-color: #f2f3f5;
+}
+
 .headPortrait {
   cursor: pointer;
   width: 50px;
@@ -173,3 +221,13 @@ const changeCollapse = () => {
   top: 0vh;
 }
 </style>
+
+<!-- 为了让popper-class生效,需要的单独写一份 -->
+<style>
+.headPopper {
+  padding: 0px !important;
+  border: 1px solid #e5e6eb;
+
+  background-color: white;
+}
+</style>

+ 12 - 6
src/views/Home/OverView.vue

@@ -1,9 +1,15 @@
-<script setup lang="ts">
-import { onMounted, reactive, ref } from 'vue'
-// let a = ref(0)
-</script>
+<script setup lang="ts"></script>
 <template>
-  <div class="gameMangeBox">test</div>
+  <div class="overViewBox">
+    <div class="header"></div>
+  </div>
 </template>
 
-<style></style>
+<style scoped>
+.overViewBox {
+  width: 98%;
+  margin: 1% auto;
+  background-color: white;
+  border: 1px solid #e5e6eb;
+}
+</style>

+ 0 - 2
src/views/Home/PlayerManageView.vue

@@ -352,8 +352,6 @@ onMounted(() => {
 .gameMangeBox {
   width: 98%;
   margin: 1% auto;
-  /* height: 100%; */
-  /* padding-top: 2%; */
   background-color: white;
   border: 1px solid #e5e6eb;
 }

+ 83 - 35
src/views/Login/LoginView.vue

@@ -4,6 +4,7 @@ import type { FormRules, FormInstance } from 'element-plus'
 import { useRequest } from '@/hooks/useRequest'
 import router from '@/router'
 import axiosInstance from '@/utils/axios/axiosInstance'
+import TextInput from '@/components/input/TextInput.vue'
 
 const { AllApi, analysisResCode } = useRequest()
 
@@ -61,54 +62,101 @@ onMounted(() => {})
 </script>
 
 <template>
-  <div class="loginBox">
-    <el-form
-      ref="loginFormRef"
-      class="loginForm"
-      :rules="rules"
-      :model="loginInfo"
-      label-width="auto"
-      style="max-width: 600px"
-    >
-      <el-form-item label="用户名" prop="userName">
-        <el-input class="formItem" v-model="loginInfo.userName" />
-      </el-form-item>
-      <el-form-item label="密码" prop="password">
-        <el-input class="formItem" v-model="loginInfo.password" />
-      </el-form-item>
-      <el-form-item>
-        <el-button type="primary" @click="onSubmit(loginFormRef)">登录</el-button>
-      </el-form-item>
-    </el-form>
+  <div class="container">
+    <div class="loginBox">
+      <div class="banner"></div>
+      <div class="logo"></div>
+      <div class="content">
+        <div class="loginFormBox">
+          <div class="loginFormTitle">登录管理系统</div>
+          <div class="loginFormSubTitle">登录管理系统</div>
+          <form class="loginForm">
+            <TextInput
+              :input-obj="{
+                inputType: 'text',
+                inputValue: loginInfo.userName
+              }"
+            ></TextInput>
+          </form>
+          <!-- <el-form
+            ref="loginFormRef"
+            class="loginForm"
+            :rules="rules"
+            :model="loginInfo"
+            label-width="auto"
+          >
+            <el-form-item label="用户名" prop="userName">
+              <el-input class="formItem" v-model="loginInfo.userName" />
+            </el-form-item>
+            <el-form-item label="密码" prop="password">
+              <el-input class="formItem" v-model="loginInfo.password" />
+            </el-form-item>
+            <el-form-item>
+              <el-button type="primary" @click="onSubmit(loginFormRef)">登录</el-button>
+            </el-form-item>
+          </el-form> -->
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
 <style scoped lang="less">
-.loginBox {
+.container {
   width: 100vw;
   height: 100vh;
   background-color: lightblue;
-  //   position: relative;
-  //   left: 50%;
-  //   top: 50%;
-  //   transform: translate(-50%, -50%);
-  //   background-color: lightblue;
+  position: relative;
+}
+
+.loginBox {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  width: 900px;
+  height: 500px;
+  background-color: lightcoral;
+  display: flex;
+}
+
+.banner {
+  width: 400px;
+  height: 100%;
+  background-color: lightgreen;
+}
+
+.content {
+  width: 500px;
+  position: relative;
+  background-color: white;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.loginFormBox {
+  width: 320px;
+}
+.loginFormTitle {
+  color: black;
+  font-weight: 500;
+  font-size: 24px;
+  line-height: 32px;
+}
+
+.loginFormSubTitle {
+  color: rgb(134, 144, 156);
+  font-size: 16px;
+  line-height: 24px;
 }
 
 .loginForm {
-  width: 25vw;
-  height: 40vh;
+  width: 100%;
   display: flex;
   flex-direction: column;
-  justify-content: center;
+
   align-items: center;
-  position: relative;
-  left: 50%;
-  top: 50%;
-  transform: translate(-50%, -50%);
-  background: rgba(255, 255, 255, 0.7);
-  backdrop-filter: blur(30px);
-  border-radius: 15px;
 }
 
 .formItem {

+ 3 - 1
tsconfig.app.json

@@ -5,7 +5,9 @@
     "src/**/*.d.ts",
     "src/**/*.tsx",
     "src/**/*.vue",
-    "src/components/toolsPopover/FilterPopover.vue"
+    "src/components/toolsPopover/FilterPopover.vue",
+    "src/components/input/TextInput.vue",
+    "src/components/input/TextInput.VUE"
   ],
   "exclude": ["src/**/__tests__/*"],
   "compilerOptions": {

+ 2 - 8
vite.config.ts

@@ -14,19 +14,13 @@ export default defineConfig({
   plugins: [
     vue(),
     AutoImport({
-      resolvers: [
-        ElementPlusResolver(),
-        IconsResolver({
-          enabledCollections: ['ep']
-        })
-      ]
+      resolvers: [ElementPlusResolver()]
     }),
     Components({
       resolvers: [
         ElementPlusResolver(),
         IconsResolver({
-          prefix: 'icon',
-          enabledCollections: ['ep']
+          prefix: 'icon'
         })
       ]
     }),