使用Nodejs写一个英雄联盟英雄故事网站
前言
- 纯属无聊,写一个英雄联盟故事网站小demo,设计方案:展示英雄列表,点击英雄跳转至英雄故事。在线展示
- 英雄联盟官网的一些接口可以直接调用,本文主要用到以下两个
- 使用
express
做后台服务,nunjucks
做模板引擎,简单明了。 - 推荐一个库
request-promise
,此库可以直接await request结果,无需自己封装。 - 源码至github
英雄联盟api
拳头并没有直接开放api,用到的两个api是国服官网的api,可以直接调用。不保证长期有效。
网站用到的图片图标全部来自官方,纯玩。
开始
yarn add express nunjucks request request-promise
# or
npm install express nunjucks request request-promise
目录结构
|-- lol
|-- node_modules
|-- public
| |-- favicon.ico
| |-- style.css
|-- router
| |-- home.js
| |-- hero.js
|-- views
| |-- home.njk
| |-- hero.njk
|-- app.js
|-- package.json
|-- yarn.lock or package-lock.json
搭服务
先起服务
express
起服务是非常简单、快的,几行代码一个服务。
// ./app.js
var express = require("express");
var app = express();
app.get("/", (req, res) => {
res.send("lol");
});
app.listen(8012);
添加模板引擎
ejs、nunjucks、jede大同小异,都可以用。
// ./app.js
var express = require("express");
var app = express();
var nunjucks = require("nunjucks");
/** 启用nunjucks 并设置views文件夹为页面文件 */
/** mkdir ./views */
nunjucks.configure(path.join(__dirname, "views"), {
autoescape: true,
express: app,
});
/** 设置静态资源目录 */
app.use(express.static(path.join(__dirname, "public")));
app.get("/", (req, res) => {
res.send("lol");
});
app.listen(8012, () => {
console.log(`lol serve start ok! port:${8012}`);
});
路由
路由文件夹
因为设计方案是首页展示英雄列表,点击英雄图片进入展示英雄故事,那么至少需要两个路由 /
和 /:hero
创建/router
目录,创建/router/home.js
和/router/hero.js
文件
express配置路由
// ./app.js
// app.get("/", (req, res) => {
// res.send("lol");
// });
app.get("/", require("./router/home"));
app.get("/:hero", require("./router/hero"));
页面
/views
下创建/views/base.njk
、/views/home.njk
、/views/hero.njk
这里使用njk作为后缀,也可以用html,具体配置见nunjucks
njk模板语法比较简单,详情见nunjucks语法
模板页
base.njk
为模板页,引用一些资源。
使用bootstrap
来排版吧
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>英雄联盟 - 英雄故事</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/css/bootstrap.min.css"/>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/twitter-bootstrap/4.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="/style.css"/>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
首页(英雄列表页)
// ./router/home.js
const rq = require("request-promise");
module.exports = async function (req, res) {
/** 接口直接返回了英雄列表,还有版本信息、更新日期等,此处直接返回列表给前端即可 */
const result = await rq(
"https://yz.lol.qq.com/v1/zh_cn/search/index.json"
).then((res) => JSON.parse(res));
res.render("home.njk", { list: result.champions });
};
// ./views/home.njk
{% extends "base.njk" %}
{% block content %}
<div class="list-block">
<div class="container">
<div class="header">
<h2>英雄联盟人物故事</h2>
<div class="search">
<input type="email" class="form-control" id="searchInput" aria-describedby="emailHelp" value="{{queryVal}}"/>
<button type="button" class="btn btn-primary" onclick="Javascript: window.location.href = '/'+$(`#searchInput`).val()+''">
搜索
</button>
</div>
</div>
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-4">
{% for item in list %}
<div class="col">
<div class="card" onclick="window.open('/{{item.slug}}')">
<img src="{{item.image.uri}}" class="card-img-top" />
<div class="card-body">
<h5 class="card-title">{{ item.name }}</h5>
<p class="card-text">
{{ item.slug }}
</p>
<p class="card-text">
{{ item["release-date"] }}
</p>
</div>
</div>
</div>
{% else %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}
故事页
// ./router/hero.js
const rq = require("request-promise");
module.exports = async function (req, res) {
const hero = req.params.hero;
/** 该接口传入英雄名,注意:这个英雄名是通过英雄列表获取的字段为'sign',并不是name */
/** 接口会将该英雄所有信息全部返回,此demo只取英雄故事,所以其他功能自行扩展 */
const result = await rq(
`https://yz.lol.qq.com/v1/zh_cn/champions/${hero}/index.json`
).then((res) => JSON.parse(res));
const champion = result.champion;
res.render("hero.njk", {
info: {
name: champion.name,
nickname: champion.title,
img: champion.image.uri,
fullDesc: champion.biography.full,
gameUri: champion["game-info-url"],
},
});
};
// ./views/hero.njk
{% extends "base.njk" %}
{% block content %}
<div class="info-block">
<div class="info-header">
<img class="background" src="https://game.gtimg.cn/images/lol/universe/v1/assets/images/vastaya-journal-long.jpg" />
<span class="info-name">{{info.nickname}}
:
{{info.name}}</span>
<img src="https://game.gtimg.cn/images/lol/universe/images/t1HeaderDivider.png" srcset=""/>
<a href="{{info.gameUri}}">游戏信息</a>
</div>
<div class="info-body">
<div class="desc">
{{info.fullDesc | replace("<p>", "") | replace("</p>", "")}}
</div>
</div>
</div>
{% endblock %}
效果
完成
功能比较简单,适合初学者学习,如有问题可以留言。
页面做了简单的展示,如需扩展可自行加功能,英雄联盟官网可以继续再挖掘一些接口。
代码存放在github,有兴趣的同学可以玩一玩。
文章版权声明:除非注明,否则均为猿易帮原创文章,转载或复制请以超链接形式并注明出处。
还没有评论,来说两句吧...