Vue项目实战(第一部分)

Vue项目实战–第一部分

项目概述

  • PC端后台管理项目

  • 功能:
    在这里插入图片描述

  • 开发模式:采用前后端分离的开发模式,其中前端项目是基于Vue技术栈的SPA(单页面)项目。

  • 技术栈

    • Vue
    • Vue-router
    • Element-UI
    • Axios
    • Echarts

项目初始化

前端项目初始化步骤

  1. 安装vue脚手架
通过vue脚手架创建项目
配置Vue路由

vue ui内配置完成

配置Element-UI组件库
  • 添加插件
    在这里插入图片描述

  • 在这里插入图片描述

配置axios库
  • 安装依赖
    在这里插入图片描述
初始化git远程仓库
将本地项目托管到Github或码云中
  • 创建仓库

  • 在这里插入图片描述

  • 已有仓库

    cd existing_git_repo
    
    git status
    git add .
    git commit -m"add files"
    
    git remote add origin git@gitee.com:gezilzq/vue_shop.git
    git push -u origin master
    

( 后台项目环境安装配置)

也可以不在本地安装后台环境

使用其他人搭建的后台

  • 安装MySQL数据库
  • 安装Node.js环境
  • 配置项目相关信息
  • 启动项目
  • 使用Postman测试后台项目接口是否正常

后端接口文档

登录退出功能

登录概述

1.登录业务流程
  1. 在登录页面输入用户名和密码

  2. 调用后台接口进行验证

  3. 通过验证之后,根据后台的响应状态跳转到项目主页

2.登录业务的相关技术点
  • http是无状态的
  • 通过cookie在客户端记录状态
  • 通过session在服务器端记录状态
  • 通过token方式维持状态(存在跨域问题时)
    *在这里插入图片描述

关于登录业务所必须知道的cookie,session token的作用与区别

  • 登录状态保持
    如果服务器和客户端同源,建议可以使用cookie或者session来保持登录状态
    如果客户端和服务器跨域了,建议使用token进行维持登录状态。

  • 登录逻辑:
    在登录页面输入账号和密码进行登录,将数据发送给服务器
    服务器返回登录的结果,登录成功则返回数据中带有token
    客户端得到token并进行保存,后续的请求都需要将此token发送给服务器,服务器会验证token以保证用户身份。

登录功能实现

