Node.js
对前端来讲无疑具备里程碑意义,与其愈来愈流行的今天,掌握Node.js技术已经不只仅是加分项,而是前端攻城师们必需要掌握的一项技能。而Express基于Node.js平台,快速、开放、极简的Web开发框架,成为Node.js最流行的框架,因此使用Express进行web服务端的开发是个不错且可信赖的选择。可是Express初始化后,并不立刻就是一个开箱即用,各类功能完善的web服务端项目,例如:MySQL链接、jwt-token认证、md5加密、中间件路由模块、异常错误处理、跨域配置、自动重启等一系列常见的功能,须要开发者本身手动配置安装插件和工具来完善功能,若是你对web服务端开发或者Express框架不熟悉,那将是一项耗费巨大资源的工做。javascript
本文做者根据项目实战经验已将底层服务架构搭建完成,而且本项目已在github开源,供你们学习参考使用(若有不足,还请批评指正),但愿能减轻你们的工做量,更高效的完成工做,有更多时间提高本身的能力。🤭css
后端API接口源码地址👉:github.com/jackchen012…html
前端界面源码地址👉:github.com/jackchen012…前端
若是以为本文还不错,记得点个👍赞或者给个❤️star,大家的赞和star是做者编写更多更精彩文章的动力!vue
分享以前咱们先来认识一下Node.js、Express
都是什么东东。java
简单的说Node.js就是运行在服务端的 JavaScript。node
Node.js是一个基于Chrome JavaScript运行时创建的一个平台。mysql
Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度很是快,性能很是好。linux
Express 是一个简洁而灵活的Node.js Web应用框架,提供了一系列强大特性帮助你建立各类Web应用,和丰富的HTTP工具。使用Express能够快速地搭建一个完整功能的网站。webpack
Express框架核心特性:
前端项目采用的技术栈是基于Vue + iView
,用vue-cli构建前端界面,后端项目采用的技术栈是基于Node.js + Express + MySQL
,用Express搭建的后端服务器。
在线演示DEMO地址👉:http://106.55.168.13:8082/
开发前准备工做,相关运行环境配置以下:
工具名称 | 版本号 |
---|---|
node.js | 10.16.2 |
npm | 6.9.0 |
运行项目
1> 下载安装依赖
git clone https://github.com/jackchen0120/todo-vue-admin.git
cd todo-vue-admin
npm install 或 yarn
2> 开发模式
npm run serve
运行以后,访问地址:http://localhost:8082
3> 生产环境打包
npm run build
│ package.json // npm包管理所需模块及配置信息 │ vue.config.js // webpack配置 ├─public │ favicon.ico // 图标 │ index.html // 入口html文件 └─src │ App.vue // 根组件 │ main.js // 程序入口文件 ├─assets // 存放公共图片文件夹 ├─components │ Footer.vue // 页面底部公用组件 │ Header.vue // 页面头部公用组件 ├─router │ index.js // 单页面路由注册组件 ├─store │ │ index.js // 状态管理仓库入口文件 │ └─modules │ userInfo.js // 用户模块状态管理文件 ├─styles │ base.scss // 基础样式文件 ├─utils │ api.js // 统一封装API接口调用方法 │ network.js // axios封装与拦截器配置 │ url.js // 自动部署服务器环境 │ valid.js // 统一封装公用模块方法 └─views Home.vue // 首页界面 Login.vue // 登陆界面 复制代码
npm install -g @vue/cli
#安装指定版本
npm install -g @vue/cli@4.4.0
#OR
yarn global add @vue/cli
vue create todo-vue-admin
cd todo-vue-admin
npm run serve
在项目根目录新增vue.config.js
文件,配置信息如图所示:
按照上面的步骤完成脚手架搭建后,把须要的axios、vue-router、view-design、sass-loader、node-sass等依赖库安装配置好,准备开始上膛。
首先在views文件夹下面新建login.vue
组件,编写一个静态的登陆注册页面。登陆成功后将登陆返回的token保存到浏览器端并跳转到主页。views文件夹下面新建home.vue
组件,显示登陆成功后的页面,并获取用户基本信息,主页右上角显示用户头像、修改密码、退出登陆等功能。代码以下:
<template>
<div class="login-container"> <div class="pageHeader"> <img src="../assets/logo.png" alt="logo"> <span>TODOList区块链管理平台</span> </div> <div class="login-box"> <div class="login-text" v-if="typeView != 2"> <a href="javascript:;" :class="typeView == 0 ? 'active' : ''" @click="handleTab(0)">登陆</a> <b>·</b> <a href="javascript:;" :class="typeView == 1 ? 'active' : ''" @click="handleTab(1)">注册</a> </div> <!-- 登陆模块 --> <div class="right-content" v-show="typeView == 0"> <div class="input-box"> <input autocomplete="off" type="text" class="input" v-model="formLogin.userName" placeholder="请输入登陆邮箱/手机号" /> <input autocomplete="off" type="password" class="input" v-model="formLogin.userPwd" maxlength="20" @keyup.enter="login" placeholder="请输入登陆密码" /> </div> <Button class="loginBtn" type="primary" :disabled="isDisabled" :loading="isLoading" @click.stop="login"> 当即登陆 </Button> <div class="option"> <Checkbox class="remember" v-model="checked" @on-change="checkChange"> <span class="checked">记住我</span> </Checkbox> <span class="forget-pwd" @click.stop="forgetPwd">忘记密码?</span> </div> </div> <!-- 注册模块 --> <div class="right_content" v-show="typeView == 1"> <div class="input-box"> <input autocomplete="off" type="text" class="input" v-model="formRegister.userName" placeholder="请输入注册邮箱/手机号" /> <input autocomplete="off" type="password" class="input" v-model="formRegister.userPwd" maxlength="20" @keyup.enter="register" placeholder="请输入密码" /> <input autocomplete="off" type="password" class="input" v-model="formRegister.userPwd2" maxlength="20" @keyup.enter="register" placeholder="请再次确认密码" /> </div> <Button class="loginBtn" type="primary" :disabled="isRegAble" :loading="isLoading" @click.stop="register"> 当即注册 </Button> </div> </div> </div> </template> <style lang="scss" scoped> .login-container { background-image: url('../assets/bg.png'); background-position: center; background-size: cover; position: relative; width: 100%; height: 100%; .pageHeader { padding-top: 30px; padding-left: 40px; img { vertical-align: middle; display: inline-block; margin-right: 15px; } span { font-size: 18px; display: inline-block; vertical-align: -4px; color: rgba(255, 255, 255, 1); } } .login-box { position: absolute; left: 64vw; top: 50%; -webkit-transform: translateY(-50%); transform: translateY(-50%); box-sizing: border-box; text-align: center; box-shadow: 0 1px 11px rgba(0, 0, 0, 0.3); border-radius: 2px; width: 420px; background: #fff; padding: 45px 35px; .option { text-align: left; margin-top: 18px; .checked { padding-left: 5px; } .forget-pwd, .goback { float: right; font-size: 14px; font-weight: 400; color: #4981f2; line-height: 20px; cursor: pointer; } .protocol { color: #4981f2; cursor: pointer; } } .login-text { width: 100%; text-align: center; padding: 0 0 30px; font-size: 24px; letter-spacing: 1px; a { padding: 10px; color: #969696; &.active { font-weight: 600; color: rgba(73, 129, 242, 1); border-bottom: 2px solid rgba(73, 129, 242, 1); } &:hover { border-bottom: 2px solid rgba(73, 129, 242, 1); } } b { padding: 10px; } } .title { font-weight: 600; padding: 0 0 30px; font-size: 24px; letter-spacing: 1px; color: rgba(73, 129, 242, 1); } .input-box { .input { &:nth-child(1) { /*margin-top: 10px;*/ } &:nth-child(2), &:nth-child(3) { margin-top: 20px; } } } .loginBtn { width: 100%; height: 45px; margin-top: 40px; font-size: 15px; } .input { padding: 10px 0px; font-size: 15px; width: 350px; color: #2c2e33; outline: none; // 去除选中状态边框 border: 1px solid #fff; border-bottom-color: #e7e7e7; background-color: rgba(0, 0, 0, 0); // 透明背景 } input:focus { border-bottom-color: #0f52e0; outline: none; } .button { line-height: 45px; cursor: pointer; margin-top: 50px; border: none; outline: none; height: 45px; width: 350px; background: rgba(216, 216, 216, 1); border-radius: 2px; color: white; font-size: 15px; } } // 滚动条样式 ::-webkit-scrollbar { width: 10px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.3); border-radius: 8px; } ::-webkit-scrollbar-thumb { border-radius: 10px; background: rgba(0, 0, 0, 0.2); -webkit-box-shadow: inset006pxrgba(0, 0, 0, 0.5); } ::-webkit-scrollbar-thumb:window-inactive { background: rgba(0, 0, 0, 0.4); } //设置更改input 默认颜色 ::-webkit-input-placeholder { /* WebKit browsers */