Eggjs配合Nextjs使用

[TOC]

Eggjs-Nextjs

先使用Nextjs的脚手架搭建整体架构

  • 这里使用

    npx create-next-app my-next-app
    

安装egg.js

  • 我们先进入到项目的根文件夹中(与创建的package.json同级),然后在根文件夹下,建立一个service的文件夹,这就是中台的文件夹了。

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

  • cd到根目录下的service目录,在下面输入命令

    npm init egg --type=simple
    
  • 初始化后需要安装包

    npm install
    
  • 安装后即可启动服务,注意是在service目录下

    npm run dev
    

路由配置

与koa的路由配置基本相同

  • 让egg为前端提供Api接口,实现中台主要的功能 ;这里使用restful-api接口设计

  • 在controller控制器中,eggjs默认给我们一个示例home.js

    • 创建eggjs的项目之后都会有home.js
    • 在controller中写我们逻辑代码可以写service
    'use strict';
    
    const Controller = require('egg').Controller;
    
    class HomeController extends Controller {
      async index() {
        const { ctx } = this;
        ctx.body = 'hi, egg';
      }
    }
    module.exports = HomeController;
    
    
  • 在router.js中配置路由

    • 也是框架提供给我们的
    'use strict';
    
    /**
     * @param {Egg.Application} app - egg application
     */
    module.exports = app => {
      const { router, controller } = app;
      router.get('/', controller.home.index);
    };
    
    
  • 可以看出:框架在加载router.js中路由,会去找controller下对应的找对应的文件夹/文件,找问价中对应的方法;当然配置路由时需要指定每个路由对应的方法

  • 可以启动egg服务后通过修改ctx.body的值可以看到不同的返回值,那个即是我们在访问接口的时候的返回值

  • 为了让router.js只是为了暴露配置,在app文件夹下面创建router文件夹

    ├─controller
    │  ├─client
    │  └─server
    ├─public
    └─router
    │  ├─client.js
    │  └─server.js
     ─router.js
    
    • 可在router/client.js中配置访问的路由

      'use strict';
      /**
       * @param {Egg.Application} app - egg application
       */
      module.exports = app => {
        const { router, controller } = app;
        router.get('/client/getList', controller.client.home.getArticleList);
      }
      
      //这里请求方式和我们正常的请求一样,像get/put/post/delete
      
    • 在router.js中引入

      'use strict';
      
      const client = require('./router/client');
      /**
       * @param {Egg.Application} app - egg application
       */
      module.exports = app => {
        const { router, controller } = app;
        client(app);
      };
      
    • 在controller也是一样创建client/home.js;只需在其写方法即可;

连接数据库

这里是使用mysql数据库

使用egg-mysql插件

  • 如果eggjs是npm/i创建的那么最好使用npm安装插件,使用yarn可能会导致安装失败以及其他原因,这里使用npm进行安装

    npm i egg-mysql --save
    
  • 和我们之前不一样的是,安装后不能直接使用,需要配置插件

    • 插件配置config下面的plugin.js以及config.default.js两者都需要配置
    • config/plugin.js
      • 如果有要安装其他的egg-plugin插件都要在这里进行配置
    'use strict';
    
    //这里是框架提供的,可以直接注释掉
    /** @type Egg.EggPlugin */
    // module.exports = {
    //   // had enabled by egg
    //   // static: {
    //   //   enable: true,
    //   // }
    // };
    
    // 配置插件
    exports.mysql = {
      enable: true,
      package: 'egg-mysql',
    };
    
    • config/config.default.js

      • 在其本身基础上增加对象config的属性即可
      • 里面的keys最好先不要动,不然会引起报错
      /* eslint valid-jsdoc: "off" */
      'use strict';
      /**
       * @param {Egg.EggAppInfo} appInfo app info
       */
      module.exports = appInfo => {
        /**
         * built-in config
         * @type {Egg.EggAppConfig}
         **/
        const config = exports = {};
        // use for cookie sign key, should change to your own and keep security
        config.keys = appInfo.name + '_1572838718244_4569';
        // add your middleware config here
        config.middleware = [];
        // add your user config here
        const userConfig = {
          // myAppName: 'egg',
        };
        config.mysql = {
          // database configuration
          client: {
            // host
            host: 'localhost',
            // port
            port: '3306',
            // username
            user: 'root',
            // password
            password: 'qd1224',
            // database
            database: 'blog_demo',
          },
          // load into app, default is open
          app: true,
          // load into agent, default is close
          agent: false,
        };
        return {
          ...config,
          ...userConfig,
        };
      };
      
        config.mysql = {
          // database configuration
          client: {
            // host
            host: 'localhost',
            // port
            port: '3306',
            // username
            user: 'root',
            // password
            password: 'qd1224',
            // 数据库名称
            database: 'blog_demo',
          },
          // load into app, default is open
          app: true,
          // load into agent, default is close
          agent: false,
        };
      

