使用nuxtjs实现vue项目的同构渲染(客户端渲染+服务器端渲染)

1,505 阅读7分钟

使用nuxt.js 可以解决vue项目中的SEO优化+首屏加载时间长出现白屏的问题

实际开发中,简单项目使用nuxtjs默认的路由规则就可以

但是在复杂的项目内,用nuxtjs默认的路由规则反而会变得十分麻烦,因此在复杂的项目内,通常通过手动配置nuxtjs的路由规则来实现

手动配置nuxtjs的路由规则:

1、在项目的根目录下(和package.json同一级目录下)新建一个文件,文件名叫:nuxt.config.js

2、在nuxt.config.js文件写输入如下代码:

export default {

  plugins: ['~/plugins/formatDate.js', '~/plugins/apiConfig.js'], // 在nuxt.js中添加插件的方法
  
   // 把项目部署到服务器的时候,进行的配置
  server: {
    host: '0.0.0.0',
    port: 3000,
  },
  
  router: {
  	linkExactActiveClass: 'active', // <nuxt-link>标签默认 active class(类名)严格模式
    // 自定义nuxtjs的路由规则
    extendRoutes(routes, resolve) {
      // 清除 Nuxt.js 基于 pages 目录默认生成的路由表规则
      // 把nuxtjs中默认的路由规则全部删除不要了
      routes.splice(0)
      // 添加自己配置的路由规则给nuxtjs来使用,结构和vue原始的路由结构一样
      routes.push(
        ...[
          {
            path: '/',
            component: resolve(__dirname, 'pages/layout/'), // nuxtjs中的页面组件
            children: [
              {
                path: '', // 默认子路由
                name: 'home',
                component: resolve(__dirname, 'pages/home/'), // nuxtjs中被页面组件,包裹的子组件(路由组件)
              },
            ],
          },
        ]
      ) 
    },
  },
}

nuxtjs中监视地址栏的中变化,一但变化,nuxtjs中自带的asyncData方法就会调用

在vue文件中添加watchQuery:[],和vue的生命周期同级

watchQuery: ['tab', 'tag', 'page'],  // 重点在这里
mounted() {}, // 生命周期 - 挂载之后

nuxtjs中中间件的使用

在项目的根目录下新建文件夹:middleware

文件夹middleware里面的js文件就是中间件,在对应的页面加载的时候自动执行的

例如新建一个文件authenticated.js,代码如下:

// 验证是否登录的中间件==>已经登录了
// 如果登录,让其跳转到首页
// 解决用户直接手动修改路由的url造成的问题:用户已经登录,手动修改地址栏的url后,还可以跳转到登录页的问题

export default function({ store, redirect }) {
  // If the user is not authenticated
  if (store.state.users) {
    return redirect('/')
  }
}

接下来在对应的login.vue页面内添加如下代码:

middleware: 'authenticated', // 用户已经登录了,使用nuxtjs,跳转到首页【主要代码在这里】
mounted() {},

这样一来在地址栏输入登录的url就是自动进行判断,如果用户已经登录了,使用nuxtjs,跳转到首页

nuxtjs中插件的使用

在项目的根目录下新建文件夹:plugins

nuxtjs中插件是在创建 Vue 实例之前调用的

例如可以穿件格式化项目中的所有日期的插件

在plugins文件夹内新建文件:formatDate.js,代码如下:

// 格式化项目中的所有日期的插件

import Vue from 'vue'
import dayjs from 'dayjs'

// 在创建 Vue 实例之前全局定义过滤器
Vue.filter('formatDate', function(value, format = 'YYYY-MM-DD HH:mm:ss') {
  return dayjs(value).format(format) 
})

接下来在对应的vue文件内,有日期数据的位置写下如下代码即可:

{{article.createdAt | formatDate('MMMM DD,YYYY') }} 

最后还需要在nuxt.config.js文件内进行配置才可以,代码如下:

export default {
   plugins: ['~/plugins/formatDate.js', '~/plugins/apiConfig.js'], // 在nuxt.js中添加插件的方法
}

这样一来,插件就会在创建 Vue 实例之前自动调用了

nuxtjs项目在服务器端发布部署->最简单的部署项目的方式

  • (1) 配置host+port (在nuxt.vonfig.js文件中配置)
server: {
      host: '0.0.0.0',
      port:3000
},
  • (2) 压缩发布包,把打包后的项目的一些文件进行压缩,文件包括:

.nuxt文件夹
static文件夹
nuxt.config.js文件
package.json文件
package-lock.json文件

把上面这几个文件、文件夹,进行压缩,然后把压缩包传递给服务器端

  • (3) 把发布包传到服务器端(用xftp软件、用git软件、用xshell中的linux的命令)

