從壹開(kāi)始前后端分離 [ Vue2.0+.NetCore2.1] 二十六║Client渲染乏冀、Server渲染知多少{補(bǔ)充}

前言

書(shū)接上文蝶糯,昨天簡(jiǎn)單的說(shuō)到了 SSR 服務(wù)端渲染的相關(guān)內(nèi)容《二十五║初探SSR服務(wù)端渲染》,主要說(shuō)明了相關(guān)概念辆沦,以及為什么使用等昼捍,昨天的一個(gè)小栗子因?yàn)闀r(shí)間問(wèn)題,沒(méi)有好好的給大家鋪開(kāi)來(lái)講肢扯,今天呢妒茬,咱們就繼續(xù)說(shuō)一下這個(gè) SSR 服務(wù)端渲染,并結(jié)合著 Client 客戶(hù)端渲染蔚晨,一起說(shuō)一說(shuō)相關(guān)的內(nèi)容乍钻,當(dāng)然還是圍繞著原理來(lái)的,并不是要搭建項(xiàng)目铭腕,項(xiàng)目我會(huì)在下一個(gè)系列說(shuō)到银择,經(jīng)過(guò)和群里小伙伴的商量,并采納大家的意見(jiàn)累舷,我初步考慮了下浩考,下一個(gè)系列我會(huì)說(shuō)下** Nuxt.js** 相關(guān)內(nèi)容(我感覺(jué)這個(gè)很有必要的說(shuō),現(xiàn)在網(wǎng)站SEO是灰常重要滴 )笋粟,然后再下一個(gè)系列就是搭建一個(gè)功能豐富的 后臺(tái)管理系統(tǒng) 作為開(kāi)源項(xiàng)目怀挠,手里有貨的小伙伴來(lái)群里,咱們一起開(kāi)源吧哈哈哈害捕。

這個(gè)時(shí)候細(xì)心的小伙伴會(huì)發(fā)現(xiàn)绿淋,每天的那個(gè)腦圖不見(jiàn)了,哈哈尝盼,并沒(méi)有吞滞,而是在最下邊,看文末就知道了盾沫。

一裁赠、Client 瀏覽器端渲染是怎樣運(yùn)行的

為了介紹瀏覽器渲染是怎么回事,我們運(yùn)行一下npm run build 看看我們之前的項(xiàng)目——就是我們的個(gè)人博客第一版赴精,大家應(yīng)該還記得《 二十二║Vue實(shí)戰(zhàn):個(gè)人博客第一版(axios+router)》佩捞,發(fā)布版本的文件,到底有哪些東西蕾哟,

執(zhí)行

npm run build

這里我們通過(guò) Webpack 打包一忱,將我們的項(xiàng)目打包莲蜘,生成一個(gè) dist 目錄 ,我們可以看到里面有 css+fonts+js 文件夾帘营,還有一個(gè) index.html 靜態(tài)頁(yè)面票渠,我們打開(kāi)這個(gè)靜態(tài)頁(yè)面,可以看到下面內(nèi)容:

<!DOCTYPE html>
<html lang=en>
<head>
    <meta charset=utf-8>
    <meta http-equiv=X-UA-Compatible content="IE=edge">
    <meta name=viewport content="width=device-width,initial-scale=1">
    <link rel=icon href=/favicon.ico>
    <title>blogvue3</title>
    <link href=/js/about.143cb27a.js rel=prefetch>
    <link href=/css/app.51e9ecbc.css rel=preload as= style>
    <link href=/css/chunk-vendors.5aa02cc7.css rel=preload as= style>
    <link href=/js/app.16d68887.js rel=preload as=script>
    <link href=/js/chunk-vendors.1c001ffe.js rel=preload as=script>
    <link href=/css/chunk-vendors.5aa02cc7.css rel=stylesheet>
    <link href=/css/app.51e9ecbc.css rel=stylesheet>//全部都是樣式文件芬迄,可忽略研究
</head>
<body>
    <noscript>
        <strong>We're sorry but blogvue3 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id=app />//頁(yè)面掛載入口
    <script src=/js/chunk-vendors.1c001ffe.js />//vue 用到的區(qū)塊文件问顷,vue-cli全家桶默認(rèn)配置里面這個(gè)chunk就是將所有從node_modules/里require(import)的依賴(lài)都打包到這里
    <script src=/js/app.16d68887.js />//這個(gè)就是我們項(xiàng)目的核心內(nèi)容,主要就是 app.vue 的內(nèi)容禀梳,封裝了所有方法杜窄,包括路由和頁(yè)面渲染之類(lèi)的
</body>
</html>
image

大家觀察生成的文件,只有一個(gè)div掛載入口出皇,并沒(méi)有多余的dom元素羞芍,那么頁(yè)面要怎么呈現(xiàn)呢?答案是js append拼接郊艘,對(duì)荷科,下面的那些 js 會(huì)負(fù)責(zé)innerHTML。而js是由瀏覽器解釋執(zhí)行的纱注,所以呢畏浆,我們稱(chēng)之為瀏覽器渲染,相信這里大家應(yīng)該很明白這個(gè)原理了狞贱,和我們平時(shí)用 jQuery 寫(xiě)局部異步加載是一樣的刻获,但是,這有幾個(gè)致命的缺點(diǎn):

  1. js放在dom結(jié)尾瞎嬉,如果js文件過(guò)大蝎毡,那么必然造成頁(yè)面阻塞。
  2. 隨著我們的業(yè)務(wù)需求增大氧枣,打包后的 js 文件愈來(lái)愈大沐兵,頁(yè)面白屏更加明顯,用戶(hù)體驗(yàn)明顯不好便监,特別是首頁(yè)扎谎,幾個(gè),幾十個(gè)組件一起渲染烧董,天訥毁靶!不敢相信
  3. 不利于SEO
  4. 客戶(hù)端運(yùn)行在老的JavaScript引擎上
image

這個(gè)時(shí)候,我們就想其他的一些辦法逊移,比如會(huì)單獨(dú)給我們的首頁(yè)寫(xiě)一個(gè)靜態(tài)處理预吆,為了應(yīng)對(duì)相應(yīng)速度,但是這個(gè)并不是一個(gè)好的辦法胳泉,我們需要處理兩套邏輯啡浊,基于以上的一些問(wèn)題觅够,服務(wù)端渲染呼之欲出....

總結(jié):相信大家看到這里應(yīng)該都能明白,客戶(hù)端渲染的工作原理了巷嚣,其實(shí)就是開(kāi)發(fā)的時(shí)候組件化,然后通過(guò) webpack 打包工具钳吟,將我們的邏輯處理 js 廷粒,打包成文件,然后和前端頁(yè)面一起部署红且,這樣就能講數(shù)據(jù)在 DOM 上展示出來(lái)了坝茎。

二、Server 服務(wù)端渲染是怎樣運(yùn)行的

上邊咱們看了客戶(hù)端瀏覽器渲染暇番,明白了原理和弊端嗤放,咱們這個(gè)時(shí)候就需要用到服務(wù)器渲染,SSR , Server Side Render的簡(jiǎn)稱(chēng), 服務(wù)端渲染. 首先服務(wù)端渲染的思想由來(lái)已久, 在 ajax 興起之前, 所有 web 應(yīng)用都是服務(wù)端渲染, 服務(wù)器直接返回 html 文本給瀏覽器, 用戶(hù)操作比如在登陸頁(yè)面提交表單, 成功后跳轉(zhuǎn)到首頁(yè), 服務(wù)器需要返回兩個(gè)頁(yè)面. 這樣的弊端顯而易見(jiàn), 加大了服務(wù)器的消耗壁酬,到了 vue 時(shí)代次酌,咱們雖然是通過(guò) api 返回的Json,但是需要 node 服務(wù)器, 很耗費(fèi)性能, 需要做好緩存和優(yōu)化, 相當(dāng)于空間換時(shí)間舆乔。

這里咱們先說(shuō)下原理

image

從這個(gè)圖里大家應(yīng)該也能看到岳服,我們的SSR打包流程變化了,在客戶(hù)端渲染的時(shí)候希俩,我們 webpack 是打包成js約束文件吊宋,直接發(fā)給瀏覽器,然后再獲取數(shù)據(jù)渲染DOM颜武,

