The eleventh bullet of the qualified front-end series - a preliminary study of Nuxt.js secret garden

foreword

The author recently wanted to learn something new in his spare time, so I started to get in touch with server-side rendering (SSR).

The technology stack is Nuxt, which is smooth out of the box. The whole project integrates vue + nuxt + axios + vuex + vue-router (nuxt comes with vuex and vue-router).

The project currently implements the following major functions

  • Server-side rendering
  • Static page deployment
  • Nuggets Home
  • Nuggets Recommended List
  • Scrolling pagination loading
  • Layout adaptation on different sides

The full address of the project: nuxt-ssr-demo

Front-end communication group: 731175396

1. Effect diagram

1, PC edge

2. Mobile terminal

After reading the final renderings, let's start our actual combat journey~

2. Project combat

Before starting a project, I like to set up an empty shelf. So here is the old rule, first take everyone to build the empty shell of the project.

1. Use the starter template

Here about the project initialization, I directly use the starter template provided by the Nuxtofficial website

# 安装 vue-cli
npm install -g vue-cli
# 初始化项目
vue init nuxt-community/starter-template nuxt-ssr-demo
# 安装依赖
cd nuxt-ssr-demo
npm install # Or yarn install
# 启动本地服务
npm run dev

Visit http://localhost:3000 , now let's look at the initialized project directory

├── assets						css,图片等资源都在这
├── components                  组件相关
├── layouts                     路由布局
├── middleware                  中间件
├── pages                  		路由页面
├── static                  	静态资源
├── pages                  		路由页面
├── store              	      	vuex 相关
├── nuxt.config.js              nuxt 相关配置
├── package.json              	依赖相关
├── README.md              	    项目介绍

Friends who have been vuein , may have a little doubt when looking at this, why is there no router routing related files? Do n't panic, Nuxtit will help you to automatically parse the files under pages into routes. So in the next development, remember not to add files under pages blindly, each vue file under pages is a route.

2. Introduce axios

i. Install dependencies

npm i axios -S

ii. Package axios

For more convenient development after the project, it is necessary for us to encapsulate axios, and we must always develop such a good habit.

First, create a new servicedirectory , config.jsand create index.jstwo files under it. The following code is for reference only. If your project needs to do some additional configuration, you can expand it yourself.

config.jsWrite in :

import http from 'http'
import https from 'https'

export default {
  // 自定义的请求头
  headers: {
    post: {
      'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
    },
    'X-Requested-With': 'XMLHttpRequest'
  },
  // 超时设置
  timeout: 10000,
  // 跨域是否带Token
  withCredentials: true,
  // 响应的数据格式 json / blob /document /arraybuffer / text / stream
  responseType: 'json',
  // 用于node.js
  httpAgent: new http.Agent({
    keepAlive: true
  }),
  httpsAgent: new https.Agent({
    keepAlive: true
  })
}

index.jsWrite in :

import axios from 'axios'
import qs from 'qs'
import config from './config'

const service = axios.create(config)

// POST 传参序列化
service.interceptors.request.use(
  config => {
    if (config.method === 'post') config.data = qs.stringify(config.data)
    return config
  },
  error => {
    return Promise.reject(error)
  }
)
// 返回结果处理
service.interceptors.response.use(
  res => {
    return res.data
  },
  error => {
    return Promise.reject(error)
  }
)

export default {
  // post 方法
  post (url, data) {
    console.log('post request url', url)
    return service({
      method: 'post',
      url,
      params: data
    })
  },
  // get 方法
  get (url, data) {
    console.log('get request url', url)
    return service({
      method: 'get',
      url,
      params: data
    })
  },
  // delete 方法
  delete (url, data) {
    console.log('delete request url', url)
    return service({
      methods: 'delete',
      url,
      params: data
    })
  }
}

iii. Cross-domain processing

vueStudents who have used , must know that for the cross-domain in the project, thevue-cli options in are encapsulated. What it exposes is an , which is an integration of in and its third-party plugins.webpackproxyproxyTablewebpackproxyhttp-proxy-middleware

Unfortunately, there Nuxtis no proxyTablesuch a configuration item for cross-domain configuration. Fortunately of course, in Nuxt, you can http-proxy-middlewarehandle cross-domain directly by configuring . Fortunately, two packages are Nuxtofficially provided to deal with axioscross-domain issues.