(3-1) 在自己电脑上连接上远程的服务器

ssh root@服务器的IP地址

(3-2) 在远程的服务器的根目录下创建一个文件夹:

mkdir realworld-nuxtjs
cd realworld-nuxtjs
pwd (把pwd后显示的路径复制->/root/realworld-nuxtjs)
exit (退出服务器,与服务器断开连接)
scp .\realworld-nuxtjs.zip root@服务器的IP地址:/root/realworld-nuxtjs (把压缩包传递给服务器)
ssh root服务器的IP地址
cd realworld-nuxtjs
ls (查看是否上传成功了)

  • (4) 在服务器端解压

unzip /realworld-nuxtjs.zip (unzip 命令是解压.zip压缩文件的)
ls -a (查看是否解压成功)

  • (5) 在服务器端安装依赖

npm install (在服务端安装依赖)
提示-bash: npm: command not found

友情链接:如何在CentOS 8服务器上安装和使用NVM

  • (6) 在服务器端启动服务看效果

npm run start
服务器的IP地址:端口号(查看最终的效果)

友情链接 1、Centos7开放及查看端口连接
友情链接 2、解决FirewallD is not running问题
友情链接 3、解决Warning:allowzonedrifting is enabled.This is considered an insecure configuration option.It will be removed in a future release ... ling it now.

nuxtjs项目在服务器端发布部署->使用PM2启动Node服务

上面的这种方式,在服务端启动的项目会占用命令行
命令行窗口一但关闭或者命令一但退出,项目就无法访问了
为了解决这个问题,我们可以项目运行在服务器的后台进程中,因此就需要使用PM2这个工具了

使用pm2启动服务端项目

pm2的githup仓库地址:github.com/Unitech/pm2
官方文档:pm2.io/

  • (1) 在服务器端安装pm2

npm install --global pm2

  • (2) 在服务器端使用pm2启动项目【pm2 start 脚本路径/启动项目的npm命令 】

在项目文件夹内运行:pm2 start npm -- start

  • (3) 在浏览器输入【服务器的IP地址:端口号】 查看效果

服务器的IP地址:端口号

  • (4) 在服务器端关闭pm2启动的项目

pm2 stop 0 (0是上图中的id的值)
pm2 stop npm (npm是上图中的name的值)
上面的2个方法都可以

  • (5) pm2的常用命令

nuxtjs项目在服务器端发布部署->现代化的部署方式->自动化部署(CI/CD)

CI/CD服务

常见的有:Jenkins\Gitlab CI\GitHub Actions\Travis CI\ Circle CI...

环境准备

  • (1) 有一台Linux系统的服务器
  • (2) 把代码提交到GitHub远程仓库
  • (3) 配置GitHub Access Token如下:

生成项目的tokens

  • 登录github --> 点击右上角头像,选择settings --> 选择页面左下角的Developer settings --> 选择页面左下角的Personal access tokens --> 点击右上角的Generate new token
    Generate new token页面的截图如下:

然后会生成一个令牌(下方截图),这个令牌要保存好,因为后期就再也看不见了
如果没有保存,后期忘记了,只能重新在生成一个新的令牌了

配置项目的Secrets
进入到自己的github项目内,点击Settings按钮,点击页面左下角的Secrets按钮,点击页面右上角中的New repository secret按钮
New repository secret按钮页面的截图如下:

  • (4) 配置GitHub Actions 执行脚本

在项目的根目录下创建.github/workflows目录 (名字不能错) 创建main.yml文件到workflows目录中,main.yml文件内容如下:

  • (5) 在项目的根目录下配置PM2的配置文件,文件名字叫【pm2.config.json】,代码如下:
{
 "apps": [
   {
     "name": "RealWorld",
     "script": "npm",
     "args": "start"
   }
 ]
}
  • (6) 把本地代码提交到远程仓库

git add.
git commit -m '就提交的信息'
git push (默认提交到master/main分支)

  • (7) 提交更新去开始自动化部署

git tag v0.1.0 (先打版本,因为main.yml文件中配置只有tag的时候才是去执行自动化部署)
git push origin v0.1.0 (必须加分支名,否则不让提交)

  • (8) 查看自动化部署的进度和状态

点击github项目内的Actions按钮,就可以查看

点击Aaction按钮后,页面的截图如下所示,说明自动化部署成功:

  • (9) 访问网站

服务器的IP地址:端口号

  • (10) 项目有调整,重复执行(6)~(10)

购买完服务器后主机后,【首次登陆 ssh root@主机ip】 提示ssh_exchange_identification: read: Connection reset by peer

题外话:
CentOS的回收站目录应该是这个路径:cd ~/.local/share/Trash/files/ 这个路径是隐藏属性的
删掉一个目录下所有的文件的命令: rm -rf *