Express+vue 后台与登录实现

6 篇文章 0 订阅

在前面的基础上,我们首先实现后台管理的登录逻辑。我们使用的是Express+vue进行实现,后面的文章也一样。

创建名为manager的项目,用来实现后台管理。创建client项目,用来实现前端。整个工程的结构如下:
在这里插入图片描述

在这里我们使用Axios来实现后台数据请求,Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

安装使用:

yarn add axios

接下来我们就实现一个简单的后台登录页面,然后对axios进行简单的封装实现后台数据获取。

为了方便构建页面,这里我们使用 element-ui,当然了你也可以使用其他的ui框架,比如iview等等。

安装命令:

yarn add  element-ui

安装完成后,在main.js中完成element的导入:

// 引入element ui框架
import ElementUI from "element-ui";
// 引入element ui 样式文件
import "element-ui/lib/theme-chalk/index.css";

//全局使用插件
Vue.use(ElementUI);

由于element的icon库资源比较少,这里我们推荐使用阿里icon作为第三方的icon库,然后将其导入我们的工程中。

首先,我们需要一个阿里icon的账号,如果你没有,那么请注册一个然后登陆。

在这里插入图片描述

然后选择一个icon库,选择你想要的图标加入购物车,当然了,你也可以在控制台使用下面的命令将整个库的图标加入购物车:
在这里插入图片描述

var icons = document.querySelectorAll('.icon-gouwuche1');

var auto_click = function(i) {
    if (i < icons.length) {
        setTimeout(function() {
            icons.item(i).click();
            auto_click(i + 1);
        },
        600);
    }
};
auto_click(0);

操作完成后,打开购物车然后添加至项目,完成后是这个样子的:
在这里插入图片描述

将项目下载到本地解压,然后将我们需要的文件拷贝至项目中:
在这里插入图片描述
在iconfont.css中添加上图的代码:

