Vue 项目实战一 电商项目系列 01项目初始化和登录页面

----------------------- GIT规范 ---------------------------

Commit message格式
<type>: <subject>

注意冒号后面有空格。

  1. type用于说明 commit 的类别,只允许使用下面7个标识。
  2. feat:新功能(feature)
  3. fix:修补bug
  4. docs:文档(documentation)
  5. style: 格式(不影响代码运行的变动)
  6. refactor:重构(即不是新增功能,也不是修改bug的代码变动)
  7. test:增加测试
  8. chore:构建过程或辅助工具的变动
    如果type为feat和fix,则该 commit 将肯定出现在 Change log 之中。

------------------- 项目概述 -----------------------

根据不同的应用场景,电商系统一般都提供了 PC 端、移动 APP、移动 Web、微信小程序等多种终端访问方式

1.2 电商后台管理系统的功能

电商后台管理系统用于管理用户账号、商品分类、商品信息、订单、数据统计等业务功能。

1.3 电商后台管理系统的开发模式(前后端分离)

电商后台管理系统整体采用前后端分离的开发模式,其中前端项目是基于 Vue 技术栈的 SPA 项目

1.4 电商后台管理系统的技术选型

  1. 前端项目技术栈
    Vue
    Vue-router
    Element-UI
    Axios
    Echarts
  2. 后端项目技术栈
    Node.js
    Express
    Jwt
    Mysql
    Sequelize

--------------------- 项目初始化 ------------------------

2.1 前端项目初始化步骤

  1. 安装 Vue 脚手架
  vue create 文件名  通过命令来安装
  1. 通过 Vue 脚手架创建项目
把脚手架一些自带的东西删除 , 记得调 代码规范
  1. 配置 Vue 路由
删除一些自带的路由设置
  1. 配置 Element-UI 组件库
npm install element-ui -s  安装

在main.js文件中 引入 element 组件  :
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
 
    Vue.use(ElementUI)
  1. 配置 axios 库 ⑥ 初始化 git 远程仓库
npm install axios
  1. 将本地项目托管到 Github 或 码云 中
7. 添加公钥
8. 
  1. 安装 less 和 less-loader
npm install less@3.9.0
npm install less-loader@4.1.0
安装好了可以直接使用

2.2 后台项目的环境安装配置

  1. 安装 MySQL 数据库(启动MySQL,导入数据库)
  2. 安装 Node.js 环境
  3. 配置项目相关信息
  4. 启动项目 (node app.js 启动那个文件)
  5. 使用 Postman 测试后台项目接口是否正常

------------------ 登录/退出功能 --------------------------

3.0 重置表单数据

element-ui 中 
Form Methods 区域 调用 resetFields 方法
设置一个表单的实例对象  ref="loginFormRef"
然后去函数中调用这个方法
       resetLoginForm(){
     
           this.$ref.loginFormRef.resetFields()
       }

3.1 登录概述

  1. 登录业务流程
    ① 在登录页面输入用户名和密码
    ② 调用后台接口进行验证
    ③ 通过验证之后,根据后台的响应状态跳转到项目主页
  2. 登录业务的相关技术点
    http 是无状态的
    通过 cookie 在客户端记录状态
    通过 session 在服务器端记录状态
    通过 token 方式维持状态

3.2 登录 — token 原理分析

 git checkout -b login  创建 login 分支
 在分支中写代码
 git add . 
 git commit -m “注意规范!!!!!”
 git pull origin master
 git push origin master

  1. 登录页面输入用户名和密码进行登录
  2. 服务器验证通过之后生成该用户的 token 并返回
  3. 客户端存储该 token
  4. 后续所有的请求都携带该 token 发送请求
  5. 服务器端验证 token 是否通过

3.3 登录功能实现

1. 登录页面的布局

  1. 通过 Element-UI 组件实现布局
    el-form
    el-form-item
    el-input
    el-button
    字体图标

2. 实现登录
① 通过 axios 调用登录验证接口
② 登录成功之后保持用户 token 信息
③ 跳转到项目主页

const {
     data: res } = await this.$http.post('login', this.loginForm)