網(wǎng)絡(luò)解釋有點(diǎn)兒羞澀難懂:ssr 有兩個(gè)入口文件璃搜,client.js 和 server.js, 都包含了應(yīng)用代碼鳞上,webpack 通過(guò)兩個(gè)入口文件分別打包成給服務(wù)端用的 server bundle 和給客戶(hù)端用的 client bundle. 當(dāng)服務(wù)器接收到了來(lái)自客戶(hù)端的請(qǐng)求之后这吻,會(huì)創(chuàng)建一個(gè)渲染器 bundleRenderer,這個(gè) bundleRenderer 會(huì)讀取上面生成的 server bundle 文件因块,并且執(zhí)行它的代碼橘原, 然后發(fā)送一個(gè)生成好的 html 到瀏覽器,等到客戶(hù)端加載了 client bundle 之后涡上,會(huì)和服務(wù)端生成的DOM 進(jìn)行 Hydration(判斷這個(gè)DOM 和自己即將生成的DOM 是否相同趾断,如果相同就將客戶(hù)端的vue實(shí)例掛載到這個(gè)DOM上, 否則會(huì)提示警告)吩愧。

可以看出來(lái)芋酌,我們?cè)黾恿艘粋€(gè)步驟:就是之前我們是在瀏覽器里,通過(guò)JavaScript框架來(lái)渲染數(shù)據(jù)的雁佳,但是現(xiàn)在我們的請(qǐng)求中間走了一遍 node 服務(wù)器脐帝,然后 node 服務(wù)器幫我們生成相應(yīng)的 Html 片段同云,直接發(fā)送給瀏覽器,那瀏覽器肯定是認(rèn)識(shí)html的堵腹,所以不用再通過(guò) js 去獲取數(shù)據(jù)渲染了答憔,直接就渲染了秕狰,嗯大概就是這樣,就好像多了一個(gè)中間件。

相信大家看內(nèi)容可能不是很清楚狠持,關(guān)鍵時(shí)候還是得上代碼才能說(shuō)的更清晰叛买。

三椰憋、通過(guò)代碼實(shí)現(xiàn)服務(wù)端渲染

客戶(hù)端渲染咱們就不寫(xiě)代碼了吧波势,這些天都寫(xiě)了很多了

1、首先我們新建一個(gè)文件夾 Vue_SSR_Demo 并對(duì)其 node 服務(wù)初始化

執(zhí)行

 npm install vue vue-server-renderer --save

會(huì)看到生成一個(gè) node_modules 文件夾 和 package-lock.json 文件笆檀。

然后執(zhí)行

 npm install express --save

安裝 express 的node服務(wù)忌堂。

2、然后創(chuàng)建一個(gè) index.html 頁(yè)面酗洒,作為一個(gè)承載頁(yè)面士修,類(lèi)似我們 vue-cli 腳手架中的 index.html

<!-- 如同vue-cli創(chuàng)建項(xiàng)目中的index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{title}}</title> {{{meta}}} </head>
<body>
    <!--vue-ssr-outlet-->
    <!--↑↑↑↑↑ 注意上邊的格式一定要有,并且不能帶空格 ↑↑↑↑↑-->
</body>
</html>

3寝蹈、新建一個(gè) server.js 文件李命,用作我們的啟服務(wù)入口

const Vue = require('vue')//引入 vue
const server = require('express')()//引入 express 服務(wù)框架
const fs = require('fs') //讀取 html 模版
const renderer = require('vue-server-renderer').createRenderer({
    template: fs.readFileSync('./index.html', 'utf-8')//文件地址路徑
}) // 此參數(shù)是vue 生成Dom之外位置的數(shù)據(jù)  如vue生成的dom一般位于body中的某個(gè)元素容器中, //此數(shù)據(jù)可在header標(biāo)簽等位置渲染箫老,是renderer.renderToString()的第二個(gè)參數(shù)封字, //第一個(gè)參數(shù)是vue實(shí)例,第三個(gè)參數(shù)是一個(gè)回調(diào)函數(shù)耍鬓。
const context = {
      title: '老張的哲學(xué)',
      meta:` <meta name="viewport" content="width=device-width, initial-scale=1" />
                  <meta name="description" content="vue-ssr">
                  <meta name="generator" content="GitBook 3.2.3"> `
} //定義服務(wù)
server.get('*', (req, res) => { //創(chuàng)建vue實(shí)例   主要用于替換index.html中body注釋地方的內(nèi)容阔籽, //index.html中 <!--vue-ssr-outlet-->的地方 ,約定熟成
    const app = new Vue({
        data: {
            url: req.url,
            data: ['C#', 'SQL', '.NET', '.NET CORE', 'VUE'],
            title: '我的技能列表' }, //template 中的文本最外層一定要有容器包裹牲蜀, 和vue的組件中是一樣的笆制, //只能有一個(gè)父級(jí)元素,這里是div涣达!
 template: ` <div>
                <p>{{title}}</p>
                <p v-for='item in data'>{{item}}</p>
            </div> `
    }) //將 Vue app實(shí)例渲染為字符串  (其他的API自己看用法是一樣的)
    renderer.renderToString(app, context,  (err, html) => { if (err) {
            res.status(500).end('err:' + err) return } //將模版發(fā)送給瀏覽器
 res.end(html) //每次請(qǐng)求 都在node 服務(wù)器中打印
        console.log('success')
    })
}) //服務(wù)端口開(kāi)啟并監(jiān)聽(tīng)
server.listen(8060, () => {
    console.log('server success!')
})

