Rumah > hujung hadapan web > tutorial js > 在Vue中有关如何实现单页面骨架屏

在Vue中有关如何实现单页面骨架屏

亚连
Lepaskan: 2018-06-20 18:09:06
asal
2875 orang telah melayarinya

这篇文章主要给大家介绍了关于Vue单页面骨架屏实践的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起看看吧。

关于骨架屏介绍

骨架屏的作用主要是在网络请求较慢时,提供基础占位,当数据加载完成,恢复数据展示。这样给用户一种很自然的过渡,不会造成页面长时间白屏或者闪烁等情况。 常见的骨架屏实现方案有ssr服务端渲染和prerender两种解决方案。

这里主要通过代码为大家展示如何一步步做出这样一个骨架屏:

prerender 渲染骨架屏

本组件库骨架屏的实现也是基于预渲染去实现的,有关于预渲染更详细的介绍请参考这篇文章:处理 Vue 单页面 Meta SEO的另一种思路 下面我们主要介绍其实现步骤,首先我们也是需要配置webpack-plugin,不过已经有实现好的prerender-spa-plugin可用

1

2

3

4

5

6

7

8

9

10

11

12

13

var path = require('path')

var PrerenderSpaPlugin = require('prerender-spa-plugin')

module.exports = {

 // ...

 plugins: [

 new PrerenderSpaPlugin(

 // Absolute path to compiled SPA

 path.join(__dirname, '../dist'),

 // List of routes to prerender

 ['/']

 )

 ]

}

Salin selepas log masuk

然后写好我们的骨架屏文件main.skeleton.vue

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<template>

 <p class="main-skeleton">

 <w-skeleton height="80px"></w-skeleton>

 <p>

 <p class="skeleton-container">

 <p class="skeleton">

  <w-skeleton height="300px"></w-skeleton>

 </p>

 <w-skeleton height="45px"></w-skeleton>

 </p>

 <p class="skeleton-bottom">

 <w-skeleton height="45px"></w-skeleton>

 </p>

 </p>

 </p>

</template>

Salin selepas log masuk

当初次进入页面的时候我们需要显示骨架屏,数据加载完,我们需要移除骨架屏:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

<template>

 <p id="app">

 <mainSkeleton v-if="!init"></mainSkeleton>

 <p v-else>

 <p class="body"></p>

 </p>

 </p>

</template>

<script>

 import mainSkeleton from &#39;./main.skeleton.vue&#39;

 export default {

 name: &#39;app&#39;,

 data () {

 return {

 init: false

 }

 },

 mounted () {

 // 这里模拟数据请求

 setTimeout(() => {

 this.init = true

 }, 250)

 },

 components: {

 mainSkeleton

 }

 }

</script>

Salin selepas log masuk

ssr 渲染骨架屏

下面我用我灵魂画师的笔法,画出了大致的过程:

首先创建我们的skeleton.entry.js

1

2

3

4

5

6

7

8

import Vue from &#39;vue&#39;;

import Skeleton from &#39;./skeleton.vue&#39;;

export default new Vue({

 components: {

 Skeleton

 },

 template: &#39;<skeleton />&#39;

});

Salin selepas log masuk

当然这里的skeleton.vue使我们事先写好的骨架屏组件,看起来可能是这样:

1

2

3

4

5

6

<template>

 <p class="skeleton-wrapper">

 <header class="skeleton-header"></header>

 <p class="skeleton-block"></p>

 </p>

</template>

Salin selepas log masuk

然后我们需要的是能把skeleton.entry.js编译成服务端渲染可用的bundle文件,所以我们需要有个编译骨架屏的webpack.ssr.conf.js文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

const path = require(&#39;path&#39;);

const merge = require(&#39;webpack-merge&#39;);

const baseWebpackConfig = require(&#39;./webpack.base.conf&#39;);

const nodeExternals = require(&#39;webpack-node-externals&#39;);

function resolve(dir) {

 return path.join(__dirname, dir);

}

module.exports = merge(baseWebpackConfig, {

 target: &#39;node&#39;,

 devtool: false,

 entry: {

 app: resolve(&#39;./src/skeleton.entry.js&#39;)

 },

 output: Object.assign({}, baseWebpackConfig.output, {

 libraryTarget: &#39;commonjs2&#39;

 }),

 externals: nodeExternals({

 whitelist: /\.css$/

 }),

 plugins: []

});

Salin selepas log masuk

接下来最终的步骤,就是编写我们的webpackPlugin,我们期望我们的webpackPlugin可以帮我们把入口文件编译成bundle,然后再通过vue-server-renderer来render bundle,最终产出响应的html片段和css片段,这里贴出核心代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

// webpack start to work

var serverCompiler = webpack(serverWebpackConfig);

var mfs = new MFS();

// output to mfs

serverCompiler.outputFileSystem = mfs;

serverCompiler.watch({}, function (err, stats) {

 

if (err) {

 reject(err);

 return;

}

stats = stats.toJson();

stats.errors.forEach(function (err) {

 console.error(err);

});

stats.warnings.forEach(function (err) {

 console.warn(err);

});

var bundle = mfs.readFileSync(outputPath, &#39;utf-8&#39;);

var skeletonCss = mfs.readFileSync(outputCssPath, &#39;utf-8&#39;);

// create renderer with bundle

var renderer = createBundleRenderer(bundle);

// use vue ssr to render skeleton

renderer.renderToString({}, function (err, skeletonHtml) {

 if (err) {

 reject(err);

 }

 else {

 resolve({skeletonHtml: skeletonHtml, skeletonCss: skeletonCss});

 }

});

});

Salin selepas log masuk

最后一步,我们对产出的html片段, css片段进行组装,产出最终的html,所以我们需要监听webpack 的编译挂载之前的事件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

compiler.plugin(&#39;compilation&#39;, function (compilation) {

 // add listener for html-webpack-plugin

 compilation.plugin(&#39;html-webpack-plugin-before-html-processing&#39;, function (htmlPluginData, callback) {

 ssr(webpackConfig).then(function (ref) {

  var skeletonHtml = ref.skeletonHtml;

  var skeletonCss = ref.skeletonCss;

  // insert inlined styles into html

  var headTagEndPos = htmlPluginData.html.lastIndexOf(&#39;</head>&#39;);

  htmlPluginData.html = insertAt(htmlPluginData.html, ("<style>" + skeletonCss + "</style>"), headTagEndPos);

 

  // replace mounted point with ssr result in html

  var appPos = htmlPluginData.html.lastIndexOf(insertAfter) + insertAfter.length;

  htmlPluginData.html = insertAt(htmlPluginData.html, skeletonHtml, appPos);

  callback(null, htmlPluginData);

 });

 });

 });

Salin selepas log masuk

github 地址: VV-UI/VV-UI

演示地址: vv-ui

文档地址:skeleton

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

详细解答Webpack+Babel+React环境搭建(详细教程)

详细介绍webpack中scss的相关配置

在Vue中项目组件化开发(详细教程)

如何实现webpack多入口文件打包配置

在JavaScript中如何实现多重继承

Atas ialah kandungan terperinci 在Vue中有关如何实现单页面骨架屏. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan