vue基础教程(5)——构建项目级登录页

同学们可以私信我加入学习群!


正文开始


前言

前面我们已经把vue自带的页面删除,也搭建了最简单的router路由,下面就可以真正开发我们自己的项目了,一般而言,很少有人从零开始写代码,博主也是为了完善这个系列博客,才会从零开始,把关键的代码都敲了一遍。

哪怕同学们有自己心仪的项目,搭建基础的架构,跟着博主学一遍关键的知识点,也有助于以后优化升级项目,修改别人的代码或者修复bug。

跟着博主写一遍,大概率是可以真正把控全局,把vue如何搭建网站彻底搞明白。


一、创建首页

上篇文章讲到,我们会习惯把所有路由信息都保存到一个js文件中,作为路由模块。例如:

c 复制代码
export default [
  {
    path: '/',
    name: 'login',
    meta: {
      title: '登录',
      hideInMenu: true
    },
    component: () => import('@module-base/views/login/login.vue')
  },
  ...
]

这段代码就是记录了部分路由信息,我们路由数组的第一个元素,一般就是项目默认登录的地址。component字段就是对应的组件,它的地址是默认地址"/",如果我们把项目运行到localhost:5173,那么只要我们在浏览器输入localhost:5173或者localhost:5173/,就会跳转到login.vue组件的内容。

我们login.vue中的代码十分简单,就是一个背景图+一个登录卡片,这是基础的html和vue知识,我们下面会一一讲解。

最终效果如图:

二、登录页代码讲解

只关注实战的同学可以快速略过代码讲解部分。

本系列主要为vue教程,所以可能在涉及html、js的基础知识时,会重点讲解,因为这属于上手vue的必学必会技能,但是css3相关知识可能会弱化,一个原因是知识点比较多,一个原因是新手入门抄样式也能磕磕绊绊地做项目。对css感兴趣同学,可以看博主源码,自行查阅资料。

登录代码可以分解为两个部分:

1.卡片组件

2.登录逻辑

  • 卡片组件
c 复制代码
<Card title="欢迎登录" :bordered="false">
        <div class="form-con">
          <login-form @on-success-valid="handleSubmit"></login-form>
          <p class="login-tip">输入任意用户名和密码即可</p>
        </div>
      </Card>

这是iview提供的卡片组件,如果使用其它ui库,参考对应官网代码即可,都是换汤不换药。

关键代码讲解:

title:组件的标题

bordered:是否有边框

login-form:是一个组件,把form表单相关功能封装到一个单独的组件中,然后vue会把login-form组件里的所有内容,最终都渲染到这个位置

@on-success-valid:@标记是vue提供的语法,代表监听事件,这里就是监听一个名叫"on-success-valid"的事件。

这里涉及到了login-form组件,所以我们再看这个组件的代码:

c 复制代码
<Form ref="loginForm" :model="form" :rules="rules" @keydown.enter.native="handleSubmit">
    <FormItem prop="userName">
      <Input v-model="form.userName" placeholder="请输入用户名">
        <span slot="prepend">
          <Icon :size="16" type="ios-person"></Icon>
        </span>
      </Input>
    </FormItem>
    <FormItem prop="password">
      <Input type="password" v-model="form.password" placeholder="请输入密码">
        <span slot="prepend">
          <Icon :size="14" type="md-lock"></Icon>
        </span>
      </Input>
    </FormItem>
    <FormItem>
      <Button @click="handleSubmit" class="c-btn-primary" long>登录</Button>
    </FormItem>
  </Form>

这段代码里,主要用到了iview的form组件,Form标签用来包裹在最外面,fomritem指表单中的每一个表单项,这里一共有三项:姓名输入框、密码输入框、登录按钮。

其他代码都是一些辅助代码,为了让我们的表单样式看起来更舒服,我们重点关注登录按钮,它定义了一个事件:handleSubmit。

我们上面讲过,在html元素中,@是vue定义的一个语法,代表着事件监听,@click不同于上面提到的@on-success-valid,是官方定义的监听事件,意思是监听点击事件。

完整逻辑就是在登录这个按钮上,监听了点击事件,当发现登录按钮被点击后,就调用后面定义的方法handleSubmit。我们继续看handleSubmit的代码:

c 复制代码
 methods: {
    handleSubmit () {
      this.$refs.loginForm.validate((valid) => {
        if (valid) {
          this.$emit('on-success-valid', {
            userName: this.form.userName,
            password: this.form.password
          })
        }
      })
    }
  }

它先通过this.$refs.loginForm.validate验证上面的表单元素是否合规,如果合规的话,就运行后面emit的代码,emit是vue定义的触发方法,这里代码要触发一个叫on-success-valid的方法,这个方法是不是很熟悉?不错,它就是我们在login.vue中监听的方法@on-success-valid。

到这里,逻辑就比较清晰了,login.vue中引入了一个card组件,card组件是view提供的官方组件,card组件中引入了login-form组件,login-form组件是我们自己写的组件,并且在引入组件时,我们写了@on-success-valid用来监听login-form组件中触发的on-success-valid方法。

login-form中定义了一个点击事件,当点击登录按钮时,触发on-success-valid,这个信号被login.vue接收到,login.vue就会去调用@on-success-valid监听后面定义的方法。代码如下:

c 复制代码
 <login-form @on-success-valid="handleSubmit"></login-form>

在login.vue中也叫handleSubmit方法,找到login.vue中的handleSubmit方法:

c 复制代码
 handleSubmit ({ userName, password }) {
      this.$router.push({
        name: '_home'
      })
    }

发现它主要做了一件事,那就是利用router插件提供的方法,跳转到_home页面。

至此,一个最简单的登录逻辑完成。

三、对应的vue知识点:

1.@click、@on-success-valid是vue中事件监听的语法,意思是监听后面的操作,当发现触发了对应的操作,就调用对应的方法。

2.vue中最重要的就是组件的思想,不管是使用ui框架提供的组件,还是自定义组件,都是在一个大组件中拼接各种小组件,共同构成一个完整页面。每个组件只需要关注自己的功能,把所有功能串联起来,就是页面的完整功能。

3.代码中出现的:value、:size、:model等,是vue中v-bind语法的变种,等价于v-bind:value,v-bind:size,v-bind:model,这是在定义html元素的属性,不同于直接在html中写attribute,vue中这种语法,可以绑定一个动态变量,动态设置属性更加灵活。

四、附件-各文件代码

login.vue:

c 复制代码
<style lang="less">
  @import './login.less';

</style>

<template>
  <div class="login">
    <div class="login-con">
      <Card icon="log-in" title="欢迎登录" :bordered="false">
        <div class="form-con">
          <login-form @on-success-valid="handleSubmit"></login-form>
          <p class="login-tip">输入任意用户名和密码即可</p>
        </div>
      </Card>
    </div>
    <div style="position: absolute;bottom: 8px;width: 100%;display: flex;justify-content: center;color: white">
      <a href="https://beian.miit.gov.cn/" target="_blank">冀ICP备2022011594号-1</a>
    </div>

  </div>
</template>

<script>
import LoginForm from '_c/login-form'

export default {
  components: {
    LoginForm
  },
  methods: {
    handleSubmit ({ userName, password }) {
      this.$router.push({
        name: '_home'
      })
    }
  }
}
</script>

<style scoped>
</style>

login-form.vue:

c 复制代码
<template>
  <Form ref="loginForm" :model="form" :rules="rules" @keydown.enter.native="handleSubmit">
    <FormItem prop="userName">
      <Input v-model="form.userName" placeholder="请输入用户名">
        <span slot="prepend">
          <Icon :size="16" type="ios-person"></Icon>
        </span>
      </Input>
    </FormItem>
    <FormItem prop="password">
      <Input type="password" v-model="form.password" placeholder="请输入密码">
        <span slot="prepend">
          <Icon :size="14" type="md-lock"></Icon>
        </span>
      </Input>
    </FormItem>
    <FormItem>
      <Button @click="handleSubmit" class="c-btn-primary" long>登录</Button>
    </FormItem>
  </Form>
</template>
<script>
export default {
  name: 'LoginForm',
  props: {
    userNameRules: {
      type: Array,
      default: () => {
        return [
          { required: true, message: '账号不能为空', trigger: 'blur' }
        ]
      }
    },
    passwordRules: {
      type: Array,
      default: () => {
        return [
          { required: true, message: '密码不能为空', trigger: 'blur' }
        ]
      }
    }
  },
  data () {
    return {
      form: {
        userName: 'super_admin',
        password: ''
      }
    }
  },
  computed: {
    rules () {
      return {
        userName: this.userNameRules,
        password: this.passwordRules
      }
    }
  },
  methods: {
    handleSubmit () {
      this.$refs.loginForm.validate((valid) => {
        if (valid) {
          this.$emit('on-success-valid', {
            userName: this.form.userName,
            password: this.form.password
          })
        }
      })
    }
  }
}
</script>

总结

获取资源,或者联系我,都可以通过下面入口:

https://lizetoolbox.top:8080/qrCode_contact

相关推荐
神仙别闹21 分钟前
基于C语言实现B树存储的图书管理系统
c语言·前端·b树
玄魂39 分钟前
如何查看、生成 github 开源项目star 图表
前端·开源·echarts
前端一小卒1 小时前
一个看似“送分”的需求为何翻车?——前端状态机实战指南
前端·javascript·面试
syt_10131 小时前
Object.defineProperty和Proxy实现拦截的区别
开发语言·前端·javascript
遝靑2 小时前
Flutter 跨端开发进阶:可复用自定义组件封装与多端适配实战(移动端 + Web + 桌面端)
前端·flutter
cypking2 小时前
Web前端移动端开发常见问题及解决方案(完整版)
前端
长安牧笛2 小时前
儿童屏幕时间管控学习引导系统,核心功能,绑定设备,设时长与时段,识别娱乐,APP超时锁屏,推荐益智内容,生成使用报告,学习达标解锁娱乐
javascript
老前端的功夫2 小时前
Vue 3 vs Vue 2 深度解析:从架构革新到开发体验全面升级
前端·vue.js·架构
栀秋6662 小时前
深入浅出链表操作:从Dummy节点到快慢指针的实战精要
前端·javascript·算法
狗哥哥2 小时前
Vue 3 动态菜单渲染优化实战:从白屏到“零延迟”体验
前端·vue.js