文檔中的解釋已經(jīng)很詳細(xì)了在辆,大家可以自行看一看,這樣我們就定義好了一個(gè) node 服務(wù)度苔,并通過(guò) express 框架匆篓,將我們的 vue 實(shí)例通過(guò) renderer.renderToString() 方法生成字符串,返回到瀏覽器寇窑。

4鸦概、開(kāi)啟 node 服務(wù)

執(zhí)行

node server

注意,這里的 server 是我們的文件名甩骏,你也可以用其他的窗市,比如 node aaa.js先慷,或者 node aaa

image

這個(gè)時(shí)候,我們就發(fā)現(xiàn)我們已經(jīng)成功的把我們的頁(yè)面內(nèi)容返回到了瀏覽器咨察,為什么呢论熙?因?yàn)槲覀兊捻?yè)面源代碼已經(jīng)有內(nèi)容了,證明不是通過(guò) js 后期渲染的摄狱。binggo赴肚!

大家有沒(méi)有對(duì) SSR 服務(wù)端渲染有一定的任何和了解,是不是品出來(lái)一點(diǎn)兒感覺(jué)了二蓝,這個(gè)還是最簡(jiǎn)單的一個(gè) node 服務(wù)器渲染。

代碼就不上傳了指厌,大家粘貼復(fù)制就行刊愚,全部結(jié)構(gòu)文件

image

四、通過(guò) webpack 打包踩验,來(lái)深入了解服務(wù)器渲染

dang dang dang鸥诽,如果大家看到這里不費(fèi)勁,或者看懂前邊的了箕憾,好滴牡借,你可以看這一塊了,如果上邊的不是很清晰袭异,或者很難懂钠龙,好吧,這一塊可能更羞澀了御铃,不過(guò)沒(méi)關(guān)系碴里,慢慢來(lái)!

1上真、這個(gè)代碼是昨天的咬腋,咱們這里重新說(shuō)一下

結(jié)構(gòu)如下:

├── dist                               // 保存我們的打包后的文件
├── node_modules                        // 依賴(lài)包文件夾
├── entry                              // 打包入口文件夾
│   └── entry-server.js                 // 服務(wù)端 打包入口文件
├── src                              // 我們的項(xiàng)目的源碼編寫(xiě)文件
│   ├── views                           // view存放目錄
│   │   ├── about.vue                //about 頁(yè)面
│   │   ├── like.vue                //like 頁(yè)面
│   │   └── Home.vue                   //Home 頁(yè)面
│   └── App.vue                     // App入口文件
│   └── main.js                      // 主配置文件
│   └── router.js                    // 路由配置文件
└── .babelrc                              // babel 配置文件
└── package.json                          // 項(xiàng)目依賴(lài)包配置文件
└── package-lock.json                     // npm5 新增文件,優(yōu)化性能
└── server.js                            // server 文件
└── README.md                             // 說(shuō)明文檔
image

咱們分塊的說(shuō)一說(shuō)

2睡互、普通的app代碼塊

image

這一塊根竿,就是對(duì)應(yīng)的我們 src 文件夾下的模板,這些內(nèi)容大家一定很熟悉了就珠,就不多說(shuō)了寇壳,就是 組件的定義、路由定義嗓违、app入口和 main.js 主方法九巡,這里重點(diǎn)說(shuō)下 main.js

image

在之前的 main.js 我們是直接實(shí)例化 vue() ,然后對(duì) #appp 進(jìn)行掛載的蹂季,但是現(xiàn)在咱們變成了 服務(wù)器渲染冕广,這里就不能掛載了疏日,而是把創(chuàng)建的vue實(shí)例返回出去。

