国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Vue頁面骨架屏的實現方法

2019-11-19 13:48:11
字體:
來源:轉載
供稿:網友

在開發webapp的時候總是會受到首屏加載時間過長的影響,主流的解決方法是在載入完成之前顯示loading圖效果,而一些大公司會配置一套服務端渲染的架構來解決這個問題??紤]到ssr所要解決的一系列問題,越來越多的APP采用了“骨架屏”的方式去提升用戶體驗。

小米商城:

一、分析Vue頁面的內容加載過程

vue項目中的入口index.html只有簡單的內容:

<!DOCTYPE html><html lang="zh-CN"><head>  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">  <title>Document</title></head><body>  <div id="root">      </div>  <script type="text/javascript" src="bundle.js"></script></body></body></html>

當js執行完之后,會用vue渲染成的dom將div#root完全替換掉。

我們在div#root中加入模擬骨架屏,在Chrome開發者工具調整網速:

<div id="root">  這里是骨架屏</div>


由此可知,將骨架屏內容直接插入div#root中即可實現骨架屏。

二、使用vue-server-renderer來實現骨架屏

我們需要骨架屏也是一個單獨的.vue文件,因此我們需要用到vue-server-renderer。對vue服務端渲染有所了解的同學一定知道,這個插件能夠將vue項目在node端打包成一個bundle,然后由bundle生成對應的html。
首先是生成項目:

.├── build│  ├── webpack.config.client.js│  └── webpack.config.server.js├── src│  └── views│    ├── index│    │  └── index.vue│    ├── skeleton│    │  └── skeleton.vue│    ├── app.vue│    ├── index.js│    └── skeleton-entry.js├── index.html└── skeleton.js└── package.json

vue的服務端渲染一般會用vue-server-renderer將整個項目在node端打包成一份bundle,而這里我們只要一份有骨架屏的html,所以會有一個單獨的骨架屏入口文件skeleton-entry.js,一個骨架屏打包webpack配置webpack.config.server.js,而skeleton.js作用是將webpack打包出來的bundle寫入到index.html中。

//skeleton-entry.jsimport Vue from 'vue'import Skeleton from './views/skeleton/skeleton.vue'export default new Vue({ components: {  Skeleton }, template: '<skeleton />'})
//webpack.config.server.jsconst path = require('path')const { VueLoaderPlugin } = require('vue-loader')const VueSSRServerPlugin = require('vue-server-renderer/server-plugin')module.exports = { mode: process.env.NODE_ENV, target: 'node', entry: path.join(__dirname, '../src/skeleton-entry.js'), output: {  path: path.join(__dirname, '../server-dist'),  filename: 'server.bundle.js',  libraryTarget: 'commonjs2' }, module: {  rules: [   {    test: //.vue$/,    loader: 'vue-loader'   },   {    test: //.css$/,    use: [     'vue-style-loader',     'css-loader'    ]   }    ] }, externals: Object.keys(require('../package.json').dependencies), resolve: {  alias: {   'vue$': 'vue/dist/vue.esm.js'  } }, plugins: [  new VueLoaderPlugin(),  new VueSSRServerPlugin({   filename: 'skeleton.json'  }) ]}

其中骨架屏的webpack配置因為是node端,所以需要target: 'node' libraryTarget: 'commonjs2'。在VueSSRServerPlugin中,指定了其輸出的json文件名。當執行webpack會在/server-dist目錄下生成一個skeleton.json文件,這個文件記載了骨架屏的內容和樣式,會提供給vue-server-renderer使用。

//skeleton.jsconst fs = require('fs')const path = require('path')const createBundleRenderer = require('vue-server-renderer').createBundleRenderer// 讀取`skeleton.json`,以`index.html`為模板寫入內容const renderer = createBundleRenderer(path.join(__dirname, './server-dist/skeleton.json'), { template: fs.readFileSync(path.join(__dirname, './index.html'), 'utf-8')})// 把上一步模板完成的內容寫入(替換)`index.html`renderer.renderToString({}, (err, html) => { fs.writeFileSync('index.html', html, 'utf-8')})

注意,作為模板的html文件,需要在被寫入內容的位置添加<!--vue-ssr-outlet-->占位符,本例子在div#root里寫入:

<div id="root"><!--vue-ssr-outlet--></div>

最后執行node skeleton就能實現vue的骨架屏。

最終的index.html:

<!DOCTYPE html><html lang="zh-CN"><head>  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">  <title>Document</title><style data-vue-ssr-id="a7049cb4:0">.skeleton[data-v-61761ff8] { position: relative; height: 100%; overflow: hidden; padding: 15px; box-sizing: border-box; background: #fff;}.skeleton-nav[data-v-61761ff8] { height: 45px; background: #eee; margin-bottom: 15px;}.skeleton-swiper[data-v-61761ff8] { height: 160px; background: #eee; margin-bottom: 15px;}.skeleton-tabs[data-v-61761ff8] { list-style: none; padding: 0; margin: 0 -15px; display: flex; flex-wrap: wrap;}.skeleton-tabs-item[data-v-61761ff8] { width: 25%; height: 55px; box-sizing: border-box; text-align: center; margin-bottom: 15px;}.skeleton-tabs-item span[data-v-61761ff8] { display: inline-block; width: 55px; height: 55px; border-radius: 55px; background: #eee;}.skeleton-banner[data-v-61761ff8] { height: 60px; background: #eee; margin-bottom: 15px;}.skeleton-productions[data-v-61761ff8] { height: 20px; margin-bottom: 15px; background: #eee;}</style></head><body>  <div id="root">    <div data-server-rendered="true" class="skeleton page" data-v-61761ff8><div class="skeleton-nav" data-v-61761ff8></div> <div class="skeleton-swiper" data-v-61761ff8></div> <ul class="skeleton-tabs" data-v-61761ff8><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li><li class="skeleton-tabs-item" data-v-61761ff8><span data-v-61761ff8></span></li></ul> <div class="skeleton-banner" data-v-61761ff8></div> <div class="skeleton-productions" data-v-61761ff8></div><div class="skeleton-productions" data-v-61761ff8></div><div class="skeleton-productions" data-v-61761ff8></div><div class="skeleton-productions" data-v-61761ff8></div><div class="skeleton-productions" data-v-61761ff8></div><div class="skeleton-productions" data-v-61761ff8></div></div>  </div></body></html>

看下效果:


效果還是闊以的。

尾聲

文章開頭小米商城手機頁面就是用的這樣的方法,不同的是它的骨架屏是一個base64的圖片。

更多關于vue-server-renderer內容請戳vue-ssr

文章相關代碼已經同步到Github,歡迎查閱~

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 育儿| 宝应县| 绿春县| 剑河县| 平昌县| 邛崃市| 巴里| 特克斯县| 长子县| 惠州市| 张家口市| 柳州市| 南郑县| 绥德县| 乐业县| 石林| 乌兰察布市| 漠河县| 方城县| 建瓯市| 大理市| 广西| 华容县| 宝坻区| 齐河县| 固安县| 崇阳县| 祁阳县| 惠安县| 博白县| 宜春市| 苍南县| 乌兰浩特市| 孟连| 西昌市| 辽阳县| 昌吉市| 安仁县| 新竹县| 广饶县| 元阳县|