日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

vue項目中使用骨架屏的方法

瀏覽:24日期:2022-09-29 13:31:15

現(xiàn)在的應(yīng)用開發(fā),基本上都是前后端分離的,前端主流框架有SPA、MPA等,那么解決頁面渲染、白屏時間成為首要關(guān)注的點

webpack可以按需加載,減小首屏需要加載代碼的體積;

使用CDN技術(shù)、靜態(tài)代碼等緩存技術(shù),可以減小加載渲染的時長

問題:但是首頁依然存在加載、渲染等待時長的問題。那么如何從視覺效果上減小首屏白屏的時間呢?

骨架屏:舉個例子:其實就是在模版文件中id=app容器下面寫想要展示的效果,在new Vue(option)之后,該id下的內(nèi)容就被替換了( 這時候,可能Vue編譯生成的內(nèi)容還沒有掛載。因為new Vue的時候會進行一系列的初始化,這也需要耗費時間的)。這樣就可以從視覺上減小白屏的時間

骨架屏的實現(xiàn)方式

1、直接在模版文件id=app容器下面,寫進想要展示的效果html

2、直接在模板文件id=app容器下面,用圖片展示

3、使用vue ssr提供的webpack插件

4、自動生成并且自動插入靜態(tài)骨架屏

方式1和方式2存在的缺陷:針對不同入口,展示的效果都一樣,導(dǎo)致不能靈活的針對不同的入口,展示不同的樣式

方式3可以針對不同的入口展示不同的效果。(實質(zhì)也是先通過ssr生成一個json文件,然后將json文件內(nèi)容注入到模板文件的id=app容器下)

方案一、直接在模版文件id=app容器下面,寫進想要展示的效果html

在根目錄的模版文件內(nèi)寫進內(nèi)容,如紅色圈出來的地方

vue項目中使用骨架屏的方法

在瀏覽器打開項目

在調(diào)用new Vue之前的展示效果(只是做了個簡單效果,不喜勿噴):

vue項目中使用骨架屏的方法

可以看到elements中id=app的容器下內(nèi)容,就是我們寫進的骨架屏效果內(nèi)容

vue項目中使用骨架屏的方法

在看下調(diào)了new Vue之后的效果,id=app容器下的內(nèi)容被vue編譯生成的內(nèi)容替換了

vue項目中使用骨架屏的方法

vue項目中使用骨架屏的方法

方案二、直接在模板文件id=app容器下面,用圖片展示(這個就不做展示了)方案三、使用vue ssr提供的webpack插件:即用.vue文件完成骨架屏

在方案一的基礎(chǔ)上,將骨架屏的代碼抽離出來,不在模版文件里面書寫代碼,而是在vue文件里面書寫效果代碼,這樣便于維護

1、在根目錄下建一個skeleton文件夾,在該目錄下創(chuàng)建文件App.vue文件(根組件,類似Vue項目的App.vue)、home.skeleton.vue(首頁骨架屏展示效果的代碼,類似Vue項目寫的路由頁面)、skeleton-entry.js(入口文件類似Vue項目的入口文件)、plugin/server-plugin.js(vue-server-renderer包提供了server-plugin插件,從里面將代碼拷貝出來)

vue項目中使用骨架屏的方法

home.skeleton.vue(首頁骨架屏展示效果的代碼)

