Eggjs配合Nextjs使用

[TOC]

Eggjs-Nextjs

先使用Nextjs的腳手架搭建整體架構

  • 這里使用

    npx create-next-app my-next-app
    

安裝egg.js

  • 我們先進入到項目的根文件夾中(與創(chuàng)建的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

    • 創(chuàng)建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文件夾下面創(chuàng)建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也是一樣創(chuàng)建client/home.js;只需在其寫方法即可;

連接數據庫

這里是使用mysql數據庫

使用egg-mysql插件

  • 如果eggjs是npm/i創(chuàng)建的那么最好使用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,
        };
      

創(chuàng)建基本數據

  • 在數據庫創(chuàng)建一個表,隨意設計一個表錄入一條數據

  • 到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
    
  • 在寫請求之前我們可以先進行接口地址的配置,將其放在一個文件中去

  • 這里在根目錄下創(chuàng)建config文件夾,在下面創(chuàng)建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中循環(huán)生成數據了
    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',
        };
      
    • 在兩個文件加入配置即可解決跨域請求了

小結:

基本的流程就是這些,其他的也就是業(yè)務邏輯不同導致的接口以及數據不同而已,都是按照這樣來從數據庫拿數據,接口返回值,頁面請求數據,頁面顯示數據

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 原文鏈接:http://www.itdecent.cn/p/2a9367afe9e7 1510997059(1)....
    懸筆e絕閱讀 5,674評論 0 0
  • ##### 什么是Socket.io 一個基于 Node.js 的實時應用程序框架,在即時通訊、通知與消息推送,實...
    c4e78fd2e90b閱讀 672評論 1 3
  • ##### 什么是Socket.io 一個基于 Node.js 的實時應用程序框架,在即時通訊、通知與消息推送,實...
    49a054febed1閱讀 5,200評論 5 2
  • 苦,才是人生。 苦,才是生活。 苦,才是擁有。 苦,才是逆旅。 人生有八苦: 生苦、老苦、病苦、死苦、 愛別離苦、...
    拾敬齋主凈默閱讀 441評論 0 0
  • 人到了一定年紀就得面臨相應的事情。 在二十多歲這個尷尬的年紀總能遇到很多尷尬的事。 最尷尬的就是關于“對象”這件事...
    簡小取閱讀 437評論 17 7

友情鏈接更多精彩內容