前端学习之vue+element-ui电商项目(一)登录界面+主页面

本文介绍了使用Vue和Element-UI构建电商项目的步骤,包括项目创建、配置ElementUI和axios、处理ESLint错误、设置后端接口、创建登录页面、实现表单验证和路由跳转,以及主页面布局、token验证和侧边栏菜单的渲染等。通过此教程,读者可以掌握基于Vue的前端开发实践。

1.创建项目

1.1使用图形化界面创建项目

vue ui

在这里插入图片描述

1.2创建项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.2.1选择手动创建项目

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1.3进入项目仪表盘

在这里插入图片描述

1.3.1配置ElementUI组件库

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.3.2安装axios依赖

在这里插入图片描述

1.3.3运行项目

在这里插入图片描述
在这里插入图片描述

1.4修改控制台报错

在这里插入图片描述

1.4.1修改ESLint发出的语法报错警告

1.项目根目录中创建文件.prettierrc

{
  "semi": false, // 格式化是结尾不加分号
  "singleQuote" : true // 单引号代替分号
}

2.修改ESLint语法规则.eslintrc.js

rules: {
  'space-before-function-paren': 0 // 禁用函数后面要加空格的格式要求
}

2. 配置后端接口

2.1安装 MySQL 数据库

1)关闭Apache

使用phpStudy软件:安装phpStudy后,点击【其他选项菜单】—>【服务器管理】—>【服务器管理】—>【Apache】—>【停止】

2)导入数据库文件(路径不能有中文)

使用phpStudy软件:【MySQL管理器】—>【MySQL导入导出】—>【MySQL密码(输入:root)】—>【选择要还原的文件:…\db\mydb.aql】、【还原到:mydb】—>【导入】

3)检查数据数据是否导入完成。

使用phpStudy软件:【其他选项菜】—>【MySQL工具】—>【打开数据库目录】 可以看到< mydb >< mysql >等文件说明导入成功

2.2安装node.js

进入项目文件夹输入:

cnpm install

2.3启动项目

node app.js

在这里插入图片描述

2.4测试后台项目接口

1)打开 Postman,打开API文档电商管理后台 API 接口文档.md。进入Postman测试。
在这里插入图片描述

打开phpstudy,开启MySQL,再次测试。

2 ) 注意:MySQL第一次打开要重新设置密码

3)postman测试成功
在这里插入图片描述

3.登录页面制作

3.1登录页面绘制

准备工作:
1 )清空Vue模板和路由 main.js App.vue ./components/HelloWorld.vue ./views

2 )创建组件 ./view/Login.vue
3 )编写Home.vue

3.1.1 按需引入element-ui组件

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

Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)

Vue.use(Button)

3.1.2 安装less less-loader

1)在命令行输入以下代码,或者在可视化工具中直接安装。

npm install less less-loader

安装过后重新编译。

2 )设置全局样式./assets/css/global.css,并导入到main.js中

/* 全局样式表 */
html,
body,
#app {
  height: 100%;
  margin: 0;
  padding: 0;
  min-width: 1366px;
}
// 导入全局样式表
import './assets/css/global.css'

3.1.3 绘制登录盒子(Login.Vue)

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

.login_container {
  background-color: #409eff;
  height: 100%;
}

.login_box {
  width: 450px;
  height: 300px;
  background-color: #fff;
  border-radius: 3px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

3.1.4 绘制登录头像(Login.Vue)

<!-- 头像区域 -->
<div class="avatar_box">
  <img src="../assets/logowl.png" alt="" />
</div>

.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;
}

3.1.5 绘制表单区(Login.Vue)

<!-- 登录表单区域 -->
<el-form label-width="0px" class="login_form">
  <!-- 用户名 -->
  <el-form-item>
    <el-input></el-input>
  </el-form-item>
  <!-- 密码 -->
  <el-form-item>
    <el-input></el-input>
  </el-form-item>
  <!-- 按钮 -->
  <el-form-item>
    <el-button type="primary" class="btns">登录</el-button>
    <el-button type="info">重置</el-button>
  </el-form-item>
</el-form>

.login_form {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px;
  box-sizing: border-box;
}
.btns {
  display: flex;
  justify-content: flex-end;
}

3.1.6 绘制带图标的输入框(Login.Vue)

官方图标库: https://element.eleme.cn/#/zh-CN/component/input

这里使用:

<el-input prefix-icon="el-icon-user"></el-input>

<el-input prefix-icon="el-icon-lock"></el-input>

带图标的输入框
阿里图标库:iconfont
使用方式:
1 )下载选好的阿里字体图标
2 )demo_fontclass.html查看图标名称
3 )在main.js引入iconfont.css样式表 import ‘./assets/fonts/iconfont.css’
4)标签添加相应的类名 class=“iconfont icon-xxx”

3.2 表单绑定事件

3.2.1 表单的数据绑定

<el-form :model="loginForm">
	<el-input v-model="loginForm.username"></el-input>
	<el-input v-model="loginForm.password" type="password"></el-input>
</el-form>