创建基本数据

  • 在数据库创建一个表,随意设计一个表录入一条数据

  • 到controller中写接口以及返回值,记得配置对应的路由

    // 使用get请求
    router.get('/client/index', controller.client.home.index);
    
    'use strict';
    const Controller = require('egg').Controller;
    
    class HomeController extends Controller {  
      async index() {
            //从全局this中结构出上下文的 ctx
          const { ctx } = this;
            //数据库查询命令可以在egg-mysql/github中查,这里是查询 表blog_title的全部数据
          const result = await this.app.mysql.select('blog_title', {});
            //可打印返回值,这是启动的命令行那里,不在浏览器中
          // console.log(result);
            //返回的值
          ctx.body = result;
          }
    }
    
  • 在浏览器中输入对应的路由,如果看到返回的json数据即可

接口拿取数据

  • 进入项目的根目录下面,注意是最外层的package.json同级目录

  • 安装axios

    yarn add axios
    
  • 在写请求之前我们可以先进行接口地址的配置,将其放在一个文件中去

  • 这里在根目录下创建config文件夹,在下面创建url.js的文件专门用来放地址

    const baseUrl = 'http://127.0.0.1:7001/client/'
    
    const urlPath = {
      getIndex: `${baseUrl}index`,
    }
    
    export default urlPath
    
  • 在pages下的index.js中开始写请求

    • 这里使用hooks写
    • 这里使用getInitialProps在其中写异步请求并且返回值
    • 接收props参数,这个参数可以打印出来,可以看到有data属性其中就是接口的返回值,
    • 拿到的值可以赋值给myList(自定义参数)就可以在jsx中循环生成数据了
    import React, { Fragment, useState, useEffect } from 'react'
    import Head from 'next/head'
    import axios from 'axios'
    
    import urlPath from '../config/url'
    
    const { getIndex: getList } = urlPath;
    
    const Home = (props) => {
      const list = props.data
      const [myList, setMyList ] = useState(list)
    
      return (
        <Fragment>
          <Head>
            <title>Home</title>
          </Head>
          <ul>
              {myList.map(item => {
              return (<li>item.title</li>)
            })}
          </ul>
       </Fragment>
      )
    }
    
    Home.getInitialProps = async () => {
      const promiseList = new Promise((resolve) => {
        axios.get(getList).then((res) => {
          resolve(res.data)
        })
      })
      return await promiseList, 
    }
    
    export default Home
    
    

解决跨域问题

  • 请求数据时会出现跨域的报错,虽然我们是都在本地,在端口不同而会导致跨域问题

  • 安装egg-cors

    npm install --save egg-cors
    
  • 配置插件 (和数据库插件一样需要进行配置)

    • plugin.js

      exports.cors = {
        enable: true,
        package: 'egg-cors',
      };
      
    • config.default.js

       // egg-cors 解决跨域
        config.security = {
          csrf: { enable: false },
          domainWhiteList: [ '*' ],
        };
        config.cors = {
          origin: 'http://localhost:3000', // 只允许这个域进行访问接口
          credentials: true, // 开启认证
          allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS',
        };
      
    • 在两个文件加入配置即可解决跨域请求了

小结:

基本的流程就是这些,其他的也就是业务逻辑不同导致的接口以及数据不同而已,都是按照这样来从数据库拿数据,接口返回值,页面请求数据,页面显示数据

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • 原文链接:http://www.jianshu.com/p/2a9367afe9e7 1510997059(1)....
    悬笔e绝阅读 5,404评论 0 0
  • ##### 什么是Socket.io 一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实...
    c4e78fd2e90b阅读 564评论 1 3
  • ##### 什么是Socket.io 一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实...
    49a054febed1阅读 5,115评论 5 2
  • 苦,才是人生。 苦,才是生活。 苦,才是拥有。 苦,才是逆旅。 人生有八苦: 生苦、老苦、病苦、死苦、 爱别离苦、...
    拾敬斋人阅读 339评论 0 0
  • 人到了一定年纪就得面临相应的事情。 在二十多岁这个尴尬的年纪总能遇到很多尴尬的事。 最尴尬的就是关于“对象”这件事...
    简小取阅读 372评论 17 7