Skip to content
On this page

nuxt

vue 的预渲染插件

vue 的预渲染插件

bash
npm install prerender-spa-plugin
1

缺陷数据不够动态,可以使用 ssr 服务端渲染

js
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const path = require('path');
module.exports = {
    configureWebpack: {
        plugins: [
            new PrerenderSPAPlugin({
                staticDir: path.join(__dirname, 'dist'),
                routes: [ '/', '/about',],
            })
        ]
    }
  }
1
2
3
4
5
6
7
8
9
10
11
12

app-skeleton

配置 webpack 插件 vue-skeleton-webpack-plugin 单页骨架屏幕

js
import Vue from 'vue';
import Skeleton from './Skeleton.vue';
export default new Vue({
    components: {
        Skeleton:Skeleton
    },
    template: `
        <Skeleton></Skeleton>
    `
});
// 骨架屏
plugins: [
    new SkeletonWebpackPlugin({
        webpackConfig: {
            entry: {
                app: resolve('./src/entry-skeleton.js')
            }
        }
    })
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

带路由的骨架屏,编写 skeleton.js 文件

js
import Vue from 'vue';
import Skeleton1 from './Skeleton1';
import Skeleton2 from './Skeleton2';

export default new Vue({
    components: {
        Skeleton1,
        Skeleton2
    },
    template: `
        <div>
            <skeleton1 id="skeleton1" style="display:none"/>
            <skeleton2 id="skeleton2" style="display:none"/>
        </div>
    `
});
new SkeletonWebpackPlugin({
    webpackConfig: {
        entry: {
            app: path.join(__dirname, './src/skeleton.js'),
        },
    },
    router: {
        mode: 'history',
        routes: [
            {
                path: '/',
                skeletonId: 'skeleton1'
            },
            {
                path: '/about',
                skeletonId: 'skeleton2'
            },
        ]
    },
    minimize: true,
    quiet: true,
})
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
33
34
35
36
37
38

优化白屏效果

实现骨架屏插件

js
class MyPlugin {
    apply(compiler) {
        compiler.plugin('compilation', (compilation) => {
            compilation.plugin(
                'html-webpack-plugin-before-html-processing',
                (data) => {
                    data.html = data.html.replace(`<div id="app"></div>`, `
                        <div id="app">
                            <div id="home" style="display:none">首页 骨架屏</div>
                            <div id="about" style="display:none">about页面骨架屏</div>
                        </div>
                        <script>
                            if(window.hash == '#/about' ||  location.pathname=='/about'){
                                document.getElementById('about').style.display="block"
                            }else{
                                document.getElementById('home').style.display="block"
                            }
                        </script>
                    `);
                    return data;
                }
            )
        });
    }
}
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

什么是服务端渲染?

概念:放在浏览器进行就是浏览器渲染,放在服务器进行就是服务器渲染。

客户端渲染不利于 SEO 搜索引擎优化 服务端渲染是可以被爬虫抓取到的,客户端异步渲染是很难被爬虫抓取到的 SSR 直接将 HTML 字符串传递给浏览器。大大加快了首屏加载时间。 SSR 占用更多的 CPU 和内存资源 一些常用的浏览器 API 可能无法正常使用 在 vue 中只支持 beforeCreate 和 created 两个生命周期

什么是 nuxt

Nuxt.js 是使用 Webpack 和 Node.js 进行封装的基于 Vue 的 SSR 框架

nuxt 特点

优点: 更好的 SEO,由于搜索引擎爬虫抓取工具可以直接查看完全渲染的页面。首屏渲染速度快

缺点: Node.js 中渲染完整的应用程序,显然会比仅仅提供静态文件的 server 更加大量占用 CPU 资源。需要考虑服务器负载,缓存策略

项目生成

bash
npx create-nuxt-app nuxt-project
cd nuxt-project
yarn dev
1
2
3

项目目录

  • assets 静态资源 会被 webpack 处理
  • static 不会被 webpack 处理
  • components 公共组件
  • layout 布局组件
  • pages 路由页面 可以生成对应的路由
  • middleware 运行过程中发生的事
  • store 存放 vuex
  • plugins 存放 javascript 插件的
  • nuxt.config.js 存放 nuxt 配置文件
  • 别名默认可以采用 ~ 或者 @符号

nuxt.config.js 配置

env 可以配置环境变量通过 cross-env

js
env:{
    baseUrl:process.env.BASE_URL
}
1
2
3
  • cache:false // 提升组件缓存策略

  • css 全局 css 样式

  • head 配置头

  • loading (需要等待 $loading 挂载完成)

js
loading: { color: '#000',height:'10px' }
mounted(){
    this.$nextTick(()=>{
        this.$nuxt.$loading.start()
    });
}
1
2
3
4
5
6
  • modules 存放第三方模块 @nuxtjs/axios 第三方模块

  • plugins 配置插件

  • transition 动画效果

js
    config.js
    transition: {
        name: 'layout',
        mode: 'out-in'
    },
    .layout-enter-active, .layout-leave-active {
        transition: opacity .5s
    }
    .layout-enter, .layout-leave-active {
        opacity: 0
    }
1
2
3
4
5
6
7
8
9
10
11

使用 history.pushState 跳转页面,不会触发页面整体重新渲染

  • 路径参数
html
   <nuxt-link to="/user/4/5">路径参数</nuxt-link>
1
  • 查询字符串
  • validate 方法 必须返回是否访问这个页面,返回 false 执行 404 逻辑
js
export default {
    validate({params}){
        return params.id != 4;
    }
}
1
2
3
4
5
  • 动画效果
css
.page-enter-active, .page-leave-active {
    transition: opacity .5s;
}
.page-enter, .page-leave-active {
    opacity: 0;
}
1
2
3
4
5
6

中间件

如果经过服务端则在服务端执行

  • 全局中间件
  • layout 在 layout 中增加 middleware
  • 组件中间件 在组件中增加 middleware
js
export default function ({ store, redirect }) {
  if (!store.state.user) {
    return redirect('/login')
  }
}
router: {
    middleware: 'auth'
}
1
2
3
4
5
6
7
8

layout 配置

自定义 error 页面 增加 error.vue(配置错误 layout) 自定义 layout 布局 增加错误页面,错误页需要配置 layout

export default { props:['error'], layout:'page' }

数据获取

js
asyncData 使用(仅在页面组件中使用)
async asyncData ({ params }) { // 无 this
    let { data } = await axios.get();
    return { title: data }
}
1
2
3
4
5

插件的使用

扩展原型上的方法 plugins

js
export default function({app},inject){
    inject('my',()=>{ // 在 app 上和 this 都注册这个方法
        console.log('my');
    })
}
1
2
3
4
5

运行流程

  • nextServerinit 只在主模块中使用
  • nuxt.config.js 全局中间件
  • matching layout 不同布局的中间件
  • matching page & children 页面中间件
  • validate 返回 false 显示错误页面
  • asyncData 服务端渲染的页面数据请求
  • fetch 同步 vuex 数据
沪ICP备20006251号-1