Vue页面骨架屏_vue横竖屏怎么切换

Vue页面骨架屏_vue横竖屏怎么切换在开发webapp的时候总是会受到首屏加载时间过长的影响,主流的解决方法是在载入完成之前显示loading图效果,而一些大公司会配置一套服务端渲染的架构来解决这个问题。考虑到ssr所要解决的一系列问题,越来越多的APP采用了“骨架屏”的方式去提升用户体验。

在开发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>

Vue页面骨架屏_vue横竖屏怎么切换
由此可知,将骨架屏内容直接插入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.js
import Vue from 'vue'
import Skeleton from './views/skeleton/skeleton.vue'

export default new Vue({
  components: {
    Skeleton
  },
  template: '<skeleton />'
})
//webpack.config.server.js
const 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.js
const 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,欢迎查阅~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13253.html

(0)

相关推荐

  • 如何用 Python 读取 CSV 文件?

    CSV 文件代表逗号分隔的值文件。这是一种纯文本文件,其中的信息以表格形式组织。它只能包含实际的文本数据。文本数据不需要用逗号(,)分隔。还有许多分隔符,如制表符(\t)、冒号(:)和分号(;),可用作分隔符。让我们理解下面的例子。

    2023-08-24
    143
  • Jupyter安装方法

    Jupyter安装方法Jupyter是一款支持多种编程语言的交互式计算环境,可以帮助用户轻松地将代码、文本、图像、视频等多种形式的内容融合在一起,进行数据分析和数据可视化。

    2024-05-11
    78
  • redis订阅和发布_redis 发布订阅

    redis订阅和发布_redis 发布订阅发布与订阅。

    2023-03-16
    144
  • Ubuntu 16.04 安装 CUDA、CUDNN 和 GPU 版本的 TensorFlow 一般步骤总结[亲测有效]

    Ubuntu 16.04 安装 CUDA、CUDNN 和 GPU 版本的 TensorFlow 一般步骤总结[亲测有效]1. 安装显卡驱动 安装显卡驱动网上有各种各样的方法,甚至有的还需要更改一些配置文件切换到命令行终端模式进行操作,然而就我多次安装驱动的经验来看,我从来没有这么费劲过。在 Ubuntu 系统中的 System Settings -> Software & Updates -> …

    2023-08-06
    123
  • Python的非数字类型的应用

    Python的非数字类型的应用字符串是Python中最常用的非数字类型之一。Python字符串是一串字符序列,可以通过引号引用。以下是Python字符串的一些常见操作:

    2024-04-07
    83
  • Python分割字符串实现

    Python分割字符串实现在Python编程中经常遇到需要将一个字符串分成多个部分来进行操作的情况。这个时候,我们就需要使用字符串分割操作。Python为我们提供了多种分割字符串的方法,我们可以根据具体的需求来选择使用哪种方法。

    2024-06-14
    50
  • Python工程师必知:super()__init__()用法

    Python工程师必知:super()__init__()用法在Python面向对象编程中,我们经常需要调用父类的构造函数,而调用父类构造函数的一种常用方法是使用super()函数,其搭配的关键字是__init__()函数。

    2024-05-11
    82
  • 记mysql中delete操作中使用in不会走索引的问题[通俗易懂]

    记mysql中delete操作中使用in不会走索引的问题[通俗易懂]目前负责的一个项目,需要维护一个电话号码对比库,表名为phone_bak1,以下称为a表,量级为3000万条。还有另外一张表存储电话白名单,表名为phone_delete,以下称为b表,量级为3000

    2023-02-05
    153

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注