zoukankan      html  css  js  c++  java
  • 第一篇、搭建前(vue)后(node)端环境,开发一个简单的登录功能

    一、环境准备

    • 操作系统:支持 macOS,Linux,Windows
    • 运行环境:建议选择 LTS 版本,最低要求 8.x。

    二、快速初始化服务端eggjs项目

    Egg.js 为企业级框架和应用而生,我们希望由 Egg.js 孕育出更多上层框架,帮助开发团队和开发人员降低开发和维护成本。

    注:Egg.js 缩写为 Egg

    设计原则

    我们深知企业级应用在追求规范和共建的同时,还需要考虑如何平衡不同团队之间的差异,求同存异。所以我们没有选择社区常见框架的大集市模式(集成如数据库、模板引擎、前端框架等功能),而是专注于提供 Web 开发的核心功能和一套灵活可扩展的插件机制。我们不会做出技术选型,因为固定的技术选型会使框架的扩展性变差,无法满足各种定制需求。通过 Egg,团队的架构师和技术负责人可以非常容易地基于自身的技术架构在 Egg 基础上扩展出适合自身业务场景的框架。

    Egg 的插件机制有很高的可扩展性,一个插件只做一件事(比如 Nunjucks 模板封装成了 egg-view-nunjucks、MySQL 数据库封装成了 egg-mysql)。Egg 通过框架聚合这些插件,并根据自己的业务场景定制配置,这样应用的开发成本就变得很低。

    Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。但约定不等于扩展性差,相反 Egg 有很高的扩展性,可以按照团队的约定定制框架。使用 Loader 可以让框架根据不同环境定义默认配置,还可以覆盖 Egg 的默认约定。

    与社区框架的差异

    Express 是 Node.js 社区广泛使用的框架,简单且扩展性强,非常适合做个人项目。但框架本身缺少约定,标准的 MVC 模型会有各种千奇百怪的写法。Egg 按照约定进行开发,奉行『约定优于配置』,团队协作成本低。

    Sails 是和 Egg 一样奉行『约定优于配置』的框架,扩展性也非常好。但是相比 Egg,Sails 支持 Blueprint REST API、WaterLine 这样可扩展的 ORM、前端集成、WebSocket 等,但这些功能都是由 Sails 提供的。而 Egg 不直接提供功能,只是集成各种功能插件,比如实现 egg-blueprint,egg-waterline 等这样的插件,再使用 sails-egg 框架整合这些插件就可以替代 Sails 了。

    特性

    安装

    推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0):

    $ mkdir egg-example && cd egg-example
    $ npm init egg --type=simple
    $ npm i
    

    得到目录结构如下:

    egg-project
    ├── package.json
    ├── app.js (可选)
    ├── agent.js (可选)
    ├── app
    |   ├── router.js
    │   ├── controller
    │   |   └── home.js
    │   ├── service (可选)
    │   |   └── user.js
    │   ├── middleware (可选)
    │   |   └── response_time.js
    │   ├── schedule (可选)
    │   |   └── my_task.js
    │   ├── public (可选)
    │   |   └── reset.css
    │   ├── view (可选)
    │   |   └── home.tpl
    │   └── extend (可选)
    │       ├── helper.js (可选)
    │       ├── request.js (可选)
    │       ├── response.js (可选)
    │       ├── context.js (可选)
    │       ├── application.js (可选)
    │       └── agent.js (可选)
    ├── config
    |   ├── plugin.js
    |   ├── config.default.js
    │   ├── config.prod.js
    |   ├── config.test.js (可选)
    |   ├── config.local.js (可选)
    |   └── config.unittest.js (可选)
    └── test
        ├── middleware
        |   └── response_time.test.js
        └── controller
            └── home.test.js
    

    启动项目:

    $ npm run dev
    $ open http://localhost:7001
    

    三、建立一个会员信息表,mysql>=5.7

    建立一个会员信息表,有用户名密码等信息

    四、使用egg-mysql插件访问数据库

    egg框架提供了 egg-mysql 插件来访问 MySQL 数据库。这个插件既可以访问普通的 MySQL 数据库,也可以访问基于 MySQL 协议的在线数据库服务。

    安装与配置

    安装对应的插件 egg-mysql

    $ npm i --save egg-mysql
    

    开启插件:

    // config/plugin.js
    exports.mysql = {
      enable: true,
      package: 'egg-mysql',
    };
    

    config/config.${env}.js 配置各个环境的数据库连接信息。

    单数据源

    如果我们的应用只需要访问一个 MySQL 数据库实例,可以如下配置:

    // config/config.${env}.js
    exports.mysql = {
      // 单数据库信息配置
      client: {
        // host
        host: 'mysql.com',//本机127.0.0.1
        // 端口号
        port: '3306',
        // 用户名
        user: 'test_user',
        // 密码
        password: 'test_password',
        // 数据库名
        database: 'users',//users
      },
      // 是否加载到 app 上,默认开启
      app: true,
      // 是否加载到 agent 上,默认关闭
      agent: false,
    };
    

    使用方式:

    await app.mysql.query(sql, values); // 单实例可以直接通过 app.mysql 访问
    

    多数据源

    如果我们的应用需要访问多个 MySQL 数据源,可以按照如下配置:

    exports.mysql = {
      clients: {
        // clientId, 获取client实例,需要通过 app.mysql.get('clientId') 获取
        db1: {
          // host
          host: 'mysql.com',
          // 端口号
          port: '3306',
          // 用户名
          user: 'test_user',
          // 密码
          password: 'test_password',
          // 数据库名
          database: 'test',
        },
        db2: {
          // host
          host: 'mysql2.com',
          // 端口号
          port: '3307',
          // 用户名
          user: 'test_user',
          // 密码
          password: 'test_password',
          // 数据库名
          database: 'test',
        },
        // ...
      },
      // 所有数据库配置的默认值
      default: {
    
      },
    
      // 是否加载到 app 上,默认开启
      app: true,
      // 是否加载到 agent 上,默认关闭
      agent: false,
    };
    

    使用方式:

    const client1 = app.mysql.get('db1');
    await client1.query(sql, values);
    
    const client2 = app.mysql.get('db2');
    await client2.query(sql, values);
    

    在数据库里建一个users表

    service层

    • 在app目录下新建service目录,用来放置service层的代码

    • 新建一个users.js文件

      'use strict';
      
      const Service = require('egg').Service;
      
      class UsersService extends Service {
      
          async account(name, pwd) {
              const result = await this.app.mysql.select('users', { // 搜索 users 表
                  where: { name: name, password: pwd }, // WHERE 条件
              });
              return result;
          }
      }
      
      module.exports = UsersService;
    

    controller层

    • 在controller目录下新建account.js
    'use strict';
    
    const Controller = require('../core/base_controller');
    
    class AccontController extends Controller {
      async account() {
        const { ctx } = this;
        //解析post请求的参数
        const name = ctx.request.body.loginname;
        const pwd = ctx.request.body.password;
        let res = await ctx.service.users.account(name,pwd);//调用service层的方法
        this.success(res);
        
      }
    }
    
    module.exports = AccontController;
    
    • 这里base_controller是自己创建的一个基类controller,在app目录下新建“/core/base_controller.js”。
    const { Controller } = require('egg');
    class BaseController extends Controller {
      success(data) {
        this.ctx.body = {
          success: true,
          data,
        };
      }
    
      notFound(msg) {
        msg = msg || 'not found';
        this.ctx.throw(404, msg);
      }
    }
    module.exports = BaseController;
    
    • 配置服务端路由
    'use strict';
    
    /**
     * @param {Egg.Application} app - egg application
     */
    module.exports = app => {
      const { router, controller } = app;
      router.get('/', controller.home.index);
      router.post('/account', controller.accont.account);//我们的简单登录验证接受post请求
        // controller.accont.account 是accountController里的account方法,,,accont拼写错了
    };
    
    

    这样我们简单的一个服务端就写好了。

    五、初始化一个前端vue项目

    • 安装一下vue的clivue-cli,初始化一个vue工程
    npm install -g @vue/cli-service-global
    
    vue ui //用图形化界面创建vue工程
    

    六、引用element-ui 插件

    自己配一个喜欢的主题色,我自己瞎配了个绿色。

    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './store'
    import './plugins/element.js'
    
    Vue.config.productionTip = false
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    

    七、封装请求模块

    安装axios

    在src目录下新建“http/http.js”,在这里我们先初步简单封装一下我们前端的请求模块:

    import axios from "axios";
    
    axios.defaults.timeout = 5000;
    axios.defaults.baseURL = 'http://127.0.0.1:7001';
    // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    axios.defaults.headers.post['Content-Type'] = 'application/json';
    
    
    
    function get(url, data = {}) {
        return new Promise((resolve, reject) => {
            axios.get(url, {
                params: data
            }).then(response => {
                resolve(response.data);
            }).catch(err => {
                reject(err)
            })
        })
    }
    
    function post(url, data = {}) {
        return new Promise((resolve, reject) => {
            axios.post(url, data).then(response => {
                resolve(response.data);
            }).catch(err => {
                reject(err)
            });
        })
    }
    
    function patch(url, data = {}) {
        return new Promise((resolve, reject) => {
            axios.patch(url, data)
                .then(response => {
                    resolve(response.data);
                }, err => {
                    reject(err)
                })
        })
    }
    
    function put(url, data = {}) {
        return new Promise((resolve, reject) => {
            axios.put(url, data)
                .then(response => {
                    resolve(response.data);
                }, err => {
                    reject(err)
                })
        })
    }
    
    export default { get,post,patch,put }
    

    在新建一个api.js文件用来管理一下我们前端的请求接口:

    import http from "./http";
    
    /**
     * login 页面
     */
    export const login = (data) => http.post("/account",data);//用户登录
    

    八、创建登录页面,实现简单登录

    在views里新建“login/login.vue”

    <template>
        <div>
            <div style="height: 300px;margin-top: 100px">
                <p style="text-align: center;"><img src="../../assets/logo.png"></p>
            </div>
            <div style=" 350px;margin: 0 auto">
    
                <el-form ref="form" :model="form">
                    <el-form-item label="">
                        <el-input v-model.trim="form.loginname" placeholder="用户名"></el-input>
                    </el-form-item>
                    <el-form-item label="">
                        <el-input v-model.trim="form.password" placeholder="密码"></el-input>
                    </el-form-item>
                    <el-form-item label="">
                        <el-button type="primary" style=" 100%" @click="login">登录</el-button>
                    </el-form-item>
                </el-form>
            </div>
        </div>
    </template>
    
    <script>
        import {login} from "../../http/api";
    
        export default {
            name: "loign",
            data() {
                return {
                    form: {
                        loginname: "",
                        password: ""
                    }
                }
            },
            methods: {
                login() {
                    login(this.form).then(res => {
                        if (res.success) {
                            if(res.data.length > 0){
                                this.$message.success("成功!页面跳转中");
                                this.$router.push("/conent");
                            }else {
                                this.$message.error("失败");
                            }
    
                        }else {
                            this.$message.error("失败")
                        }
                    }).catch(e => {
                        console.log(e)
                    })
                }
            }
        }
    </script>
    
    <style scoped>
    
    </style>
    

    配置一下前端路由

        {
            path: '/',
            name: 'Login',
            component: Login
        },
    
          npm run serve
    

    好啦,一个简单的登录完成了!
    快来打赏我吧!

  • 相关阅读:
    配置apache的文件访问路径
    php 常量const
    php接口interface的使用
    php 抽象类abstract
    php 面向对象三大特点:封装、继承、多态
    程序员的情怀《从前慢》木心
    php static静态属性和静态方法
    php面向对象的构造方法与析构方法
    关于php变量的赋值和引用的区别
    angular4.0微信oAuth第三方认证的正确方式
  • 原文地址:https://www.cnblogs.com/chopin-1990/p/13179066.html
Copyright © 2011-2022 走看看