第66讲管理员登录功能实现

项目样式初始化

在这里插入图片描述
放assets目录下;

border.css

@charset "utf-8";
.border,
.border-top,
.border-right,
.border-bottom,
.border-left,
.border-topbottom,
.border-rightleft,
.border-topleft,
.border-rightbottom,
.border-topright,
.border-bottomleft {
   
    position: relative;
}
.border::before,
.border-top::before,
.border-right::before,
.border-bottom::before,
.border-left::before,
.border-topbottom::before,
.border-topbottom::after,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::before,
.border-topleft::after,
.border-rightbottom::before,
.border-rightbottom::after,
.border-topright::before,
.border-topright::after,
.border-bottomleft::before,
.border-bottomleft::after {
   
    content: "\0020";
    overflow: hidden;
    position: absolute;
}
/* border
 * 因,边框是由伪元素区域遮盖在父级
 * 故,子级若有交互,需要对子级设置
 * 定位 及 z轴
 */
.border::before {
   
    box-sizing: border-box;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    border: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-top::before,
.border-bottom::before,
.border-topbottom::before,
.border-topbottom::after,
.border-topleft::before,
.border-rightbottom::after,
.border-topright::before,
.border-bottomleft::before {
   
    left: 0;
    width: 100%;
    height: 1px;
}
.border-right::before,
.border-left::before,
.border-rightleft::before,
.border-rightleft::after,
.border-topleft::after,
.border-rightbottom::before,
.border-topright::after,
.border-bottomleft::after {
   
    top: 0;
    width: 1px;
    height: 100%;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
   
    border-top: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-right::before,
.border-rightbottom::before,
.border-rightleft::before,
.border-topright::after {
   
    border-right: 1px solid #eaeaea;
    transform-origin: 100% 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::before {
   
    border-bottom: 1px solid #eaeaea;
    transform-origin: 0 100%;
}
.border-left::before,
.border-topleft::after,
.border-rightleft::after,
.border-bottomleft::after {
   
    border-left: 1px solid #eaeaea;
    transform-origin: 0 0;
}
.border-top::before,
.border-topbottom::before,
.border-topleft::before,
.border-topright::before {
   
    top: 0;
}
.border-right::before,
.border-rightleft::after,
.border-rightbottom::before,
.border-topright::after {
   
    right: 0;
}
.border-bottom::before,
.border-topbottom::after,
.border-rightbottom::after,
.border-bottomleft::after {
   
    bottom: 0;
}
.border-left::before,
.border-rightleft::before,
.border-topleft::after,
.border-bottomleft::before {
   
    left: 0;
}
@media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) {
   
    /* 默认值,无需重置 */
}
@media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) {
   
    .border::before {
   
        width: 200%;
        height: 200%;
        transform: scale(.5);
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
   
        transform: scaleY(.5);
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
   
        transform: scaleX(.5);
    }
}
@media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) {
   
    .border::before {
   
        width: 300%;
        height: 300%;
        transform: scale(.33333);
    }
    .border-top::before,
    .border-bottom::before,
    .border-topbottom::before,
    .border-topbottom::after,
    .border-topleft::before,
    .border-rightbottom::after,
    .border-topright::before,
    .border-bottomleft::before {
   
        transform: scaleY(.33333);
    }
    .border-right::before,
    .border-left::before,
    .border-rightleft::before,
    .border-rightleft::after,
    .border-topleft::after,
    .border-rightbottom::before,
    .border-topright::after,
    .border-bottomleft::after {
   
        transform: scaleX(.33333);
    }
}

reset.css