export default {
  data () {
    return {
      // 登录表单的数据绑定对象
      loginForm: {
        username: 'admin',
        password: '123456'
      }
    }
  }
}


3.2.2 表单的数据验证

<el-form :rules="loginFormRules">
	<el-form-item prop="username">
		<el-input v-model="loginForm.username"></el-input>
	</el-form-item>
	<el-form-item prop="password">
		<el-input v-model="loginForm.password" type="password"></el-input>
	</el-form-item>
</el-form>

export default {
  data () {
    return {
	  loginFormRules: {
	    // 验证用户名是否合法
	    username: [
	      { required: true, message: '请输入登录名称', trigger: 'blur' },
	      { min: 4, max: 6, message: '长度在 4 到 6 个字符', trigger: 'blur' }
	    ],
	    // 验证密码是否合法
	    password: [
	      { required: true, message: '请输入登录密码', trigger: 'blur' },
	      { min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
	    ]
	  }
	}
  }
}

3.2.3 表单的重置功能

1 )通过 ref 标注 DOM 元素

<el-form ref="loginFormRef"></el-form>

2 )为重置按钮绑定单击事件

<el-button type="info" @click="resetLoginForm">重置</el-button>

3 )定义重置方法(通过 $refs 获取 DOM 元素)

methods: {
  // 点击重置按钮,重置登录表单
  resetLoginForm () {
    // console.log(this) // VueComponent
    this.$refs.loginFormRef.resetFields()
  }
}

3.2.4 表单数据的预验证,配置axios发起登录请求

1 )添加点击事件

<el-button type="primary" @click="login">登录</el-button>

2 )导入axios包main.js,配置axios

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

3 )导入弹框提示组件element.js

import { Message } from 'element-ui'
Vue.prototype.$message = Message // 弹框提示组件挂在在Vue原型上

4 )编写login方法

methods: {
  login () {
    this.$refs.loginFormRef.validate(async (valid) => {
      // console.log(valid) // false/ture
      if (!valid) return
      const { data: result } = await this.$http.post('login', this.loginForm)
      // console.log(result) //Promise
      if (result.meta.status !== 200) return this.$message.error('登录失败')
      this.$message.success('登录成功')
      
      // 1. 将登录成功之后的 token 保存到客户端的 sessionStorage 中(会话期间的存储机制)(所以不放在loaclStorage中)
      window.sessionStorage.setItem('token', result.data.token)
      // 2. 通过编程式导航跳转到后台主页,路由地址是 /home
      this.$router.push('/home')
    })
  }
}

3.3路由设置

3.3.1 添加路由规则

1 )添加路由规则 ./router/index.js 设置默认页面重定向到login

import Login from '../components/Login.vue'
const routes = [
  { path: '/', redirect: '/login' },
  { path: '/login', component: Login }
]

2 )添加路由占位符 App.vue

 <div id="app">
    <!-- 路由占位符 -->
    <router-view></router-view>
  </div>

3.3.2 编写Home.vue并导入路由规则

import Home from '../components/Home.vue'
const routes = [  
  { path: '/home', component: Home, }

3.3.3 路由导航守卫控制页面访问权限

如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面router/index.js

// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
  // to 将要访问的路径
  // from 代表从哪个路径跳转而来
  // next 是一个函数, 表示放行   ①next()放行   ②next('/login')强制跳转
  if (to.path === '/login') return next() // 访问登录页,直接放行
  // 获取token
  const tokenStr = window.sessionStorage.getItem('token')
  if (!tokenStr) return next('/login') // 没有token 强制跳转
  next() // (有token)直接放行
})

3.4效果展示

在这里插入图片描述

4.1主页面设置

4.1主页面布局

1 )按需导入element-ui组件:
        Header,
        Container,
        Aside,
        Main,
        Menu,
        Submenu,
        MenuItem

4.1.1主页面粗布局

<template>
  <div>
      <el-container class="home_container">
            <!-- 头部区域 -->
            <el-header>Header</el-header>
            <!-- 主页面区域 -->
            <el-container>
            <!-- 左侧边栏 -->
            <el-aside width = "200px">Aside</el-aside>
            <!-- 右侧内容主体 -->
            <el-main>Main</el-main>
            </el-container>
      </el-container>
  </div>
</template>
<style>
.home_container {
    height: 100%;
}
.el-header {
    background-color: #373d41;
}
.el-aside {
    background-color: #333744;
}
.el-main {
    background-color: #eaedf1;
}
</style>

4.1.2主页面完善布局

<!-- 头部区域 -->
   <el-header>
       <div>
           <img src="../assets/logowl.png" alt="">
           <span>电商后台管理系统</span>
       </div>
       <el-button type="info" @click="logout">退出</el-button>
   </el-header>
.el-header {
  background-color: #373d41;
  display: flex;
  justify-content: space-between;
  padding-left: 0;
  align-items: center;
  color: #fff;
  font-size: 20px;
}
.el-header > div {
  display: flex;
  align-items: center;
}
.el-header > div > span {
  margin-left: 15px;
}