在进行功能增加时,往往在新的分支内完成

  • 添加新分支login,在login分支中开发当前项目`vue_shop:

    • 打开vue_shop终端,使用git status确定当前项目状态。

    • 确定当前工作目录是干净的之后,创建一个分支进行开发,开发完毕之后将其合并到master

    • git checkout -b login

    • 然后查看新创建的分支:git branch

      确定我们正在使用login分支进行开发

    在这里插入图片描述

运行项目的方式

在这里插入图片描述

(若是运行错误,可以回到VS里进行编译,查看错误信息,基本出现报错就得自己重新配了,可能可视化界面安装时网络不好,出现问题了)

登录页面的布局

通过 Element-UI 组件实现布局

  • 首先删除无用的示例,变为干净的项目结果

  • 建立组件文件,编写路由

在components文件夹中新建Login.vue组件,添加templatescriptstyle标签,style标签中的scoped可以防止组件之间的样式冲突,没有scoped则样式是全局的

<template>
    <div class="login_container">
        
    </div>
</template>

<script>
export default {
  
}
</script>

<style lang="less" scoped>
.login_container {
  background-color: #2b5b6b;
  height: 100%;
}
</style>

router.js中导入组件并设置规则
App.vue中添加路由占位符

const router = new Router({
  routes: [
    { path: '/', redirect: '/login' },
    { path: '/login', component: Login }
  ]
})

当我们给Login.vue中的内容添加样式的时候,会报错“缺少less-loader”,需要配置less加载器(开发依赖),安装less(开发依赖)
在这里插入图片描述

然后需要添加公共样式,在assets文件夹下面添加css文件夹,创建global.css文件,添加全局样式

/* 全局样式表 */
html,body,#app{
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0; 
}

main.js中导入global.css

使得全局样式生效import "./assets/css/global.css"
然后Login.vue中的根元素也需要设置撑满全屏(height:100%

随后根据登陆界面的设计进行<template><style lang="less" scoped>的编写

在这里插入图片描述

添加element-ui的表单组件

plugins文件夹中打开element.js文件,进行elementui的按需导入

import Vue from 'vue'

import { Button, Form, FormItem, Input } from 'element-ui'

Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
添加第三方字体图标

复制素材中的fonts文件夹到assets中,在入口文件main.js

导入import './assets/fonts/iconfont.css'
然后直接在 <el-input prefix-icon="iconfont icon-3702mima"></el-input>
接着添加登录盒子

最终可得以下代码(静态页面)

<template>
    <div class="login_container">
        <!-- 登录盒子  -->
        <div class="login_box">
            <!-- 头像 -->
            <div class="avatar_box">
                <img src="../assets/logo.png" alt="">
            </div>
            <!-- 登录表单 -->
            <el-form>
                <!-- 用户名 -->
                <el-form-item>
                    <el-input ></el-input>
                </el-form-item>
                <!-- 密码 -->
                <el-form-item>
                    <el-input></el-input>
                </el-form-item>
                <!-- 按钮 -->
                <el-form-item class="btns">
                    <el-button>登录</el-button>
                    <el-button>重置</el-button>
                </el-form-item>
            </el-form>
        </div>
    </div>
</template>
<style lang="less" scoped>
.login_container {
  background-color: #2b5b6b;
  height: 100%;
}
.login_box {
  width: 450px;
  height: 300px;
  background: #fff;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  .avatar_box {
    height: 130px;
    width: 130px;
    border: 1px solid #eee;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 0 10px #ddd;
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #fff;
    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: #eee;
    }
  }
}
.login_form {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}
.btns {
  display: flex;
  justify-content: flex-end;
}
</style>
添加表单验证的步骤

1).给<el-form>添加属性:rules="rules"rules是一堆验证规则,定义在script
2).在script中添加表单验证规则loginFormRules

3).通过<el-form-item>prop属性设置验证规则<el-form-item label="活动名称" prop="name">

具体使用参考element-ui官网

表单验证

data () {
    return {
      // 数据绑定
      loginForm: {
        username: 'admin',
        password: '123456'
      },
      // 表单验证规则
      loginFormRules: {
        username: [
          {
            required: true,
            message: '请输入登录名',
            trigger: 'blur'
          },
          {
            min: 3,
            max: 10,
            message: '登录名长度在 3 到 10 个字符',
            trigger: 'blur'
          }
        ],
        password: [
          {
            required: true,
            message: '请输入密码',
            trigger: 'blur'
          },
          {
            min: 6,
            max: 15,
            message: '密码长度在 6 到 15 个字符',
            trigger: 'blur'
          }
        ]
      }
    }
  },
实现重置按钮的功能

参考文档表单重置

方法名说明参数
resetFields对整个表单进行重置,将所有字段值重置为初始值并移除校验结果-
<el-form :model="loginForm"
         ref="LoginFormRef"     //添加ref属性,创建引用
         :rules="loginFormRules"
         label-width="0px"
         class="login_form">
 
··········
    
    <el-button type="info" @click="resetLoginForm">重置</el-button>
··········
 // 添加行为,
  methods: {
    // 添加表单重置方法
    resetLoginForm () {
      // this=>当前组件对象,其中的属性$refs包含了设置的表单ref
      //   console.log(this)
      this.$refs.LoginFormRef.resetFields()
    },
	········
  }
登陆前表单数据的预验证

参考文档validate

方法名说明参数
validate对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promiseFunction(callback: Function(boolean, object))
事件名称说明回调参数
validate任一表单项被校验后触发被校验的表单项 prop 值,校验是否通过,错误消息(如果存在)
 login() {
      //点击登录的时候先调用validate方法验证表单内容是否有误
      this.$refs.LoginFormRef.validate(async valid => {
        console.log(this.loginFormRules)
        //如果valid参数为true则验证通过
        if (!valid) {
          return
        }

        //发送请求进行登录
          ········
      })
}
导入axios以发送ajax请求

打开main.jsimport axios from 'axios';
设置请求的根路径:axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/';
挂载axiosVue.prototype.$http = axios;

// 发送请求进行登录
        const { data: res } = await this.$http.post('login', this.loginForm)
        //   console.log(res);
        if (res.meta.status !== 200) {
          return console.log("登录失败:"+res.meta.msg)
        }
配置Message全局弹框组件

官网文档Message组件

在plugins文件夹中打开element.js文件,进行elementui的按需导入
import {Message} from 'element-ui'
进行全局挂载:Vue.prototype.$message = Message;
login.vue组件中编写弹窗代码:this.$message.error('登录失败')

登录成功之后的操作

登录成功之后,需要将后台返回的token保存到sessionStorage
操作完毕之后,需要跳转到/home

//保存token
window.sessionStorage.setItem('token', res.data.token)
// 导航至/home
this.$router.push('/home')

添加一个组件Home.vue,并为之添加规则

<template>
    <div>
        this is home
        <el-button type="info" @click="logout"> 退出 </el-button>
    </div>
</template>

<script>
export default {
  methods: {
    logout() {
      window.sessionStorage.clear()
      this.$router.push('/login')
    }
  }
}
</script>

<style lang='less' scoped>
</style>

添加路由规则

const router = new Router({
  routes: [
    { path: '/', redirect: '/login' },
    { path: '/login', component: Login },
    { path: '/home', component: Home }
  ]
})
添加路由守卫

如果用户没有登录,不能访问/home,如果用户通过url地址直接访问,则强制跳转到登录页面
打开router.js

import Vue from 'vue'
import Router from 'vue-router'
import Login from './components/Login.vue'
import Home from './components/Home.vue'

Vue.use(Router)

const router = new Router({
  routes: [
    { path:'/', redirect:'/login'},
    { path:'/login' , component:Login },
    { path:'/home' , component:Home}
  ]
})

//挂载路由导航守卫,to表示将要访问的路径,from表示从哪里来,next是下一个要做的操作
router.beforeEach((to,from,next)=>{ 
  if(to.path === '/login')
    return next();
  
  //获取token
  const tokenStr = window.sessionStorage.getItem('token');

  if(!tokenStr)
    return next('/login');

  next();

})

export default router 

实现退出功能
在Home组件中添加一个退出功能按钮,给退出按钮添加点击事件,添加事件处理代码如下:

export default {
    methods:{
        logout(){
            window.sessionStorage.clear();
            this.$router.push('/login');
        }
    }
}

最终Login.vue文件中的代码如下

<template>
    <div class="login_container">
        <!-- 登录盒子  -->
        <div class="login_box">
            <!-- 头像 -->
            <div class="avatar_box">
                <img src="../assets/logo.png" alt="">
            </div>
            <!-- 登录表单 -->
            <el-form :model="loginForm" ref="LoginFormRef" :rules="loginFormRules" label-width="0px" class="login_form">
                <!-- 用户名 -->
                <el-form-item prop="username">
                    <el-input v-model="loginForm.username" prefix-icon="iconfont icon-user" ></el-input>
                </el-form-item> 
                <!-- 密码 -->
                <el-form-item prop="password">
                    <el-input type="password" v-model="loginForm.password" prefix-icon="iconfont icon-3702mima"></el-input>
                </el-form-item> 
                <!-- 按钮 -->
                <el-form-item class="btns">
                    <el-button type="primary" @click="login">登录</el-button>
                    <el-button type="info" @click="resetLoginForm">重置</el-button>
                </el-form-item> 
            </el-form>
        </div>
    </div>
</template>

<script>
export default {
  data() {
    return {
      //数据绑定
      loginForm: {
        username: 'admin',
        password: '123456'
      },
      //表单验证规则
      loginFormRules: {
        username: [
          { required: true, message: '请输入登录名', trigger: 'blur' },
          {
            min: 3,
            max: 10,
            message: '登录名长度在 3 到 10 个字符',
            trigger: 'blur'
          }
        ],
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          {
            min: 6,
            max: 15,
            message: '密码长度在 6 到 15 个字符',
            trigger: 'blur'
          }
        ]
      }
    }
  },
  //添加行为,
  methods: {
    //添加表单重置方法
    resetLoginForm() {
      //this=>当前组件对象,其中的属性$refs包含了设置的表单ref
      //   console.log(this)
      this.$refs.LoginFormRef.resetFields()
    },
    login() {
      //点击登录的时候先调用validate方法验证表单内容是否有误
      this.$refs.LoginFormRef.validate(async valid => {
        console.log(this.loginFormRules)
        //如果valid参数为true则验证通过
        if (!valid) {
          return
        }

        //发送请求进行登录
        const { data: res } = await this.$http.post('login', this.loginForm)
        //   console.log(res);
        if (res.meta.status !== 200) {
          return this.$message.error('登录失败:' + res.meta.msg) //console.log("登录失败:"+res.meta.msg)
        }

        this.$message.success('登录成功')
        console.log(res)
        //保存token
        window.sessionStorage.setItem('token', res.data.token)
        // 导航至/home
        this.$router.push('/home')
      })
    }
  }
}
</script>

<style lang="less" scoped>
.login_container {
  background-color: #2b5b6b;
  height: 100%;
}
.login_box {
  width: 450px;
  height: 300px;
  background: #fff;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  .avatar_box {
    height: 130px;
    width: 130px;
    border: 1px solid #eee;
    border-radius: 50%;
    padding: 10px;
    box-shadow: 0 0 10px #ddd;
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: #fff;
    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: #eee;
    }
  }
}
.login_form {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}
.btns {
  display: flex;
  justify-content: flex-end;
}
</style>

参考课程

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值