[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, }; };- 可在egg-mysql找到其配置 https://github.com/eggjs/egg-mysql
- 根據自己的數據庫配置進行修改即可
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è)務邏輯不同導致的接口以及數據不同而已,都是按照這樣來從數據庫拿數據,接口返回值,頁面請求數據,頁面顯示數據