<template> <div class='skeleton-home'> <div>加載中...</div> </div></template> <style>.skeleton-home { width: 100vw; height: 100vh; background-color: #eaeaea;}</style>

App.vue(根組件)

<template> <div id='app'> <!-- 根組件 --> <home id='homeSkeleton'></home> </div></template><script>import home from ’./home.skeleton.vue’export default{ components: { home }}</script><style>#app { font-family: ’Avenir’, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50;}*{ padding: 0; margin: 0;}</style>

skeleton-entry.js(入口文件)

// 入口文件import Vue from ’vue’import App from ’./App.vue’let skeleton = new Vue({ render(h) { return h(App) }})export default skeleton

plugin/server-plugin.js(vue-server-renderer包提供了server-plugin插件)

’use strict’; /* */ var isJS = function (file) { return /.js(?[^.]+)?$/.test(file); }; var ref = require(’chalk’);var red = ref.red;var yellow = ref.yellow; var prefix = '[vue-server-renderer-webpack-plugin]';var warn = exports.warn = function (msg) { return console.error(red((prefix + ' ' + msg + 'n'))); };var tip = exports.tip = function (msg) { return console.log(yellow((prefix + ' ' + msg + 'n'))); }; var validate = function (compiler) { if (compiler.options.target !== ’node’) { warn(’webpack config `target` should be 'node'.’); } if (compiler.options.output && compiler.options.output.libraryTarget !== ’commonjs2’) { warn(’webpack config `output.libraryTarget` should be 'commonjs2'.’); } if (!compiler.options.externals) { tip( ’It is recommended to externalize dependencies in the server build for ’ + ’better build performance.’ ); }}; var VueSSRServerPlugin = function VueSSRServerPlugin (options) { if ( options === void 0 ) options = {}; this.options = Object.assign({ filename: ’vue-ssr-server-bundle.json’ }, options);}; VueSSRServerPlugin.prototype.apply = function apply (compiler) { var this$1 = this; validate(compiler); compiler.plugin(’emit’, function (compilation, cb) { var stats = compilation.getStats().toJson(); var entryName = Object.keys(stats.entrypoints)[0]; var entryAssets = stats.entrypoints[entryName].assets.filter(isJS); if (entryAssets.length > 1) { throw new Error('Server-side bundle should have one single entry file. ' +'Avoid using CommonsChunkPlugin in the server config.' ) } var entry = entryAssets[0]; if (!entry || typeof entry !== ’string’) { throw new Error(('Entry '' + entryName + '' not found. Did you specify the correct entry option?') ) } var bundle = { entry: entry, files: {}, maps: {} }; stats.assets.forEach(function (asset) { if (asset.name.match(/.js$/)) {bundle.files[asset.name] = compilation.assets[asset.name].source(); } else if (asset.name.match(/.js.map$/)) {bundle.maps[asset.name.replace(/.map$/, ’’)] = JSON.parse(compilation.assets[asset.name].source()); } // do not emit anything else for server delete compilation.assets[asset.name]; }); var json = JSON.stringify(bundle, null, 2); var filename = this$1.options.filename; compilation.assets[filename] = { source: function () { return json; }, size: function () { return json.length; } }; cb(); });}; module.exports = VueSSRServerPlugin;

2、新建一個骨架屏構(gòu)建配置文件:build/webpack.skeleton.conf.js,這個文件配合vue-server-renderer插件,將App.vue內(nèi)容構(gòu)建成單個json格式的文件

’use strict’ const path = require(’path’)const nodeExternals = require(’webpack-node-externals’)const VueSSRServerPlugin = require(’../skeleton/plugin/server-plugin’) module.exports = { // 這允許 webpack 以 Node 適用方式(Node-appropriate fashion)處理動態(tài)導(dǎo)入(dynamic import), // 并且還會在編譯 Vue 組件時, // 告知 `vue-loader` 輸送面向服務(wù)器代碼(server-oriented code)。 target: ’node’, // 對 bundle renderer 提供 source map 支持 devtool: ’source-map’, // 將 entry 指向應(yīng)用程序的 server entry 文件 entry: path.resolve(__dirname, ’../skeleton/skeleton-entry.js’), output: { path: path.resolve(__dirname, ’../skeleton’), // 生成的文件的目錄 publicPath: ’/skeleton/’, filename: ’[name].js’, libraryTarget: ’commonjs2’ // 此處告知 server bundle 使用 Node 風格導(dǎo)出模塊(Node-style exports) }, module: { rules: [ {test: /.vue$/,loader: ’vue-loader’,options: { compilerOptions: { preserveWhitespace: false }} }, {test: /.css$/,use: [’vue-style-loader’, ’css-loader’] } ] }, performance: { hints: false }, // https://webpack.js.org/configuration/externals/#function // https://github.com/liady/webpack-node-externals // 外置化應(yīng)用程序依賴模塊??梢允狗?wù)器構(gòu)建速度更快, // 并生成較小的 bundle 文件。 externals: nodeExternals({ // 不要外置化 webpack 需要處理的依賴模塊。 // 你可以在這里添加更多的文件類型。例如,未處理 *.vue 原始文件, // 你還應(yīng)該將修改 `global`(例如 polyfill)的依賴模塊列入白名單 allowlist: /.css$/ }), // 這是將服務(wù)器的整個輸出 // 構(gòu)建為單個 JSON 文件的插件。 // 不配置filename,則默認文件名為 `vue-ssr-server-bundle.json` plugins: [ new VueSSRServerPlugin({ filename: ’skeleton.json’ }) ]}

3、使用webpack-cli運行文件webpack.skeleton.conf.js,生成skeleton.json文件,放置在文件夾skeleton下

在package.json文件里面書寫運行命令:create-skeleton

'scripts': { 'create-skeleton': 'webpack --progress --config build/webpack.skeleton.conf.js', 'fill-skeleton': 'node ./skeleton/skeleton.js' }

在控制臺上運行命令:

npm run create-skeleton

文件夾skeleton下就會多出skelleton.json文件

vue項目中使用骨架屏的方法

4、將生成的skeleton.json內(nèi)容注入到根目錄下的index.html(模版文件)

1)在文件夾skeleton下新建skeleton.js

// 將生成的skeleton.json的內(nèi)容填充到模板文件中const fs = require(’fs’)const { resolve } = require(’path’)const createBundleRenderer = require(’vue-server-renderer’).createBundleRenderer // 讀取skeleton.json,以skeleton/index.html為模版寫入內(nèi)容const renderer = createBundleRenderer(resolve(__dirname, ’../skeleton/skeleton.json’), { template: fs.readFileSync(resolve(__dirname, ’../skeleton/index.html’), ’utf-8’)})// 把上一步模版完成的內(nèi)容寫入根目錄下的模版文件’index.html’renderer.renderToString({}, (err, html) => { if (err) { return console.log(err) } console.log(’render complete!’) fs.writeFileSync(’index.html’, html, ’utf-8’)})

2)添加運行命令:fill-skeleton

'fill-skeleton': 'node ./skeleton/skeleton.js'

3)在控制臺上運行該命令,則skeleton.json文件內(nèi)容被填充至根目錄下的模板文件index.html了

參考文章:

利用Vue SSR 做骨架屏注入:https://www.cnblogs.com/goloving/p/11397371.html

在Vue中實現(xiàn)骨架屏:http://www.360doc.com/content/20/0709/11/21412_923150401.shtml

Vue ssr渲染踩過的坑:https://blog.csdn.net/chen801090/article/details/105974987/

到此這篇關(guān)于vue項目中使用骨架屏的方法的文章就介紹到這了,更多相關(guān)vue 骨架屏內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Vue
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
午夜精品一区二区三区国产| 精品视频99| 快she精品国产999| 日韩国产欧美在线播放| 国产精品xxx| 四虎4545www国产精品 | 欧美亚洲tv| 国产精品一区三区在线观看| 日韩电影免费网站| 麻豆亚洲精品| 欧美a一区二区| 黄色av一区| 久久av影视| 妖精视频成人观看www| 国产精品亚洲人成在99www| 久久精品在线| 欧美日韩一区二区三区不卡视频| 欧美片第1页| 日韩中文字幕| 精品日韩视频| 91成人精品观看| 91精品韩国| 亚洲人www| 色一区二区三区| 日韩精选在线| 亚洲天堂成人| 国产极品模特精品一二| 中文在线不卡| 福利视频一区| 亚洲精品少妇| 99国产精品免费视频观看| 91福利精品在线观看| 欧美亚洲激情| 欧美激情福利| 久久亚洲国产精品一区二区| 国产精品久久久久久久免费观看| 深夜福利一区| 成人久久一区| 国产精品久久久久9999高清| 亚洲精品va| 欧美国产美女| 国产日韩一区二区三区在线| 国产韩日影视精品| 成人污污视频| 日韩高清不卡一区二区| 好看的av在线不卡观看| 欧美xxxx中国| 国产精品亚洲一区二区在线观看| 久久亚洲电影| 99久久亚洲精品| 精品日韩一区| 欧美久久一区二区三区| 国产亚洲毛片| 欧美日韩一二三四| 好看的亚洲午夜视频在线| 成人精品天堂一区二区三区| 国产亚洲久久| 99在线观看免费视频精品观看| 久久一区视频| 亚洲欧美网站在线观看| 韩国精品主播一区二区在线观看| 91精品一区| 欧美日韩国产亚洲一区| 久久久久伊人| 日本久久一区| 亚洲黄页一区| 国产一区二区三区四区五区| 亚洲一区二区免费看| 国产精品精品| 国产精品综合色区在线观看| 天堂va蜜桃一区二区三区| 中文字幕高清在线播放| 欧美一区成人| 中文一区一区三区免费在线观 | 国产九一精品| 视频在线在亚洲| 五月激情久久| 美女在线视频一区| 亚洲精品乱码| 国产综合欧美| 久久影院资源站| 日韩视频一二区| 香蕉国产精品| 日韩精品欧美| 国产一区三区在线播放| 日本色综合中文字幕| 99视频在线精品国自产拍免费观看| 欧美激情国产在线| 国产精品最新自拍| 日韩一区精品视频| 91精品综合| 97精品国产一区二区三区 | 国产欧美日韩综合一区在线播放| 亚洲夜间福利| 国产一区二区三区日韩精品| 欧美综合精品| 久久国产精品亚洲77777| 婷婷综合六月| 福利一区二区| 精品三级在线观看视频| 国产视频一区二| 青青草视频一区| 亚洲免费福利一区| 香蕉久久国产| 国产亚洲精品v| 亚洲一区二区毛片| 亚洲作爱视频| 国产美女精品| 欧美日韩国产免费观看视频| 黄色在线观看www| 久久精品网址| 精品视频自拍| 精品三级久久久| 九九九精品视频| 国产精品1区| 麻豆一区二区三| 久久精品国产成人一区二区三区| 欧美国产专区| 久久wwww| 超碰99在线| 亚洲伊人av| 99精品小视频| 一区在线免费| 国产亚洲网站| 在线免费观看亚洲| 日韩精品a在线观看91| 欧美一区91| 久久三级毛片| 久久人人97超碰国产公开结果| 国产91精品对白在线播放| 亚洲国产日韩欧美在线| 亚洲女人av| 日韩高清不卡在线| 久久中文字幕导航| 韩国三级一区| 香蕉成人久久| 日韩黄色av| 国产精品一区三区在线观看| 久久精品国产福利| 久久精品国产福利| 久久久天天操| 亚洲一区观看| 青青草91视频| 国产精品久久久久久久久妇女| 91精品啪在线观看国产18| 欧美特黄视频| 日韩av不卡在线观看| 精品国产亚洲一区二区三区在线| 日韩欧美午夜| 国产模特精品视频久久久久| 亚洲aa在线| 久久麻豆视频| 日本精品影院| 久久九九99| av高清不卡| 日韩精品1区2区3区| 日韩精品一区二区三区免费观看| 日本伊人久久| 日本一二区不卡| 免费观看日韩电影| 成人一区而且| 日韩极品在线观看| 激情婷婷久久| 国产精品a级| 免费日本视频一区| 日韩国产欧美| 91精品一区| 亚洲精品1区| 久久一区视频| 蜜桃av一区二区三区电影| 免费看av不卡| 国产亚洲精品精品国产亚洲综合| 婷婷亚洲综合| 国产在线一区不卡| 日韩毛片网站| 狠狠久久婷婷| 成人片免费看| 国产日韩欧美一区二区三区在线观看 | 精品久久精品| 日韩欧美四区| 国产麻豆精品久久| 黄色亚洲免费| 精品久久久中文字幕| 丝袜亚洲另类欧美| 日产精品一区二区| 中文字幕av一区二区三区人| 国产一区二区三区视频在线| 综合激情五月婷婷| 国产黄大片在线观看| 亚洲精品动态| 国产在线不卡| 精品少妇av| 日韩二区三区四区| 国产韩日影视精品| 激情久久99| 久久精品国产999大香线蕉| 欧美亚洲三级| 日韩高清不卡在线| 蜜桃久久久久久久| 国产精品社区|