<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        vue ssr 指南詳讀

        來源:懂視網 責編:小采 時間:2020-11-27 22:12:15
        文檔

        vue ssr 指南詳讀

        vue ssr 指南詳讀:本帖說明 該貼是對vue SSR Guide解讀和補充,對于官網文檔已有內容會以引用方式體現。由于官網demo在國內無法運行,該貼最后也提供了一個完整的可以運行的demo,帖子中提到的代碼均是來自于該demo,供學習交流。 介紹 什么是服務器端渲染(SSR)? Vu
        推薦度:
        導讀vue ssr 指南詳讀:本帖說明 該貼是對vue SSR Guide解讀和補充,對于官網文檔已有內容會以引用方式體現。由于官網demo在國內無法運行,該貼最后也提供了一個完整的可以運行的demo,帖子中提到的代碼均是來自于該demo,供學習交流。 介紹 什么是服務器端渲染(SSR)? Vu

        本帖說明

        該貼是對vue SSR Guide解讀和補充,對于官網文檔已有內容會以引用方式體現。由于官網demo在國內無法運行,該貼最后也提供了一個完整的可以運行的demo,帖子中提到的代碼均是來自于該demo,供學習交流。

        介紹

        什么是服務器端渲染(SSR)?

        Vue.js 是構建客戶端應用程序的框架。默認情況下,可以在瀏覽器中輸出 Vue 組件,進行生成 DOM 和操作 DOM。然而,也可以將同一個組件渲染為服務器端的 HTML 字符串,將它們直接發送到瀏覽器,最后將靜態標記"混合"為客戶端上完全交互的應用程序。

        借助vue-server-renderer 將vue實例渲染為瀏覽器可以識別的html字符串。

        為什么使用服務器端渲染(SSR)?

        1. 更好的 SEO
        2. 更快的內容到達時間 (白屏)

        左側為瀏覽器渲染,右側為服務器渲染,從圖中可以看出服務端渲染理論上明顯少于瀏覽器渲染。

        基本用法

        安裝

        git clone https://github.com/s249359986/learnssr.git
        cd learnssr 
        npm install
        npm run dev

        代碼結構

        src
        ├── components
        │ ├── Foo.vue
        ├── views
        │ ├── Home.vue
        ├── App.vue
        ├── app.js 
        ├── client-entry.js
        ├── server-entry.js
        

        代碼詳解

        server.js 是服務端啟動入口文件,接收客戶端對頁面的所有請求。

        if (isProd) {
         /**
         生產環境,createRenderer將已經通過webpack打包好的server-bundle.js轉化為一個可以操作的renderer對象。
         **/
         renderer = createRenderer(fs.readFileSync(resolve('./dist/server-bundle.js'), 'utf-8'))
         
         /**
         入口模板文件
         **/
         indexHTML = parseIndex(fs.readFileSync(resolve('./dist/index.html'), 'utf-8'))
        } else {
         /**
         開發環境,createRenderer將已經通過webpack打包好的server-bundle.js轉化為一個可以操作的renderer對象。
         **/
         require('./build/setup-dev-server')(app, {
         bundleUpdated: bundle => {
         renderer = createRenderer(bundle)
         },
         indexUpdated: index => {//index為入口文件及index.html
         indexHTML = parseIndex(index)
         }
         })
        }
        
        function createRenderer (bundle) {
        
         return require('vue-server-renderer').createBundleRenderer(bundle, {
         cache: require('lru-cache')({
         max: 1,//1000,
         maxAge: 2000//1000 * 60 * 15
         }),
         runInNewContext: false
         })
        }
        /*
        讀取入口文件
        */
        function parseIndex (template) {
         const contentMarker = '<!-- APP -->'
         const i = template.indexOf(contentMarker)
         return {
         head: template.slice(0, i),
         tail: template.slice(i + contentMarker.length)
         }
        }
        
        const serve = (path, cache) => express.static(resolve(path), {
         maxAge: cache && isProd ? 60 * 60 * 24 * 30 : 0
        })
        
        app.use('/dist', serve('./dist'))
        
        app.get('*', (req, res) => {
         if (!renderer) {
         return res.end('waiting for compilation... refresh in a moment.')
         }
        
         res.setHeader('Content-Type', 'text/html')
         res.setHeader('Server', serverInfo)
        
         var s = Date.now()
         const context = { url: req.url }
         /*
         渲染vue實例,context對象上下文
         */
         const renderStream = renderer.renderToStream(context)
        
         renderStream.once('data', () => {
         res.write(indexHTML.head)
         })
        
         renderStream.on('data', chunk => {
         res.write(chunk)
         })
        
         renderStream.on('end', () => {
         if (context.initialState) {
         res.write(
         `<script>window.__INITIAL_STATE__=${
         serialize(context.initialState, { isJSON: true })
         }</script>`
         )
         }
         res.end(indexHTML.tail)
         console.log(`whole request: ${Date.now() - s}ms`)
         })
        
         renderStream.on('error', err => {
         if (err && err.code === '404') {
         res.status(404).end('404 | Page Not Found')
         return
         }
         res.status(500).end('Internal Error 500')
         console.error(`error during render : ${req.url}`)
         console.error(err)
         })
        })
        
        const port = process.env.PORT || 8080
        app.listen(port, () => {
         console.log(`server started at localhost:${port}`)
        })
        
        

        服務端vue實例入口文件,通過上下文對象獲取請求的url,映射給對應的組件。

        export default context => {
         const s = isDev && Date.now()
         router.push(context.url)
         const matchedComponents = router.getMatchedComponents()
         if (!matchedComponents.length) {
         return Promise.reject({ code: '404' })
         }
         return Promise.all(matchedComponents.map(component => {
        /*
        增加服務端數據預處理 start
        
        */
         if (component.asyncData) {
         return component.asyncData({
         store,
         route: router.currentRoute
         })
         }
        
         /*
         增加服務端數據預處理 end
        
         */
         })).then(() => {
         isDev && console.log(`data pre-fetch: ${Date.now() - s}ms`)
         context.initialState = store.state
         return app
         })
        }
        
        

        客戶端vue實例入口文件.

        /*
        
        第一種方式
         */
        
        Vue.mixin({
         beforeMount () {
         const { asyncData } = this.$options
         console.log('beforeMount',this.$store)
         if (asyncData) {
        
         // 將獲取數據操作分配給 promise
         // 以便在組件中,我們可以在數據準備就緒后
         // 通過運行 `this.dataPromise.then(...)` 來執行其他任務
         this.dataPromise = asyncData({
         store: this.$store,
         route: this.$route
         })
         }
         },
         beforeRouteUpdate (to, from, next) {
         const { asyncData } = this.$options
         console.log('beforeRouteUpdate',this.$store)
         if (asyncData) {
         asyncData({
         store: this.$store,
         route: to
         }).then(next).catch(next)
         } else {
         next()
         }
        }
        })
        
        /**
        更新客戶端store,與服務端store同步
        **/
        // store.replaceState(window.__INITIAL_STATE__)
        if (window.__INITIAL_STATE__) {
         store.replaceState(window.__INITIAL_STATE__)
        }
        // actually mount to DOM
        
        
        router.onReady(() => {
        /**
        掛載實例,客戶端激活,所謂激活,指的是 Vue 在瀏覽器端接管由服務端發送的靜態 HTML,使其變為由 Vue 管理的動態 DOM 的過程。注釋掉app.$mount('#app') 可以清楚看到<div id="app" data-server-rendered="true"> 客戶端通過data-server-rendered="true"知道該html是vue在服務端渲染的,并且不會在做多余的渲染。由于在服務端無法綁定事件,只有通過客戶端vue處理。
        **/
         app.$mount('#app')
        })
        

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        vue ssr 指南詳讀

        vue ssr 指南詳讀:本帖說明 該貼是對vue SSR Guide解讀和補充,對于官網文檔已有內容會以引用方式體現。由于官網demo在國內無法運行,該貼最后也提供了一個完整的可以運行的demo,帖子中提到的代碼均是來自于該demo,供學習交流。 介紹 什么是服務器端渲染(SSR)? Vu
        推薦度:
        標簽: VUE ssr 指南
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲中文字幕日产乱码高清app| 两个人的视频高清在线观看免费| 国产精品免费在线播放| 成全视频在线观看免费| 在线看无码的免费网站| 无限动漫网在线观看免费| 免费A级毛片无码A∨男男| 国产亚洲av片在线观看播放| 久久久无码精品亚洲日韩京东传媒| 国产成人亚洲综合一区| 国产免费人成视频在线播放播| 国产成人精品免费视频动漫| 中文字幕亚洲综合久久男男| 亚洲国产精品成人精品软件| 一本到卡二卡三卡免费高| 国产免费丝袜调教视频| 亚洲精品无码久久久影院相关影片 | 亚洲综合av一区二区三区不卡 | 凹凸精品视频分类国产品免费| 亚洲乱码中文字幕综合| 亚洲综合精品第一页| 又大又粗又爽a级毛片免费看| jizz免费在线观看| 一区二区三区亚洲| 亚洲精品黄色视频在线观看免费资源| 久久久无码精品亚洲日韩软件 | 亚洲人成日本在线观看| 91在线视频免费观看| 免费观看国产精品| 国产一级一毛免费黄片| 综合亚洲伊人午夜网| 美女内射无套日韩免费播放| 亚洲精品字幕在线观看| AV大片在线无码永久免费| 国产AV无码专区亚洲AV麻豆丫| av无码久久久久不卡免费网站| AV激情亚洲男人的天堂国语| 亚洲va国产va天堂va久久| 大地资源网高清在线观看免费 | 国产成A人亚洲精V品无码性色| 一本岛v免费不卡一二三区|