時(shí)間:2023-06-06 13:36:01 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-06-06 13:36:01 來源:網(wǎng)站運(yùn)營
5分鐘上手Egg.js+nunjucks模板引擎快速開發(fā)SEO友好的官網(wǎng)項(xiàng)目:在日常的項(xiàng)目中,有時(shí)候還是不可避免的會(huì)維護(hù)一些jq官網(wǎng)項(xiàng)目等。面對(duì)此類需求,很多還是以前的老套路,前端寫頁面交給后端去套數(shù)據(jù)。很煩有木有~~而改動(dòng)之后還得交給后端再次修改,時(shí)間和溝通都是個(gè)麻煩。同時(shí)開發(fā)中,寫靜態(tài)頁面也很麻煩,不能復(fù)用,不能使用現(xiàn)在的工具,心累有木有~~當(dāng)然了,解決辦法很多 # 初始化 cnpm init egg --type=simple ? # 安裝依賴 cnpm i ? # 啟動(dòng)服務(wù) npm run dev
簡單看下生成的文件目錄(ps:個(gè)別文件是沒有的,后期自己添加的) 'use strict'; ? module.exports = app => { const { router, controller } = app; // 定義首頁的路由 // 即當(dāng)直接訪問域名的時(shí)候,將請(qǐng)求映射到controller.home.home中進(jìn)行進(jìn)一步的處理 router.get('/', controller.home.home); // 定義關(guān)于我們的路由 router.get('/about', controller.home.about); // 定義新聞詳情的路由 router.get('/details/:id', controller.home.details); };
xxx.com/about中的/about
'use strict'; ? const Controller = require('egg').Controller; ? class HomeController extends Controller { async home() { const { ctx } = this; await ctx.render('index.njk') } } ? module.exports = HomeController ? // 或者你也可以簡化一下寫法 module.exports = class extends require('egg').Controller { // ... }
// app/controller/home.js ? 'use strict'; module.exports = class extends require('egg').Controller { async details() { const { ctx } = this; try { // 調(diào)用service的home模塊中的details服務(wù) // 得到數(shù)據(jù)后,塞給靜態(tài)模板使用 const data = await ctx.service.home.details(ctx.params.id) // 渲染一個(gè)模板 await ctx.render('details.njk', data) } catch (error) { ctx.body = '新聞獲取出錯(cuò)' } } } ?
// 首先需要在app/下新建service文件夾 // 然后在service下新建home.js,最終為app/service/home.js ? 'use strict'; ? module.exports = class extends require('egg').Service { // 根據(jù)文章id獲取文章數(shù)據(jù) // 此處的id是controll調(diào)用service服務(wù)時(shí)傳遞的id async details(id) { try { const url = `https:xxxx.com/api/${id}` const { data } = await this.ctx.curl(url, { dataType: 'json' }) if (data.data && data.code === 200) { // 此處也可以對(duì)數(shù)據(jù)進(jìn)行處理后再返回 // 返回?cái)?shù)據(jù) return data.data } throw '數(shù)據(jù)獲取失敗' } catch (error) { throw error } } ? }
home.js
,是因?yàn)槲覀?code>controller中使用的是ctx.service.home
service.home
中的home
就是service
文件的文件名稱this.ctx.curl
方法請(qǐng)求其他接口的數(shù)據(jù)。類似于使用axios
獲取數(shù)據(jù)的操作。 # 首先安裝 cnpm i egg-view-nunjucks --save ? # 然后在根目錄下的config/plugin.js中使用插件 'use strict'; ? module.exports = { nunjucks: { enable: true, package: 'egg-view-nunjucks', } }; ? # 完成了插件的安裝和引入,我們還需要配置插件的參數(shù) # 根目錄下的config/config.default.js中 module.exports = appInfo => { // 其他代碼 // ... // 配置我們的插件參數(shù) config.view = { // 定義映射的文件后綴名 // 此處我們定義為.njk,那么我們的模板都需要以.njk結(jié)束, // 這樣該類型的文件才會(huì)被我們的模板插件進(jìn)行處理 mapping: { '.njk': 'nunjucks', } } ? // 其他代碼 // ... }
.njk
也是可以的,這個(gè)是自定義的,只要滿足你的模板文件的后綴名和你定義的一樣就行,這樣才會(huì)被插件處理。egg-view-nunjucks
封裝的是nunjucks
,nunjucks
推薦叫.njk
base.njk
這個(gè)模板,做了什么事情: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>{% block title %}title默認(rèn)內(nèi)容{% endblock %}</title> <meta name="keywords" content="{% block keywords %}keywords默認(rèn)內(nèi)容{% endblock %}"> <meta name="description" content="{% block description %}description默認(rèn)內(nèi)容{% endblock %}"> ? <link rel="stylesheet" type="text/css" href="../../public/css/base.css"> {% block head %}{% endblock %} </head> ? <body> <!-- 主體內(nèi)容部分 --> {% block content %}{% endblock %} ? <script src="../../public/js/jquery.js"></script> <!-- script部分 --> {% block script %}{% endblock %} </body> </html>
block
塊,這樣就可以在頁面中替換掉這塊的內(nèi)容。有些類似于vue的slot
插槽。 // 定義block塊 {% block title %}默認(rèn)內(nèi)容{% endblock %}
{% extends "./base/base.njk" %} ? {% block title %}這是一個(gè)新的title{% endblock %} {% block description %}這是一個(gè)新的description{% endblock %} {% block keywords %}壹沓科技,加入壹沓,聯(lián)系我們{% endblock %} {% set navActive = "about" %} ? {% block head %} <link rel="stylesheet" href="../public/css/swiper.min.css"> {% endblock %} ? {% block content %} <div class="page-wrapper"> <!-- 導(dǎo)入公共的nav模板 --> {% include './base/nav.njk' %} ? <!-- 背景圖 --> <section class="banner-wrapper"> <img src="../public/img/icon/about-banner.jpg" alt="背景LOGO"> <span>{{ userName }}</span> </section> <!-- 渲染html模板演示 --> <div>{{content | safe}}</div> ? <!-- 導(dǎo)入公共的底部模板 --> {% include './base/foot.njk' %} </div> {% endblock %} ? {% block script %} <script src="../public/js/swiper.min.js"></script> <script src="../public/js/about.js"></script> {% endblock %}
// 相對(duì)路徑即可 {% extends "./base/base.njk" %}
// 例如,設(shè)置該頁面的title // 如果不設(shè)置,就會(huì)使用基礎(chǔ)模板中默認(rèn)的 {% block title %}這是一個(gè)新的title{% endblock %}
// 定義了一個(gè)navActive變量 // 后面會(huì)講解一個(gè)常見的場(chǎng)景 {% set navActive = "about" %}
// 變量的使用,和vue的{{}}插值一樣 // 比如這個(gè)userName是我們從controller中調(diào)用service獲取的數(shù)據(jù)對(duì)象中的一個(gè)屬性, // 然后把對(duì)象傳遞給了模板, // 那么在模板中可以直接取對(duì)象中的屬性進(jìn)行渲染 // 注意,傳遞給模板的是一個(gè)對(duì)象,例如{userName: 'jack'},但是我們使用的時(shí)候直接取userName {{userName}} ? ? // 同樣的,我們?cè)谀0鍍?nèi)定義的變量也可以直接使用的 ? // 渲染html,比如很常見的富文本 // 類似vue的過濾器,這個(gè)safe是內(nèi)置的, // 過濾器也可以自定義,具體的查看文檔吧 {{content | safe}}
// 導(dǎo)入我們的nav模板 {% include './base/nav.njk' %}
<!-- 導(dǎo)航頭部 --> <nav class="nav-wrapper"> <ul class="menu-content"> <li> <a href="/news" class="{{ 'active' if navActive == 'news' else '' }}">動(dòng)態(tài)資訊</a> </li> <li> <a href="/about" class="{{ 'active' if navActive == 'about' else '' }}">關(guān)于我們</a> </li> </ul> </nav>
可以看到,我們對(duì)class名
進(jìn)行了一個(gè)if判斷,判斷當(dāng)變量navActive
是某些值的時(shí)候給他增加一個(gè)active
類名,否則就是各空的class名
。這里仔細(xì)注意一下寫法即可。 那么我們?cè)趺炊x變量呢?此時(shí)再回到上面定義變量的部分介紹,我們已經(jīng)在頁面中定義了一個(gè)變量navActive
,所以我們只需要每個(gè)頁面定義一個(gè)navActive
且值為我們需要的即可了。 // a標(biāo)簽跳轉(zhuǎn) <a href="/news"></a> ? // js調(diào)整也是一樣,使用router.js定義的路由 window.location.href="/news"
贊
跟關(guān)注
哦~ 關(guān)鍵詞:友好,項(xiàng)目,引擎,模板
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號(hào)
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。