Vue——Mall项目初始化及登录模块(九)

一、Mall项目简介

客户使用的业务服务:PC端前台采用传统html开发,(小程序,移动web,移动app)采用uniapp开发
管理员使用的业务服务:PC端后台管理端采用vue脚手架开发

Mall后台管理系统采用前后端分离的开发模式
前端项目是基于Vue的SPA(单页应用程序)项目

后台功能图
Vue——Mall项目初始化及登录模块(九)
前端技术栈:Vue,Vue-Router,Element-UI,Axios,Echarts
后端技术栈:SSM,Mysql

二、项目初始化

A.安装Vue脚手架
B.通过脚手架创建项目
C.配置路由
D.配置Element-UI:在插件中安装,搜索vue-cli-plugin-element
E.配置Axios:在依赖中安装,搜索axios(运行依赖)
F.初始化git仓库
G.将本地项目托管到github或者码云中

三、代码

登录模块项目结构图
Vue——Mall项目初始化及登录模块(九)
App.vue

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

<script>
  export default {
    name: 'app'

  }
</script>

<style>

</style>

Login.vue

<template>
  <div class="login_container">
    <div class="login_box">
      <!-- 登录表单区域 -->
      <el-form ref="loginFormRef" :model="loginForm" :rules="loginFormRules" label-width="0px" class="login_form">
        <h1>Mall后台管理</h1>
        <!-- 用户名 -->
        <el-form-item prop="username">
          <el-input v-model="loginForm.username" prefix-icon="iconfont icon-yonghu"></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item prop="password">
          <el-input v-model="loginForm.password" prefix-icon="iconfont icon-yanjing_bi" type="password"></el-input>
        </el-form-item>
        <!-- 按钮区域 -->
        <el-form-item class="login_btn">
          <el-button type="primary" @click="login">登录</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        // 登录表单的数据绑定对象
        loginForm: {
          username: 'beizhen',
          password: '123456'
        },
        // 登录表单的验证规则
        loginFormRules: {
          // 验证用户名是否合法
          username: [{
              required: true,
              message: '请输入用户名',
              trigger: 'blur'
            },
            {
              min: 2,
              max: 16,
              message: '长度在 2 到 16 个字符',
              trigger: 'blur'
            }
          ],
          // 验证密码是否合法
          password: [{
              required: true,
              message: '请输入密码',
              trigger: 'blur'
            },
            {
              min: 6,
              max: 18,
              message: '长度在 6 到 18 个字符',
              trigger: 'blur'
            }
          ]
        }
      }
    },
    methods: {
      // 登录前先验证表单输入框的值是否合法
      login() {

        this.$refs.loginFormRef.validate(async valid =>{
          if(!valid) return;
          const {data : res} = await this.$http.post("mall/user/login",this.loginForm);
          if(res.meta.status !== 200) return this.$message.error(res.meta.msg);
          this.$message.success(res.meta.msg);
          //将登陆成功之后的token保存到客户端的sessionStorage
          window.sessionStorage.setItem("token",res.data.token);
          //通过编程式导航跳转到后台主页
          this.$router.push("/home");
        })
      }
    }
  }
