Appearance
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
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
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
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
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
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
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
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
2
3
4
5
6
7
8
9
10
11
nuxt-link
使用 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
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
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
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
2
3
4
5
插件的使用
扩展原型上的方法 plugins
js
export default function({app},inject){
inject('my',()=>{ // 在 app 上和 this 都注册这个方法
console.log('my');
})
}
1
2
3
4
5
2
3
4
5
运行流程
- nextServerinit 只在主模块中使用
- nuxt.config.js 全局中间件
- matching layout 不同布局的中间件
- matching page & children 页面中间件
- validate 返回 false 显示错误页面
- asyncData 服务端渲染的页面数据请求
- fetch 同步 vuex 数据