First, install

npm i @nuxtjs/axios @nuxtjs/proxy -D

Then configure it in the nuxt.config.jsfile

modules: [
  '@nuxtjs/axios'
],
axios: {
  proxy: true
},
proxy: {
  '/api': {
    target: 'xxx.target.com',
    pathRewrite: { '^/api': '' }
  }
}

It should be noted here that because it is server-side rendering, we have to always know whether the current address belongs to a routing jump or an axios request. So we need to service/index.jswrite the following judgment in

// 判断是路由跳转还是 axios 请求
if (process.server) {
  config.baseURL = `http://${process.env.HOST || 'localhost'}:${process.env.PORT || 3000}`
}

Then you can safely use your axios to make cross-domain requests

3. Manage vuex

Let's take a look at some of the files we need in the store directory

├── actions.js                  axios 请求相关
├── index.js					主入口文件
├── mutations.js                同步状态操作相关
├── state.js                  	初始状态相关

Next, let's take a look at the content of each file

i. actions.js

import request from '~/service'

const api = '/api'

export const banner = async (store, params) => {
  return await request.get(`${api}/v1/get_banner`, params)
}

ii. state.js

export default {
  counter: 1,
  isPhone: false
}

iii. mutations.js

export function INCREMENT (state) {
  state.counter++
}

export function PCORPHONE (state, bool) {
  state.isPhone = bool
}

iv. index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import * as mutations from './mutations'
import * as actions from './actions'

Vue.use(Vuex)

const store = () => new Vuex.Store({
  state,
  mutations,
  actions
})

export default store

Then you can use it in the page

<template>
  <div class="page">
    <button @click="handleClick">{{ counter }}</button>
    <p>{{ banner.name }}</p>
  </div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  async asyncData ({ store, error }) {
    // 对 axios 进行批量处理
    let [ res ] = await Promise.all([
      store.dispatch('banner')
    ]).catch((e) => {
      error({ statusCode: 404, message: 'Post not found' })
    })
    return {
      banner: res.banner
    }
  },
  computed: {
    ...mapState({
      counter: state => state.counter
    })
  },
  methods: {
    handleClick () {
      this.$store.commit('INCREMENT')
    }
  }
}
</script>

4. Global component management

NuxtThe project of is not vueas good as the project of , which provides the main entry file for us to configure the global components. But it is relatively simple to do this. We only need to follow the specifications given by the Nuxtofficial website and write the relevant configuration introduced by the component into the plugins directory.

For example, I need to introduce the three-party component library element-ui , we just need to create a new element-ui.jsfile and write

import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(ElementUI)

Then import in the nuxt.config.jsfile

plugins: [
  '~/plugins/element-ui'
]

Finally, you can use the components in the element-uicomponent .

Of course, if you want to configure your own local global components, the same is true. First create a js file in the plugins directory, then import your file, and finally import it in the nuxt.config.jsfile .

5. Global style management

Similar to component management, the difference is that css needs to be stored in the assets directory. For example, now I need to have a main.cssfile to dynamically switch routing jumps.

First, you have assets/main.cssto write the reset style in

.page-enter-active, .page-leave-active {
  transition: opacity .2s;
}

.page-enter, .page-leave-active {
  opacity: 0;
}

Then, you just need to nuxt.config.jsenter the import at

css: [
  '~/assets/stylus/main.styl'
]

NuxtFor more usage, I will not introduce them one by one. For details, please refer to: Nuxt.js documentation official website

Then the specific development of the project is also commonplace, and I will not describe it here. If you want to know more, you can go to github and check it yourself. If you have any questions, you can add the old driver group 731175396, and then just ask me in the group.

In the next chapter, I will talk about some points of project deployment

3. Project deployment

At this point, you have to make sure that you have a server of your own. If not, I feel like I should buy one. Now both Alibaba Cloud and Tencent Cloud are doing activities, and it is very cheap~

OK, the article continues. Before proceeding to the deployment explanation, let's take a look at several commands Nuxtprovided

Order describe
nuxt Start a hot loaded web server (development mode) localhost:3000
nuxt build Compile the application with webpack, compress JS and CSS resources (for publishing)
nuxt start Start a web server in build mode ( nuxt buildwill be executed first)
nuxt generate Compile the application and generate the corresponding HTML file according to the routing configuration (for static site deployment)

1. Static page deployment