</script>

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

  .login_form {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

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

  .login_btn {
    position: absolute;
    left: 50%;
    transform: translate(-50%);
  }
</style>

Home.vue

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

<script>
  export default {
    methods:{
      logout(){
        //清空token
        window.sessionStorage.clear();
        //跳转登陆页
        this.$router.push("/login");
      }
    }
  };
</script>

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

全局样式global.css

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

阿里巴巴图标样式iconfont.css

@font-face {font-family: "iconfont";
  src: url('//at.alicdn.com/t/font_2282747_nnb35kjm1ii.eot?t=1608803274048'); /* IE9 */
  src: url('//at.alicdn.com/t/font_2282747_nnb35kjm1ii.eot?t=1608803274048#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAXMAAsAAAAACygAAAV/AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDdAqITIcSATYCJAMgCxIABCAFhG0HbxuTCSMRtntw0pL95QFP5t6oDESNahCCMrK4GaXNiAB3VXXJ0zVpFMMCcTS1/NZUuM95Hzz1a+Xr3zO7f/HmgEEFAFCxIpJRqTgglzoVYBjKQ4OK/Am/OqiYFGTSORjAH6TLTU4HIAB4+Ha+q39ZF1pJht2Ih7JbQAMdDHe1tvaY7d4hGjIlUhLzmSFSTxqfRaRD7XTmt+bqnkj4qHdHaJ882mIWKJ00e8RgDCZu/fz9Xv1J1Zjnt32XyPvuj45FUwWNRwk0oKi0kW2AE8StY+MYlcxh19MQEJRFBTJTuvXDcpgnCZBVPXE0NhPmVPCE9fkIVwZyosmmzeYisDP4ffmpEwuGmzGf1YtpP45WKjo7S4f+ryrAhxjqLgnwB4KCCsDRvZ2Y3gIetStQQXWwhhEIeNZfVDxDVVVjVapeVPV50/+uMBOwNJoGbVDO0v7hGX4upGDiMNDHdfx4hjqA4pkRDp6ZGiF4Zm2ED89cjTB4Vm6EH8+bwrhAtcd7QCLIAHkQvVlTOVxAxtpfarwkJhuE42PCMZ7/9vi4kRdlB1MBIBSFvHmThpDKJSwEjlASNzUkabepM0CJtJfkljkqCn+TlsPzbQCA5bYQcoAQssKhzSyNA6IFqESzZ84FIO8kcImV5DM33RPIcsB12nLQHFrOa4sfUSIQaSvtqkQIldrnYeEXSZFVc24rJyZ12xJ4d64gXCoCB8C1bXuIfqZPnOjqbL/dzaf6/BZWAQQd3mvBbSUQElLD2xH/mFxSgVA8r2SlyOZIYh71lN5QITBdo6zMX/AZqcyWkAMU4SJjBNZFOzdhINErfaAijwlWXuMzUNxEW+WwM8PvpfjlWzi4l3FoKSe9dAtfhm4ld9njf/LEjYljZs8aEHdpxYwc2QiFu95fMmD6RtSxpPnLlhwu+ppUXG55ZZuZOyw7FvRMaz//6ZhBrsXqJuMvN78CM+y99HjQs7zdvGdjk+iUkM9Injd9yQW5UsmQ2hrJsIK1U103ytmSPaf0anBNbKNY28QcFweZ4K78TyMfU4f1OLkrPFbt4F9v5zcf87TfkjOXnCFLcnIe94OSpqpm3v7m5O+ZkfM3OWbJnLnv5OmH7IT9+7ZFhvUZS6OBg4qT3ka2rGfP2vdPjgRnWE2V1r29eu0OoLMzv1/nz6d809MtBWh+z5KhrhtlzjD5WEHP4qE9l+mGo1ifVdyQ9WlCPfLW3FWXuoR80jHJX6/bd5v0zyU+lIu6MleobJVl1CowMMM7x8qHfrmkt0C35x/x7KeaX9Md8R0vXrLxD4B56YfNtLPCzvh3U5F7Rb8ODQ0d+uVNcmnCJvyHjgEmWhBS2I2nHo1bc1+kqTl40+Tu7/EHnUM5x+Muhn3ywvY+2G/2755BViL4UD2wv4De5oKs/cpD+L8ZGsdrZrfy0xXqmL3Mtg//KI4N23sbGRP1VUf/Z9hwR2/sWlD+vx2keccyoLZ/5nbKZY7mNCM2lPk5Nuqs1f1DaBoQtNbAx52P416X3kTq0SCsxAQMv0xQVgHZoVeAK6QBfKyWEFROx+tD4pmDKIkAUMZ6BMLjPBhRl0B53CI79LvgSuIt+HiiEDQANb9jyG2vUv34xlgJtlCfwDaUlB2Tx3DsN+ocKk47A9k/cm9rMB1N8r0vTMhdnNPv9UxEgWKK8ImehyEQdEwOGxkZkW43HivSN40aioNH3hgrwRaoT4BtKClvfXks/Pw36hwqrphVNf1H7u3ugSkjJhTkL5yoZp3K5H6vZwhuKkDxoykCnziJwWoT0JEPc9jICNOg2e0Y49UULR4N741negcQxHy7lVTaWOf5cTnTv5yq5GzSw7NBz/uYeU9R29sTJW3yTZPpkO/P9pSrtF7edfmtMw4HAwA=') format('woff2'),
  url('//at.alicdn.com/t/font_2282747_nnb35kjm1ii.woff?t=1608803274048') format('woff'),
  url('//at.alicdn.com/t/font_2282747_nnb35kjm1ii.ttf?t=1608803274048') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
  url('//at.alicdn.com/t/font_2282747_nnb35kjm1ii.svg?t=1608803274048#iconfont') format('svg'); /* iOS 4.1- */
}

.iconfont {
  font-family: "iconfont" !important;
  font-size: 16px;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.icon-ok:before {
  content: "\e611";
}

.icon-yanjing-zheng:before {
  content: "\e621";
}

.icon-yanjing_bi:before {
  content: "\e601";
}

.icon-yonghu:before {
  content: "\e603";
}

.icon-cuowu:before {
  content: "\e770";
}

.icon-ziyuan75:before {
  content: "\e617";
}

.icon-xuanze-:before {
  content: "\e663";
}

element.js

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


Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
//全局挂载
Vue.prototype.$message = Message

index.js

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()
  //获取token
  const tokenStr = window.sessionStorage.getItem('token');
  if(!tokenStr) return next('/login');
  next();
})

export default router

main.js

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://localhost:8080/"
Vue.prototype.$http = axios


Vue.config.productionTip = false

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

vue.config.js

module.exports = {
  devServer: {
    port: 8081,
    open: true
  }
}

上一篇:Dubbo-03 20190316


下一篇:mall架构及功能概览