当前位置:首页 > 博客 >vue > 正文

vue的服务端渲染方案nuxt初次探坑

时间:2019-01-08 20:52   作者:admin   点击:

首先官网有两种解决方案:

一种是ssr

一种是nuxt

因为我自己去看文档的时候,觉得可能nuxt更符合一些,感觉也更友好一些,所以以下都是nuxt相关的内容

1.先看下nuxt的生命周期:

5531211-d1a3e5b36ee03f08.webp.jpg


这其中需要注意的是,服务端渲染那部分,你是找不到window变量的哟,以及一些其他浏览器的操作


2.如何自定义错误页面

  • 可以添加layouts/error.vue页面,默认会跳转到这个页面,可以接受参数的

  • 自定义配置路由,依据找不到路由就默认跳转到最后一个路由的思路,最后添加一个(nuxt.config.js文件)

router: {
    extendRoutes(routes) {
      routes.push({
        name: 'custom',
        path: '*',
        component: resolve(__dirname, 'pages/404.vue')
      })
   }


3.nuxtserverinit方法会去修改store,需要注意的是,修改了值虽然能获取到,但是用工具(vue-tool)查看的话 ,可能看不到,但是不影响使用

4.如何压缩css等外部资源?

我查看了源代码,发现css都没有压缩,很不舒服,后面发现,打包后的css他会压缩的

5.async默认返回的就是一个promise, awiat 后面必须是promise,如果不是,他会自己转换,并且马上执行

6.写的时候,总是报虚拟dom和实际dom不匹配这个警告,虽然不影响功能,但是看着不友好。如何解决呢?

利用自带的组件(no-rss)

7.在ie9上会报错,导致页面无法正常操作?

if (process.client) {
window.history.replaceState = window.history.replaceState || function () {}
}

8.asyncData它的返回必须是一个promise对象

9.开发环境下总是报Loading chunk {n} failed(可以不处理,只是dev环境才会有问题)

找了很多资料,有两种方案,一种是服务端拦截错误,一种是客户端拦截错误,造成的原因,我感觉是因为修改了代码,webpack打包更新,之前的那个chunk找不到,造成的?但是这也是一种猜测。没实际方案解决,只能选择去拦截这种错误,因为他一但出现,就会页面假死

服务端:github原地址

app.all(/\.js$/, (req, res) => {    const fileName = req.path.slice(req.path.lastIndexOf('/') + 1);    const filePath = path.resolve(__dirname, './public/static/js/' + fileName);    if (fs.existsSync(filePath)) {
        fs.sendFile(filePath);
    } else {
        res.setHeader('Content-Type', 'application/javascript; charset=UTF-8')
        res.setHeader('Accept-Ranges', 'bytes')
        res.setHeader('Vary', 'Accept-Encoding')
        res.setHeader('Transfer-Encoding', 'chunked')
        res.setHeader('Last-Modified', new Date().toUTCString())
        res.setHeader('Cache-Control', 'no-cache')
        res.send('window.serverRebuildHook && window.serverRebuildHook();')
    }
});
接着我们在前端实现serverRebuildHook方法:
window.serverRebuildHook = function () {
  alert('服务器版本已更新,正在刷新本地缓存,请稍后...');
  location.replace(location.href);
}

客户端:监听错误路由

router.onError((error) => {  const pattern = /Loading chunk (\d)+ failed/g;  const isChunkLoadFailed = error.message.match(pattern);  const targetPath = router.history.pending.fullPath;  if (isChunkLoadFailed) {
    router.replace(targetPath);
  }
});

10.如何自定义server error界面?

我之前一直想修改后台接口错误时,会报错一个页面,但是我发现那个页面模板是在项目打包时候生成的,外面也没有这个文件定义的位置。后面想去github上提问,才发现不止我一个人有这样的需求(英语差很他妈恼火),搞不懂为啥官网没有这个说明

再项目根目录下建立/app/views/error.html文件,他会自动将这个当模板导入