We can see from the documents given on the official website that the command needed to deploy a static page is to nuxt generategenerate a dist directory under the root directory when it is executed, and the files in it are all packaged files required by the static page.

One thing to pay special attention to here is that if there is an axios request in your project, remember to start a local service locally~ Otherwise, an error will be reported when the axios request is executed during packaging. Because we used the node's process to determine whether the running environment is a jump or a request, and the package request does not depend on the node environment

i. Using gh-pages

Here, I first assume that the friends can execute normally nuxt generateand generate the corresponding dist directory.

For the parallel development of the project, we .gitignoregenerally ignore the packaged files in the file, but the deployment of our static pages needs to use all the packaged files in the dist directory. So here we will use gh-pages to publish the packaged files to our git repository

# 安装 gh-pages
npm i gh-pages -D

Then package.jsonwrite configuration (of course you can also create a new file to execute the release)

"scripts": {
  "deploy": "gh-pages -d dist"
}

Execute npm run deploy, then your dist directory will be sent to the gh-pages branch of your repository

ii. Start the deployment

After uploading the package file, the first thing you need to do is connect to your server. Then cd to the server root directory and download your project under the data/wwwdirectory git clone. then switch to gh-pagesbranch

Next, start configuring your nginx (for those who haven't downloaded nginx, please solve it by yourself)

 server {
  # 端口,默认是 80
  listen 81;
  # 服务名(写域名或者 ip 地址都可以)
  server_name 123.12.123.12;
  # server 根目录
  root  /data/www/nuxt-ssr-demo;
  # 主入口文件
  index  index.html;
  # 反向代理
  location /api/ {
    proxy_pass https://xxx.target.com/;
  }
}

Then restart nginx

sudo service nginx restart

Then you can access your deployed static page at http://123.12.123.12:81

2. Server-side rendering deployment

Seeing the above static page deployment, some students will ask for details. For static page deployment, there is no advantage of server-side rendering.

Yes, if your project is just static pages, doing static deployment is completely OJBK. But if it involves a request, let's do the server-side deployment obediently~

Before starting, please make sure that the node environment has been set up on your server. For those who don't, I recommend using nvm to install node. Next, start deploying

i. Act as a service agent

The first step is to switch the git project under the previous clone to the main development branch, and then modify yours for future conveniencepackage.json

"scripts": {
  "build": "npm run lint && nuxt build && npm start",
  "start": "nuxt start"
}

The second step, start the service

npm run build

The third step, configure your nginx file

# 通过 upstream nodejs 可以配置多台 nodejs 节点,做负载均衡
# keepalive 设置存活时间。如果不设置可能会产生大量的 timewait
# proxy_pass 反向代理转发 http://nodejs

upstream nodenuxt {
    server 127.0.0.1:3000; # nuxt 项目监听端口
    keepalive 64;
}
server {
  listen 82;
  server_name 118.25.109.133;
  
  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; # 反向代理
  }
}

Finally, restart the nginx service

sudo service nginx restart

ii. Use pm2 as a process daemon

If we deploy according to the above steps, the server will be disconnected frequently, and our service will be disconnected. So in order to guard our nodejs process, here I will use pm2 to guard the process

First install pm2 globally

npm i pm2 -g

Then go to the project directory and execute

pm2 start npm --name "nuxt-ssr-demo" -- run build

Then, my mother no longer has to worry about my nodejs process being interrupted when it is interrupted~

For the usage of pm2, please input pm2 --helpand check by yourself

Summarize

The article is coming to an end here, here I make a small summary. In a week of study and actual combat, while producing a high imitation Nuggets SSR Demo, I also stepped on some pits.

For Nuxt, in terms of use, it is relatively simple and easy to use. Compared with vue-ssr, it greatly simplifies the configuration of development, so that developers can only think about business development without worrying too much about the configuration of files. Among them, Nuxtby monitoring the changes of the pages directory file and automatically generating the route, it directly saves our usual configuration of the route.

However, there is still room for improvement as a Nuxtwhole . At present, there are relatively limited third-party plug-ins related to the community, and there are relatively few related reference materials on the market.

Anyway , I hope Nuxtthe community can get better and better~

Finally, for those who want to see the source code of the project, here I will put one last link

The full address of the project: nuxt-ssr-demo

Front-end communication group: 731175396

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324371097&siteId=291194637