初探NUXT(ssr)

项目需要 seo 及兼容手机端,百度大法后选定了 nuxt,记录一下

下载安装

百度很多就不写了

路由

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
39
40
41
42
43
44
45
46
47
48
49
50
// nuxt 会自动生成路由  主要提一下动态路由


// 目录结构为

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue


// 生成的路由配置为


router: {
routes: [
{
name: 'index',
path: '/',
component: 'pages/index.vue'
},
{
name: 'users-id',
path: '/users/:id?',
component: 'pages/users/_id.vue'
},
{
name: 'slug',
path: '/:slug',
component: 'pages/_slug/index.vue'
},
{
name: 'slug-comments',
path: '/:slug/comments',
component: 'pages/_slug/comments.vue'
}
]
}

// 可以在组件内检验参数

export default {
validate ({ params }) {
// 必须是number类型
return /^\d+$/.test(params.id)
}
}

插件

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// 举个栗子 使用iview
// 在plugins目录创建iview.js 代码入下

import Vue from 'vue'
import iView from 'iview'
import locale from 'iview/dist/locale/en-US' // Change locale, check node_modules/iview/dist/locale

Vue.use(iView, {
locale
})

Vue.prototype.$Message.config({
top: 300
})

// vuex刷新时需要初始化 我这边是用插件来设置
// initStore


import { localStore } from '@/utils/tools'
import { getStore } from '@/utils/storage'
export default function({ $axios, store }) { //这里的参数为Context上下文对象
if (JSON.stringify(store.state.info) === '{}') {
$axios.post('/api/common/info').then(res => {
store.commit('SETINFO', res.data)
})
}
if (getStore('token')) {
store.dispatch('changeLogin', {
state: true,
info: JSON.parse(getStore('userInfo')) || {}
})
$axios.post('/api/common/history')
.then(res=>{
store.commit('GETHSITORY',res.data)
})
} else {
store.dispatch('changeLogin', {
state: false
})
}
if (localStore.get('searchParams')) {
store.commit('SETSEARCH', localStore.get('searchParams'))
}
}




// nuxt.config.js

{
plugins:[
{
{
src: '@/plugins/iview',
ssr: true //ssr默认为true 表示在服务端也会渲染
},
{
src: '@/plugins/initStore',
ssr: false //ssr为false时只在客户端渲染 需要用到window对象时就需要设置
}
}
]
}

兼容移动端配置

由于 PC 端需要兼容 ie9 并不能通用 所以我使用了两套代码 通过中间件来切换

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
  // 在middleware文件下创建一个device.js  每次切换路由时会先进入中间件

import { deviceType } from "~/utils/tools";
// deviceType为判断客户端的方法
export default function(context) {
context.userAgent = process.server
? context.req.headers["user-agent"]
: navigator.userAgent;
// 给全局上下文添加一个属性来保存我们返回的匹配信息
// console.log('tag', context)
context.deviceType = deviceType(context.userAgent);
// 若是判断UA非移动端的,就在这里做处理了..
// context.redirect(status,url) 这个可以重定向到外部网站

if (context.deviceType.type === "pc") {
if (/m[-]*[\w]*/g.test(context.route.name)) {
context.redirect(context.route.fullPath.slice(2)); // 转换url /m/about 转为 /about
}
} else {
if (!/m[-]*[\w]*/g.test(context.route.name)) {
// //redirect path from '/{PATH}' to '/m /{PATH}';
context.redirect("/m" + context.route.fullPath); // 转换url /about 转为 /m/about
}
}
}

// nuxt.config.js
router: {
mode: 'history',
middleware: ['device'],
fallback: true
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 //tools.js
const deviceType = function (UA) {
const reg = /(Android|webOS|iPhone|iPod|tablet|BlackBerry|Mobile)/i;
if (reg.test(UA)) {
return {
type: "mobile",
};
} else {
return {
type: "pc",
};
}
}
export {
deviceType
}

模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// axios
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios'
// '@nuxtjs/proxy'
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
proxy: true,
// baseUrl: 'https://api.kuaimaidian.com'
},
proxy: {
'/api': {
// target: 'https://api.kuaimaidian.com',
target: 'http://192.168.2.17',
pathRewrite: {
'^/api': '/api'
}
}
},

部署

npm build 后将.nuxt,static,package.json,nuxt.config.js 这 4 个文件夹放到服务器目录文件下 或者直接在服务器上把代码拉下来 build,然后 npm i 安装依赖 ,最后 npm start 运行即可
这里有个地方要注意 我们需要在 nuxt.config.js 加上这行代码 ,不然的话访问不了

1
2
3
4
server: {
port: 3000, // default: 3000
host: "0.0.0.0" // default: localhost
},
  • nginx 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
upstream nodenuxt {
server 127.0.0.1:3000; #nuxt项目 监听端口
keepalive 64;
}
server {
listen 80;
server_name mysite.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Nginx-Proxy true;
proxy_cache_bypass $http_upgrade;
proxy_pass http://nodenuxt; #反向代理
}
}

最后装 pm2 进程守护来启动 node 就 ok 了

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
// pm2 常用命令

$ pm2 start npm --name "myapp" -- run start // 启动名称为myapp的node程序

$ pm2 start app.js # 启动app.js应用程序
$ pm2 start app.js --name="api" # 启动应用程序并命名为 "api"
$ pm2 start app.js --watch # 当文件变化时自动重启应用
$ pm2 start script.sh # 启动 bash 脚本

$ pm2 list # 列表 PM2 启动的所有的应用程序
$ pm2 monit # 显示每个应用程序的CPU和内存占用情况
$ pm2 show [app-name] # 显示应用程序的所有信息

$ pm2 logs # 显示所有应用程序的日志
$ pm2 logs [app-name] # 显示指定应用程序的日志
pm2 flush

$ pm2 stop all # 停止所有的应用程序
$ pm2 stop 0 # 停止 id为 0的指定应用程序
$ pm2 restart all # 重启所有应用
$ pm2 reload all # 重启 cluster mode下的所有应用
$ pm2 gracefulReload all # Graceful reload all apps in cluster mode
$ pm2 delete all # 关闭并删除所有应用
$ pm2 delete 0 # 删除指定应用 id 0
$ pm2 scale api 10 # 把名字叫api的应用扩展到10个实例
$ pm2 reset [app-name] # 重置重启数量

$ pm2 startup # 创建开机自启动命令
$ pm2 save # 保存当前应用列表
$ pm2 resurrect # 重新加载保存的应用列表