if (res.meta.status !== 200)return this.$message.error('登录失败!')
// 提示登录成功
this.$message.success('登录成功!')
// 把登录成功的token保存到sessionStorage
window.sessionStorage.setItem('token', res.data.token)
// 使用编程式导航,跳转到后台主页
this.$router.push('/home')

3. 路由导航守卫控制访问权限
如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面。

// 为路由对象,添加 beforeEach 导航守卫
router.beforeEach((to, from, next) => {
     
 // 如果用户访问的登录页,直接放行
 if (to.path === '/login') return next()
 // 从 sessionStorage 中获取到 保存的 token 值
 const tokenStr = window.sessionStorage.getItem('token')
 // 没有token,强制跳转到登录页
 if (!tokenStr) return next('/login')
 next()
})

4. Vue 直接操作 DOM

1.通过 ref 标注 DOM 元素
// 在 DOM 元素上通过 ref 属性标注,属性名称自定义
<div ref="info">hello</div>
2. 通过 $refs 获取 DOM 元素
// 通过 Vue 实例的 $refs 获取标记 ref 属性的元素
let info = this.$refs.info.innerHTML
console.log(info) // hello

5. 基于 Element-UI 进行表单验证
Element-UI表单验证规则

loginFormRules: {
     
 // 登录名称的验证规则
 username: [{
      required: true, message: '请输入用户名称', trigger: 'blur' }],
 password: [{
      required: true, message: '请输入用户密码', trigger: 'blur' }]
}
// 进行表单验证
this.$refs.loginFormRef.validate(async valid => {
     
 // 如果验证失败,直接退出后续代码的执行
 if (!valid) return
 // 验证通过后这里完成登录成功后的相关操作(保存token、跳转到主页)
})

3.4 退出

退出功能实现原理
基于 token 的方式实现退出比较简单,只需要销毁本地的 token 即可。这样,后续的请求就不会携带token ,必须重新登录生成一个新的 token 之后才可以访问页面。

 // 清空token
 window.sessionStorage.clear()
 // 跳转到登录页
 this.$router.push('/login')

Vue 完整代码 — login的

<template>
  <div class="login_container">
    <div class="login_box">
      <!-- 头像区域 -->
      <div class="avatar_box">
        <img src="../assets/logo.png" alt="">
      </div>
      <!-- 登录表单区域 -->
      <el-form ref="loginFormRef" :model="loginForm" :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 v-model="loginForm.password" prefix-icon="iconfont icon-3702mima" type="password"></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() {
     
      // console.log(this);
      this.$refs.loginFormRef.resetFields()
    },
    login() {
     
      this.$refs.loginFormRef.validate(async valid => {
     
        if (!valid) return
        const {
      data: res } = await this.$http.post('login', this.loginForm)
        if (res.meta.status !== 200) return this.$message.error('登录失败!')
        this.$message.success('登录成功')
        // 1. 将登录成功之后的 token,保存到客户端的 sessionStorage 中
        //   1.1 项目中出了登录之外的其他API接口,必须在登录之后才能访问
        //   1.2 token 只应在当前网站打开期间生效,所以将 token 保存在 sessionStorage 中
        window.sessionStorage.setItem('token', res.data.token)
        // 2. 通过编程式导航跳转到后台主页,路由地址是 /home
        this.$router.push('/home')
      })
    }
  }
}
</script>

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

.login_box {
     
  width: 450px;
  height: 300px;
  background-color: #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>

main 的

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
// 导入字体图标
import './assets/fonts/iconfont.css'
// 导入全局样式表
import './assets/css/global.css'

import axios from 'axios'
// 配置请求的跟路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
Vue.prototype.$http = axios

Vue.config.productionTip = false

new Vue({
     
    router,
    render: h => h(App)
}).$mount('#app')

router 路由的

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

Vue.use(VueRouter)

const routes = [{
     
  path: '/',
  redirect: '/login'
}, {
     
  path: '/login',
  component: Login
},
{
     
  path: '/home',
  component: Home
}
]

const router = new VueRouter({
     
  routes
})
router.beforeEach((to, from, next) => {
     
  if (to.path == '/login') return next()
  const tokenStr = window.sessionStorage.getItem('token')
  if (!tokenStr) return next('/login')
  next()
})
export default router

你可能感兴趣的:(vue,项目实战篇,vue)