//main.js
import Vue from 'vue' import createRouter from './router' import App from './App.vue'

// 導(dǎo)出一個(gè)工廠函數(shù)撒汉,用于創(chuàng)建新的vue實(shí)例
export function createApp() { const router = createRouter() const app = new Vue({
        router,
        render: h => h(App)
    }) return app
}

你會(huì)問(wèn)了沟优,但是返回給誰(shuí)呢,欸睬辐?挠阁!這個(gè)問(wèn)題好,請(qǐng)往下看溯饵。

3侵俗、講我們的 vue實(shí)例封裝到 promise

image

網(wǎng)友總結(jié):所謂Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器丰刊,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果隘谣。從語(yǔ)法上說(shuō),Promise 是一個(gè)對(duì)象啄巧,從它可以獲取異步操作的消息寻歧。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理秩仆。

Promise對(duì)象有以下兩個(gè)特點(diǎn)码泛。
(1)對(duì)象的狀態(tài)不受外界影響。Promise對(duì)象代表一個(gè)異步操作澄耍,有三種狀態(tài):Pending(進(jìn)行中)噪珊、Resolved(已完成,又稱(chēng) Fulfilled)和Rejected(已失斢馍弧)卿城。只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài)铅搓,任何其他操作都無(wú)法改變這個(gè)狀態(tài)瑟押。這也是Promise這個(gè)名字的由來(lái),它的英語(yǔ)意思就是“承諾”星掰,表示其他手段無(wú)法改變多望。
(2)一旦狀態(tài)改變,就不會(huì)再變氢烘,任何時(shí)候都可以得到這個(gè)結(jié)果怀偷。Promise對(duì)象的狀態(tài)改變,只有兩種可能:從Pending變?yōu)镽esolved和從Pending變?yōu)镽ejected播玖。只要這兩種情況發(fā)生椎工,狀態(tài)就凝固了,不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果维蒙。就算改變已經(jīng)發(fā)生了掰吕,你再對(duì)Promise對(duì)象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果颅痊。這與事件(Event)完全不同殖熟,事件的特點(diǎn)是,如果你錯(cuò)過(guò)了它斑响,再去監(jiān)聽(tīng)菱属,是得不到結(jié)果的。
有了Promise對(duì)象舰罚,就可以將異步操作以同步操作的流程表達(dá)出來(lái)纽门,避免了層層嵌套的回調(diào)函數(shù)。此外营罢,Promise對(duì)象提供統(tǒng)一的接口膜毁,使得控制異步操作更加容易。

簡(jiǎn)單來(lái)說(shuō)愤钾,就是把我們 main入口文件中的vue實(shí)例,都封裝到 promise候醒,就像增加一個(gè)外衣能颁,方便我們 webpack打包。對(duì)倒淫,重點(diǎn)來(lái)了

4伙菊、通過(guò) Webpack 服務(wù)器打包

image
/* 5、webpack.server.js 服務(wù)端打包 */
const path = require('path');//獲取路徑對(duì)象
const projectRoot = path.resolve(__dirname, '..');//根路徑 //定義模塊
module.exports = { // 此處告知 server bundle 使用 Node 風(fēng)格導(dǎo)出模塊(Node-style exports) // 這里必須是node敌土,因?yàn)榇虬瓿傻倪\(yùn)行環(huán)境是node镜硕,在node端運(yùn)行的,不是在瀏覽器端運(yùn)行返干。
    target: 'node', // entry需要提供一個(gè)單獨(dú)的入口文件
    entry: ['babel-polyfill', path.join(projectRoot, 'entry/entry-server.js')], // 輸出
 output: { //指定libraryTarget的類(lèi)型為commonjs2兴枯,用來(lái)指定代碼export出去的入口的形式。 // 在node.js中模塊是module.exports = {...}矩欠,commonjs2打包出來(lái)的代碼出口形式就類(lèi)似于此财剖。
        libraryTarget: 'commonjs2',
        path: path.join(projectRoot, 'dist'), // 打包出的路徑
        filename: 'bundle.server.js',// 打包最終的文件名,這個(gè)文件是給 node 服務(wù)器使用的
 },
    module: { // 因?yàn)槭褂脀ebpack2癌淮,這里必須是rules躺坟,如果使用use, // 會(huì)報(bào)個(gè)錯(cuò):vue this._init is not a function
 rules: [ //規(guī)則1乳蓄、vue規(guī)則定義
 {
            test: /\.vue$/,
            loader: 'vue-loader',
            },//js規(guī)則定義
 {
                test: /\.js$/,
                loader: 'babel-loader',
                include: projectRoot, // 這里會(huì)把node_modules里面的東西排除在外咪橙,提高打包效率
                exclude: /node_modules/, // ES6 語(yǔ)法
 options: {
                    presets: ['es2015']
                }
            },//css定義
 {
                test: /\.less$/,
                loader: "style-loader!css-loader!less-loader" }
        ]
    },
    plugins: [],
    resolve: {
        alias: { 'vue$': 'vue/dist/vue.runtime.esm.js' }
    }
}