@charset "utf-8";
html{
   background-color:#fff;color:#000;font-size:12px}
body,ul,ol,dl,dd,h1,h2,h3,h4,h5,h6,figure,form,fieldset,legend,input,textarea,button,p,blockquote,th,td,pre,xmp{
   margin:0;padding:0}
body,input,textarea,button,select,pre,xmp,tt,code,kbd,samp{
   line-height:1.5;font-family:tahoma,arial,"Hiragino Sans GB",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,small,big,input,textarea,button,select{
   font-size:100%}
h1,h2,h3,h4,h5,h6{
   font-family:tahoma,arial,"Hiragino Sans GB","微软雅黑",simsun,sans-serif}
h1,h2,h3,h4,h5,h6,b,strong{
   font-weight:normal}
address,cite,dfn,em,i,optgroup,var{
   font-style:normal}
table{
   border-collapse:collapse;border-spacing:0;text-align:left}
caption,th{
   text-align:inherit}
ul,ol,menu{
   list-style:none}
fieldset,img{
   border:0}
img,object,input,textarea,button,select{
   vertical-align:middle}
article,aside,footer,header,section,nav,figure,figcaption,hgroup,details,menu{
   display:block}
audio,canvas,video{
   display:inline-block;*display:inline;*zoom:1}
blockquote:before,blockquote:after,q:before,q:after{
   content:"\0020"}
textarea{
   overflow:auto;resize:vertical}
input,textarea,button,select,a{
   outline:0 none;border: none;}
button::-moz-focus-inner,input::-moz-focus-inner{
   padding:0;border:0}
mark{
   background-color:transparent}
a,ins,s,u,del{
   text-decoration:none}
sup,sub{
   vertical-align:baseline}
html {
   overflow-x: hidden;height: 100%;font-size: 50px;-webkit-tap-highlight-color: transparent;}
body {
   font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;color: #333;font-size: .28em;line-height: 1;-webkit-text-size-adjust: none;}
hr {
   height: .02rem;margin: .1rem 0;border: medium none;border-top: .02rem solid #cacaca;}
a {
   color: #25a4bb;text-decoration: none;}

main.js里面引入即可:

import '././assets/styles/border.css'
import '././assets/styles/reset.css'

静态登录页面实现

在这里插入图片描述

<template>
  <div class="login-container">
    <el-form :model="form" class="login-form">
      <div class="title-container">
        <h3 class="title">Java1234Mall-管理员登录</h3>
      </div>
      <el-form-item >
        <el-icon :size="20" class="svg-container">
          <edit />
        </el-icon>
        <el-input v-model="form.userName" placeholder="请输入用户名..."/>
      </el-form-item>
      <el-form-item >
        <el-icon :size="20" class="svg-container">
          <edit />
        </el-icon>
        <el-input v-model="form.password" type="password" placeholder="请输入密码.." />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" class="login-button">登录</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<script setup>
import {
    ref } from 'vue'
import {
    Edit } from '@element-plus/icons-vue'
const form=ref({
   
  userName:'',
  password:''
})
</script>

<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #889aa4;
$light_gray: #eee;
$cursor: #fff;

.login-container {
   
  min-height: 100%;
  width: 100%;
  background-color: $bg;
  overflow: hidden;

  .login-form {
   
    position: relative;
    width: 520px;
    max-width: 100%;
    padding: 160px 35px 0;
    margin: 0 auto;
    overflow: hidden;

    ::v-deep .el-form-item {
   
      border: 1px solid rgba(255, 255, 255, 0.1);
      background: rgba(0, 0, 0, 0.1);
      border-radius: 5px;
      color: #454545;
    }

    ::v-deep .el-form-item__content{
   
      color: #454545;
      background: rgba(0, 0, 0, 0.1);
    }

    ::v-deep .el-input__wrapper {
   
      display: block;
      color: #454545;
      background: rgb(36,47,60);
      box-shadow:none;
    }

    ::v-deep .el-input {
   
      display: inline-block;
      background: rgb(36,47,60);
      height: 47px;
      width: 85%;

      input {
   
        background: transparent;
        border: 0px;
        -webkit-appearance: none;
        border-radius: 0px;
        padding: 12px 5px 12px 15px;
        color: $light_gray;
        height: 47px;
        caret-color: $cursor;
      }
    }
    .login-button {
   
      width: 100%;
      box-sizing: border-box;
    }
  }

  .tips {
   
    font-size: 16px;
    line-height: 28px;
    color: #fff;
    margin-bottom: 10px;

    span {
   
      &:first-of-type {
   
        margin-right: 16px;
      }
    }
  }

  .svg-container {
   
    padding: 6px 5px 6px 15px;
    color: $dark_gray;
    vertical-align: middle;
    display: inline-block;

  }

  .title-container {
   
    position: relative;

    .title {
   
      font-size: 26px;
      color: $light_gray;
      margin: 0px auto 40px auto;
      text-align: center;
      font-weight: bold;
    }

    ::v-deep .lang-select {
   
      position: absolute;
      top: 4px;
      right: 0;
      background-color: white;
      font-size: 22px;
      padding: 4px;
      border-radius: 4px;
      cursor: pointer;
    }
  }

  .show-pwd {
   
    // position: absolute;
    // right: 10px;
    // top: 7px;
    font-size: 16px;
    color: $dark_gray;
    cursor: pointer;
    user-select: none;
  }
}
</style>

::v-deep 样式穿透 深度作用选择器

直接在 中编写的话只会影响当前组件内的样式,但如果去掉scoped话又会影响全局样式。 我们::v-deep可以作用其他组件,修改其他组件样式

App.vue

<template>
  <router-view/>
</template>

<style>
html,body,#app{
   
  height: 100%;
}
</style>

报错-sass-loader

在vue里运行报错:Failed to resolve loader: sass-loader You may need to install it.提示需要安装sass模块

在这里插入图片描述

router/index.js

import {
    createRouter, createWebHashHistory } from 'vue-router'

const routes = [
  {
   
    path:'/login',
    name:'login',

    component:()=>import('../views/login')
  }
]

const router = createRouter({
   
  history: createWebHashHistory(),
  routes
})

export default router

相关推荐

  1. 69后端登录逻辑实现

    2024-02-12 04:06:01       38 阅读
  2. 63个人中心用户信息动态显示实现

    2024-02-12 04:06:01       53 阅读
  3. Django 实现登录功能

    2024-02-12 04:06:01       35 阅读
  4. React实现登录授权功能

    2024-02-12 04:06:01       66 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-12 04:06:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-12 04:06:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-12 04:06:01       82 阅读
  4. Python语言-面向对象

    2024-02-12 04:06:01       91 阅读

热门阅读

  1. linux赋予普通用户权限

    2024-02-12 04:06:01       55 阅读
  2. Linux 禁用/启用 交换分区

    2024-02-12 04:06:01       60 阅读
  3. vue3-应用规模化-单文件组件

    2024-02-12 04:06:01       50 阅读
  4. Dockerfile命令

    2024-02-12 04:06:01       50 阅读
  5. 解锁 SpringBoot 强大配置功能

    2024-02-12 04:06:01       45 阅读
  6. vector基本用法(可变长数组)

    2024-02-12 04:06:01       43 阅读
  7. Docker-CE 国内源国内镜像

    2024-02-12 04:06:01       61 阅读
  8. Debezium发布历史121

    2024-02-12 04:06:01       55 阅读
  9. 网络编程面试系列-02

    2024-02-12 04:06:01       49 阅读
  10. 【国产MCU】-CH32V307-触摸按键检测(TKEY)

    2024-02-12 04:06:01       54 阅读
  11. freertos 源码分析六 任务调度二

    2024-02-12 04:06:01       55 阅读