4.1.3 侧边栏菜单区域

<!-- 侧边栏菜单区域 -->
<el-menu>
  <el-submenu>
    <!-- 这个 template 是一级菜单的内容模板 -->
    <i class="el-icon-menu"></i>
    <span>一级菜单</span>
    <!-- 在一级菜单中,可以嵌套二级菜单 -->
    <el-menu-item>
  	  <i class="el-icon-menu"></i>
  	  <span slot="title">二级菜单</span>
  	</el-menu-item>
  </el-submenu>
</el-menu>

4.2添加token验证

需要授权的 API ,必须在请求头中使用 Authorization字段提供 token 令牌
后台除了登录接口之外,都需要token权限验证,我们可以通过添加axios请求拦截器来添加token,以保证拥有获取数据的权限。

将axios挂载到vue原型之前添加下面的代码(main.js)

// 通过axios请求拦截器添加token,保证拥有获取数据的权限
axios.interceptors.request.use(config => {
  // 为请求头对象,添加 Token 验证的 Authorization 字段
  config.headers.Authorization = window.sessionStorage.getItem('token')
  // 在最后必须 return config
  return config
})

// 保存链接的激活状态
    saveNavState (activePath) {
      window.sessionStorage.setItem('activePath', activePath)
      this.activePath = activePath
    }

4.3获取左菜单栏数据

data() {
  return {
    // 左侧菜单数据
    menulist: []
  }
},
// 在加载之前获取数据,要在生命周期函数里
created() {
  this.getMenuList()
  this.activePath = window.sessionStorage.getItem('activePath')
},
methods: {
  // 获取所有的菜单
  async getMenuList() {
    const { data: result } = await this.$http.get('menus')
    if (result.meta.status !== 200) return this.$message.error(result.meta.msg)
    this.menulist = result.data
    console.log(result)
  }
}

4.1.3渲染左侧菜单

<!-- 一级菜单 -->
  <el-submenu :index="item.id+''" v-for="item in menulist" :key="item.id">
    <!-- 一级菜单的模板区域 -->
    <template slot="title">
      <!-- 文本 -->
      <span>{{item.authName}}</span>
  </template>
  <!-- 二级菜单 -->
  <el-menu-item :index="subItem.id+''" v-for="subItem in item.children" :key="subItem.id">
    <!-- 图标 -->
    <i class="el-icon-menu"></i>
    <!-- 文本 -->
    <span>{{subItem.authName}}</span>
  </el-menu-item>
</el-submenu>

4.1.3渲染左侧菜单

在数据中添加一个iconsObj,菜单项模板(template)中的i标签的添加类名并进行数据绑定。

<!-- 图标 -->
<i :class="iconsObj[item.id]"></i>

在数据中添加一个iconsOb:

iconsObj: {
  125: 'el-icon-s-custom',
  103: 'el-icon-s-check',
  101: 'el-icon-s-goods',
  102: 'el-icon-s-order',
  145: 'el-icon-s-marketing'
}

4.1.3渲染左侧菜单

为了保持左侧菜单每次只能打开一个,显示其中的子菜单,我们可以在el-menu中添加一个属性unique-opened
或者也可以数据绑定进行设置(此时true认为是一个bool值,而不是字符串) :unique-opened=“true”

<el-menu unique-opened>

解决边框问题:

.el-menu {
  border-right: none;
}

4.4侧边栏的toggle效果

<!-- 左边侧边栏 -->
<el-aside :width="isCollapse ? '64px':'200px'">
  <div class="toggle-button" @click="toggleCollapse">|||</div>
  <!-- 侧边栏菜单区域 -->
  <el-menu :collapse="isCollapse" :collapse-transition="false">

.toggle-button {
  background-color: #4A5064;
  font-size: 10px;
  line-height: 24px;
  color: rgb(144,147,153);
  text-align: center;
  letter-spacing: 0.2em;
  cursor: pointer
}

// 点击按钮切换菜单折叠与展开
toggleCollapse() {
  this.isCollapse = !this.isCollapse
}

4.5首页路由的重定向效果

4.5.1新增子级路由组件

新增子级路由组件components/Welcome.vue
在router/index.js中导入子级路由组件,并设置路由规则以及子级路由的默认重定向

import Welcome from '../components/Welcome.vue'
const routes = [
  {
    path: '/home',
    component: Home,
    redirect: '/welcome',
    children: [{ path: '/welcome', component: Welcome }]
  }
]

4.5.2添加一个路由占位符

Home.vue

<!-- 右侧内容主体 -->
<el-main>
  <!-- 路由占位符 -->
  <router-view></router-view>
</el-main>

4.5.3侧边栏路由链接的改造

需要将所有的侧边栏二级菜单都改造成子级路由链接,我们只需要将el-menu的router属性设置为true就可以了,此时当我们点击二级菜单的时候,就会根据菜单的index属性进行路由跳转,如: /110,

使用index id来作为跳转的路径不合适,我们可以重新绑定index

<!-- 二级菜单 -->
<el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id">

5.效果展示

请添加图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值