eggjs mysql 实战_Egg.js + MySQL + React + Antd-Mobile 实战移动端私人日记本

Egg.js 基础入门

简介

Egg.js 是啥呀?鸡蛋吗?开个小玩笑。Egg.js 是基于 Koa 的上层架构,简单说就是 Egg.js 是基于 Koa 二次开发的后端 node 解决方案。截止目前(2020-01-06) Egg 的最新版本为 v2.26.0,Github 上的星星居高不下,目前已达到了 14.6k+ 之多。可见大家对 Egg 的喜爱程度。

那么为什么我会选择 Egg 作为服务端的开发框架,而不选择 Nest、Think.js、Hapi 等框架呢?

首先 Egg 是阿里团队开发的,国内首屈一指的大厂。你不必担心这个框架的生态,更不用担心它会被停止维护,因为阿里内部很多系统也是在使用这个框架制作的。其次 Egg 在文档上做的不错,中英文文档对国人非常友好,说实话本人英文能力有限,虽说看看英文文档问题不大,但是多少看起来还是有点吃力。遇到问题的时候,还能去社区或者技术群里喊几句,遇到类似问题的朋友也会不惜余力的支援你。(普通小开发 不喜轻喷)

还有一个很重要的原因,Egg 继承于 Koa,在它的基础模型上,做了一些增强,在写法上可以说是十分便捷。相比之下 Koa 还是基础了,太多东西需要二次封装。在之后的开发中你会见识到 Egg 的强大之处。

Egg.js 开发环境搭建及生成项目目录讲解

我的环境:

操作系统:macOS

node 版本:12.6.0

npm 版本:6.9.0

通过如下脚本初始化项目:

mkdir egg-demo && cd egg-demo

npm init egg

// 选择 simple 模式的

npm install

如果 npm 不能使用的话建议安装 Yarn。

初始化项目目录如下如所示:

b56bac08642b39f37e88d6cc8d972385.png

项目文件结构分析

这里我挑重要的讲,因为有些开发中我们也不常去修改,不用浪费太多的精力去了解,当然有兴趣的小伙伴自己可以研究透彻一些。

app 文件夹:我们的主逻辑几乎都会在这个文件夹内完成,controller 是控制器文件夹,主要写一些业务代码,之后会在 app 文件夹里新建一个 service 文件夹,专门用来操作数据库,让业务逻辑和数据库操作分而治之,代码会清晰很多。

public文件夹:公用文件夹,把一些公用资源都放在这个文件夹下。

config 文件夹:这里存放一些项目的配置,如跨域的配置、数据库的配置等等。

logs文件夹:日志文件夹,正常情况下不用修改和查看里边内容。

run文件夹:运行项目时,生成的配置文件,基本不修改里边的文件。

test 文件夹: 测试使用的一些配置文件,测试接口的时候会用到。

.auto.conf.js:项目自动生成的文件,一般不需要修改。

.eslintignore 和 .eslintrc:代码格式化配置文件。

.gitignore:Git 提交的时候忽略的文件。

package.json:包管理和命令配置文件,开发时需要经常修改。

Egg.js 目录约定规范

Koa 之所以不适合团队项目的开发,是因为它缺少规范。Egg.js 在基于 Koa 的基础上制定了一些规范,所以我们放置一些脚本文件的时候,是要按照 Egg.js 的规范来的。

app/router.js 是放置路由的地方

public 文件夹放置一些公共资源如图片、公用的脚本等

app/service 文件夹放置数据库操作的内容

view 文件夹自然是放置前端模板的地方

middleware 是放置中间件的地方,这个很重要,鉴权等操作可以通过中间件的形式加入到路由,俗称路由守卫

还有挺多一些规范就不在此一一例举了,大家可以移步官方文档中文文档非常友好,向深入研究的同学可以挑灯夜读一番。

说了这么多好像忘记一件事情,咱们启动一下项目看看呗。在启动之前我们修改一点内容:

// /app/controller/home.js

'use strict';

const Controller = require('egg').Controller;

class HomeController extends Controller {

async index() {

const { ctx } = this;

ctx.body = 'hi, egg';

}

async test() {

const { ctx } = this;

ctx.body = '测试接口';

}

}

module.exports = HomeController;

// app/router.js

'use strict';

/**

* @param {Egg.Application} app - egg application

*/

module.exports = app => {

const { router, controller } = app;

router.get('/', controller.home.index);

router.get('/test', controller.home.test);

};

到项目根目录启动项目,命令行如下:

npm run dev

// 或者

yarn dev

正常情况下,Egg.js 默认启动 7001 端口,看到下图所示说明项目启动成功了。

e1521b813f19b38ba57fa5a6c4805232.png

我们通过浏览器查看如下所示:

0cb6b19a4760322eefa4d9143f408cad.png

我们在 /app/controller/home.js 文件中写的 test 方法成功被执行。

理解 Egg.js 的路由机制

路由(Router)主要用来描述请求 URL 和具体承担执行的 Controller 的对应关系,Egg.js 约定了 app/router.js 文件用于统一所有路由规则。

简单来说,上述例子,我们在 app/controller/home.js 里写了 test 方法,然后在 app/router.js 文件中将 test 方法以 GET 的形式抛出。这便是 URL 和 Controller 的对应关系。Egg.js 的方便就是体现在上下文已经为我们打通了,app 便是全局应用的上下文。路由和控制器都存放在全局应用上下文 app 里,所以你只需要关心你的业务逻辑和数据库操作便可,无需再为其他琐碎小事分心。

控制器(Controller)内主要编写业务逻辑,我们来了解一下如何命名,比如我现在希望新建一个与用户相关的控制器,我们可以这么写:

// 在 app/controller/ 下新建 user.js

'use strict';

const Controller = require('egg').Controller;

class UserController extends Controller {

async index() {

const { ctx } = this;

ctx.body = '用户';

}

}

module.exports = UserController;

首字母大写驼峰命名,UserController 继承 Controller,内部可以使用 async、await 的方式编写函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下拉多选可以使用antd-mobile的CheckboxItem组件来实现。具体代码如下: ```jsx import React, { useState } from 'react'; import { List, Checkbox } from 'antd-mobile'; const CheckboxItem = Checkbox.CheckboxItem; const options = [ { label: '选项1', value: '1' }, { label: '选项2', value: '2' }, { label: '选项3', value: '3' }, { label: '选项4', value: '4' }, ]; const MultipleSelect = () => { const [selectedValues, setSelectedValues] = useState([]); const handleCheckboxChange = (value) => { const currentIndex = selectedValues.indexOf(value); const newValues = [...selectedValues]; if (currentIndex === -1) { newValues.push(value); } else { newValues.splice(currentIndex, 1); } setSelectedValues(newValues); }; return ( <List> {options.map((option) => ( <CheckboxItem key={option.value} checked={selectedValues.indexOf(option.value) !== -1} onChange={() => handleCheckboxChange(option.value)} > {option.label} </CheckboxItem> ))} </List> ); }; export default MultipleSelect; ``` 上面的代码中,我们定义了一个`options`数组来存储选项列表。然后使用`useState`来管理已选中的值,初始值为空数组。在`handleCheckboxChange`方法中,我们根据选项的值来判断它是否已经被选中,如果已经被选中,则从已选中的值数组中删除该值,否则将该值添加到已选中的值数组中。最后通过`setSelectedValues`更新已选中的值数组。 在渲染时,我们遍历选项列表,并为每个选项渲染一个`CheckboxItem`组件。我们使用`checked`属性来判断该选项是否已经被选中,使用`onChange`事件来处理选项的选择和取消选择操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值