[class^="ele-icon-third"],
[class*=" ele-icon-third"] {
    font-family: "iconfont" !important;
    font-size: 16px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

注意[class^="ele-icon-third"] 里面其实就是我们创建项目时的类名。

最后在main.js引入css文件:


// 引入阿里icon
import "./assets/icon/iconfont.css";

在阿里icon,项目中拷贝你需要的icon对应的代码即可:

<el-input
        :placeholder="$t('lang.username')"
        prefix-icon="ele-icon-third-user"
        v-model="input21"
      />

在这里插入图片描述

最终我们的登录页面是这个样子的,由于本人不太会css,所以比较丑陋大家见谅。

在这里插入图片描述

当然了,我们配置了国际化,所以引文版的界面是下面的样子:
在这里插入图片描述

国际化的实现依赖vue-i18n,大家可以使用yarn进行安装。
使用姿势:
在这里插入图片描述

// 引入国际化插件
import VueI18n from "vue-i18n";

//全局使用插件
Vue.use(VueI18n);

// 配置国际化选项
const i18n = new VueI18n({
  // locale: "zh-CN", // 语言标识, 通过切换locale的值来实现语言切换,this.$i18n.locale
  locale: "en-US", // 语言标识, 通过切换locale的值来实现语言切换,this.$i18n.locale
  messages: {
    "zh-CN": require("./common/lang/zh"), // 中文语言包
    "en-US": require("./common/lang/en") // 英文语言包
  }
});

new Vue({
  router,
  // 使用国际化语言选项
  i18n,
  store,
  render: h => h(App)
}).$mount("#app");

在这里插入图片描述

在我的目录结构中,我创建了commen目录,下面有子目录lang用来存放国际化语言配置文件。
比如en.js:

export const lang = {
  username: "username",
  usernameValidate: "username is required",
  password: "password",
  passwordValidate: "password is required,minimum six characters need ",
  rememberAccount: "Remember me",
  forgetPassword: "Forget Password?",
  signIn: "Sign In",
  signUp: "I'm a new here,Sign Up?"
};

在我们的代码中可能有两种使用方式:

1.在html代码中使用
{{ $t("lang.forgetPassword") }}
2.在js代码中使用
this.$t("lang.forgetPassword")

关于这个插件就简单介绍一下,知道上面的用法对我们来说就足够了,更多的大家用到的时候在查阅相关文档。

说了半天,我们终于要进入我们的逻辑实现环节了。

在界面ui方面,我们目前只需要关注下面两点优化即可:

1.用户名和密码非空验证
2.点击登录按钮,实现loading状态

对于数据的验证,我们可以使用表单来完成,我这里为了简单一点,就自己简单实现一下。

  <el-input
          prefix-icon="ele-icon-third-user"
          v-model="username"
          @blur="usernameInputBlur"
        >
          <template slot="prepend">
            {{ $t("lang.username") }}
          </template>
        </el-input>
        <div class="validate-style" v-if="usernameValidated">
          {{ $t("lang.usernameValidate") }}
        </div>
        <el-input
          prefix-icon="ele-icon-third-lock"
          v-model="password"
          style="margin-top:5px;"
          type="password"
          @blur="passwordInputBlur"
        >
          <template slot="prepend">
            {{ $t("lang.password") }}
          </template>
        </el-input>
        <div class="validate-style" v-if="passwordValidated">
          {{ $t("lang.passwordValidate") }}
        </div>
      </div>
      <div class="login-remember-forget">
        <el-checkbox v-model="rememberAccount">
          {{ $t("lang.rememberAccount") }}
        </el-checkbox>
        <a href="javascript:void(0)" @click="retrievePassword">
          {{ $t("lang.forgetPassword") }}
        </a>
      </div>
      <div class="login-submit">
        <el-button
          type="primary"
          size="medium"
          :loading="loginLoading"
          @click="handleLogin"
        >
          {{ $t("lang.signIn") }}
        </el-button>
      </div>

按钮的loading效果,我们可以使用element提供的loading props很方便就可实现。

对于用户名和密码的验证我们放在当输入框失去焦点的时候,所以这里监听了输入框的blur事件,事件代码:

usernameInputBlur() {
      if (!this.username) {
        this.usernameValidated = true;
      } else {
        this.usernameValidated = false;
      }
    },
    passwordInputBlur() {
      if (!this.password) {
        this.passwordValidated = true;
      } else {
        this.passwordValidated = false;
      }
    },

效果:
在这里插入图片描述

在这里插入图片描述

接下来我们就需要封装我们的axios了,首先我们在工程目录下创建一个http的目录用来存放axios相关文件。然后创建axios.js用来创建axios的实例。在http目录下床架api目录,存放具体的请求方法。

在这里插入图片描述

先来看看axios.js:

import axios from "axios";

const instance = axios.create({
  // 接口地址的base_url
  baseURL: "http://localhost:3000",
  // 请求超时时间
  timeout: 10000
});

// request拦截器
instance.interceptors.request.use(
  config => {
    // 发送请求之前可修改配置
    return config;
  },
  error => {
    // 处理错误
    return Promise.reject(error);
  }
);

// respone拦截器
instance.interceptors.response.use(
  response => {
    //修改返回数据
    return response;
  },
  error => {
    // 处理错误
    return Promise.reject(error);
  }
);
export default instance;

这个文件我们创建axios的实例,关于更多的配置信息大家可以查阅官方文档:https://github.com/axios/axios

接着我们创建一个admin.js文件,用来请求和后台管理员相关的内容。

import request from "../axios";

export function adminLogin(data) {
  return request({
    url: "/admin/login",
    method: "get",
    params: data
  });
}

到这里其实我们就可以通过import语句 导入admin.js来使用了。不过还有一个方法可以方便的使用,不用在文件中导入,那就是使用vue插件形式。

Vue.js 的插件应该有一个公开方法 install。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象,我们在api目录下创建index.js:

import * as admin from "./admin.js";

const apis = {
  admin
};

const install = function(Vue) {
  if (install.installed) return;
  install.installed = true;
  Object.defineProperties(Vue.prototype, {
    $axios: {
      get() {
        return apis;
      }
    }
  });
};
export default {
  install
};

最后在main.js全局注册即可:

import axios from "./http/api";
Vue.use(axios);

此时我们可以在文件内这样使用:

this.$axios.admin
        .adminLogin(bodys)
        .then(response => {
          console.log(response);
        })
        .catch(error => {
          console.log(error);
        });

那么此时我们点击登录的逻辑应该是这个样子的:

index.vue

handleLogin() {
      if (!this.username || !this.password) {
        this.usernameInputBlur();
        this.passwordInputBlur();
        return;
      }

      this.loginLoading = true;

      let bodys = { username: this.username, password: this.password };
      // 请求后台数据,验证用户名和密码,数据请求成功后,停用loading效果
  this.$axios.admin
        .adminLogin(bodys)
        .then(response => {
          this.loginLoading = false;
          console.log(response);
        })
        .catch(error => {
          console.log(error);
          this.loginLoading = false;
        });
    }

到了这里我们就该考虑去完善后台的处理。在后台项目中我们创建名为admin.js的路由中间件,然后在app.js中注册。

admin.js

var express = require('express');
var router = express.Router();

router.all('/login', function (req, res, next) {
    console.log(req)
    res.send("logins")
});

module.exports = router;

app.js

var adminRouter = require('./routes/admin');
app.use('/admin', adminRouter);

运行后台项目,然后测试admin/login接口:
在这里插入图片描述

说明我们的接口可以正常使用。其中的返回数据为测试数据,我们一步步完善。

此时,我们在登录页面点击登录按钮:
在这里插入图片描述

Access to XMLHttpRequest at 'http://localhost:3000/admin/login?username=55&password=55' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是最常见的跨域问题,我们可以在后台服务器开启允许跨域,在express中可以这样设置:

app.all('*', function (req, res, next) {
    res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
    res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization,\'Origin\',Accept,X-Requested-With');
    res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
    res.header('Access-Control-Allow-Credentials', true);
    next();

});

再次点击登录,问题解决。后台返回在这里插入图片描述

接下来我们继续完善后台代码,接收到前端请求后,我们需要查询数据库来判断用户名和密码是否正确等操作:
我们介绍过怎么使用mongodb,这里简单显示如何在项目中使用,创建model文件夹用来保存数据库模型文件,
创建模型:admins
在这里插入图片描述
路由admin.js的中间件:

var express = require('express');
var router = express.Router();
// 导入数据库model
var adminModal = require("../db/models/admin")

router.all('/login', function (req, res, next) {
// 获取参数
    var params = Object.keys(req.query).length ? req.query : req.body
// 查询数据库
    adminModal.findOne({ username: params.username }, (err, doc) => {
        if (!err) {
            let response = {}
            response.errorCode = doc ? (doc.password == params.password ? 0 : 1001) : 1000
            response.data = null
            res.jsonp(response)
        } else {

        }
    })

});

module.exports = router;

其中response就是我们自定义返回的数据内容,这里大家可以根据需要返回。

此时,在我们前端页面中,就可以通过返回的数据进行相应的处理:

index.vue

handleLogin(){
......
if (response.data.errorCode) {
            this.$message({
              type: "error",
              center: true,
              message: this.$t("lang." + response.data.errorCode)
            });
          }
          .....
   }

在这里插入图片描述
效果就是这个样子的,当然了这里只是用来学习交流的,做的不是很好看,但是主要的用到的东西就是这些。关于更多的权限控制等内容后续会有学习,希望对大家有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值