基本的內(nèi)容就是上邊這些,注釋已經(jīng)很清楚了,大家可以看一看美侦,這個(gè)時(shí)候我們的準(zhǔn)備工作就已經(jīng)做好了产舞,下一步就改打包了

5、執(zhí)行打包命令音榜,生成服務(wù)端約束文件 bundle.server.js

npm run server

這個(gè)時(shí)候庞瘸,你會(huì)發(fā)現(xiàn),我們的dist 文件夾內(nèi)赠叼,多了一個(gè) bundle.server.js 文件

image

我們看一下生成的文件擦囊,部分截圖,會(huì)發(fā)現(xiàn)嘴办,我們的這個(gè)文件包含了所有頁(yè)面內(nèi)的內(nèi)容和方法瞬场,但是這個(gè) bundle.server.js 并不是直接返回給前端的,而且在 node 服務(wù)器使用的

image

6涧郊、配置 node 服務(wù)器啟動(dòng)文件贯被,這個(gè)更類(lèi)似我們上文中提到的 server.js 文件

/*7、 server.js */
const express = require('express')()//引入express 服務(wù)框架
const renderer = require('vue-server-renderer').createRenderer() const createApp = require('./dist/bundle.server.js')['default']//引入我們剛剛打包文件 // 響應(yīng)路由請(qǐng)求
express.get('*', (req, res) => { const context = { url: req.url } // 創(chuàng)建vue實(shí)例妆艘,傳入請(qǐng)求路由信息
    createApp(context).then(app => {
        renderer.renderToString(app, (err, html) => { if (err) { return res.state(500).end('運(yùn)行時(shí)錯(cuò)誤') }
            res.send(` <!DOCTYPE html>
                <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <title>Vue2.0 SSR渲染頁(yè)面</title>
                    </head>
                    <body> ${html} </body>
                </html> `)
        })
    }, err => { if(err.code === 404) { res.status(404).end('所請(qǐng)求的頁(yè)面不存在') }
    })
}) // 服務(wù)器監(jiān)聽(tīng)地址
express.listen(8089, () => {
    console.log('服務(wù)器已啟動(dòng)彤灶!')
})

7、啟動(dòng)服務(wù)

 node server

這個(gè)時(shí)候我們就可以看到效果了

好啦批旺,這個(gè)就是 SSR 服務(wù)端渲染的整個(gè)過(guò)程幌陕。

番外

哈嘍大家好,在這里忙碌的日子又和大家見(jiàn)面了汽煮,咱們的前后端系列入門(mén)篇已經(jīng) 26 篇了搏熄,按照我的計(jì)劃,基本的講解已經(jīng)到這里了暇赤,相信如果大家按照我寫(xiě)的系列心例,能搭建自己的博客系統(tǒng)了,甚至如果你比較厲害鞋囊,已經(jīng)開(kāi)始開(kāi)發(fā)中型項(xiàng)目了哈哈止后,咱們這里先回顧下知識(shí),包括 API 溜腐,Swagger 文檔坯门,Sugar 數(shù)據(jù)持久層的ORM,Repository倉(cāng)儲(chǔ)架構(gòu)逗扒,Asyn/Await 異步編程古戴,AOP面向切面編程,IoC控制反轉(zhuǎn)和DI依賴(lài)注入矩肩,Dto數(shù)據(jù)傳輸對(duì)象现恼,Redis緩存等后端知識(shí)肃续,還有Vue 基礎(chǔ)語(yǔ)法、JS高級(jí)叉袍、ES6始锚、Vue 組件 、生命周期喳逛、數(shù)據(jù)綁定瞧捌、開(kāi)發(fā)環(huán)境搭建、Vue-Cli 腳手架润文、axios Http請(qǐng)求姐呐、vue-router 路由協(xié)議、webpack 打包典蝌、Vuex 狀態(tài)管理等前端知識(shí)曙砂。雖然都是簡(jiǎn)單的說(shuō)了下皮毛,也是都涵蓋了這個(gè)框架內(nèi)容骏掀,咱們可以看看咱們的結(jié)構(gòu)樹(shù)鸠澈,這個(gè)每天都會(huì)出現(xiàn)的哈哈,這個(gè)就是這一個(gè)月咱們的辛苦,也是很有回報(bào)滴截驮,群里的小伙伴都破50了笑陈,這是個(gè)大圖,大家可以看看:

image

本來(lái)想著要換其他的系列葵袭,但是在群里小伙伴的建議下新锈,還是在把Vue好好說(shuō)說(shuō)吧,思考了下眶熬,在國(guó)慶前的時(shí)間再說(shuō)下 SSR 框架——Nuxt.js 吧,感覺(jué)這一塊應(yīng)該是要用到的块请,也是自學(xué)的一個(gè)吧娜氏,至于國(guó)慶之后,再慢慢考慮寫(xiě)其他的吧墩新。

QQ群:
867095512 (blod.core)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贸弥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子海渊,更是在濱河造成了極大的恐慌绵疲,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件臣疑,死亡現(xiàn)場(chǎng)離奇詭異盔憨,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)讯沈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)郁岩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事问慎∑继” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵如叼,是天一觀的道長(zhǎng)冰木。 經(jīng)常有香客問(wèn)我,道長(zhǎng)笼恰,這世上最難降的妖魔是什么踊沸? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮挖腰,結(jié)果婚禮上雕沿,老公的妹妹穿的比我還像新娘。我一直安慰自己猴仑,他們只是感情好审轮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著辽俗,像睡著了一般疾渣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上崖飘,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天榴捡,我揣著相機(jī)與錄音,去河邊找鬼朱浴。 笑死吊圾,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的翰蠢。 我是一名探鬼主播项乒,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼梁沧!你這毒婦竟也來(lái)了檀何?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤廷支,失蹤者是張志新(化名)和其女友劉穎频鉴,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體恋拍,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡垛孔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了施敢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片似炎。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡辛萍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出羡藐,到底是詐尸還是另有隱情贩毕,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布仆嗦,位于F島的核電站辉阶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏瘩扼。R本人自食惡果不足惜谆甜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望集绰。 院中可真熱鬧规辱,春花似錦、人聲如沸栽燕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)碍岔。三九已至浴讯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蔼啦,已是汗流浹背榆纽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捏肢,地道東北人奈籽。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像鸵赫,于是被迫代替她去往敵國(guó)和親衣屏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • awesome-github-vue 是由OpenDigg[https://blog.csdn.net/opend...
    我是七月閱讀 2,403評(píng)論 0 20
  • 一條靜謐的溪水,我漫步在溪邊的小路,微風(fēng)撩亂了垂柳柔順的長(zhǎng)發(fā),余暉在水面上拉開(kāi)了金色的秋幕奉瘤。 等候著圓月升起,凝視...
    老樹(shù)_閱讀 3,523評(píng)論 74 172
  • 攝影類(lèi)作者、講師煮甥,首先要在攝影領(lǐng)域有所成就盗温,這是一個(gè)看資歷的年代,所以接下來(lái)的主要目標(biāo)就是成肘,在攝影領(lǐng)域拿到成績(jī)卖局。 ...
    朱子先生的攝影思維閱讀 479評(píng)論 12 13
  • 7月14日,大概是我最期待的一天双霍,也是我最不愿意迎接的一天砚偶。 一直在為了自己的大學(xué)夢(mèng)努力的我批销,這個(gè)短暫...
    矮昭昭閱讀 310評(píng)論 0 0
  • 在這個(gè)環(huán)境待了有半個(gè)月了均芽。 半個(gè)月里,接觸到了形形色色的同事单鹿,小領(lǐng)導(dǎo)掀宋,大領(lǐng)導(dǎo),交流之后仲锄,發(fā)現(xiàn)每個(gè)人對(duì)自己的勸說(shuō)劲妙,告...
    張莞爾閱讀 162評(píng)論 0 0