Nuxt development experience sharing, let you step on less pits!

Keywords: Vue axios npm sass

Explain

This article is based on starter-template template for babies with vue-cli development experience.

vue init nuxt-community/starter-template

Nuxt

Official Documents

Simply put, Nuxt is an application framework based on Vue, using server-side rendering, so that your SPA application (Vue) can also have SEO.

life cycle

As we all know, the lifecycle of Vue runs on the client side (browser), while the lifecycle of Nuxt runs on the server side (Node), the client side, and even both sides:

 


Life cycle flow chart, Nuxt's life cycle in red box (running on the server side), yellow box running on the server side & client side at the same time, green box running on the client side

 

Practical Experience

1. There is no Window s object in the period of red box and yellow box.

<script>
export default {
  asyncData() {
    console.log(window) // Server Error Reporting
  },
  fetch() {
    console.log(window) // Server Error Reporting
  },
  created () {
    console.log(window) // undefined
  },
  mounted () {
    console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, ...}
  }
}
</script>

2. Configuration error page

You can customize the error page by editing the layouts/error.vue file.

<template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">Page does not exist</h1>
    <h1 v-else>Error exception occurred in application</h1>
    <nuxt-link to="/">Home page</nuxt-link>
  </div>
</template>

<script>
export default {
  props: ['error'],
  layout: 'blog' // You can specify custom layout for error pages
}
</script>

3. Custom Loading Page

nuxt.config.js

module.exports = {
  loading: '~components/loading.vue'
}

loading.vue

<template lang="html">
  <div class="loading-page" v-if="loading">
    <p>Loading...</p>
  </div>
</template>

<script>
export default {
  data: () => ({
    loading: false
  }),
  methods: {
    start () {
      this.loading = true
    },
    finish () {
      this.loading = false
    }
  }
}
</script>

4. Calibration parameters

If the validation fails, it automatically jumps to the error page

<script>
export default {
  validate({ params, query }) {
    return /^d+$/.test(params.id) // must be number
  }
}
</script>

5. Where do headers, Footer s and other public components go?

As you all know, the vue-cli entry file is app.vue, and in nuxt development it is. / layout/default.vue.

<template>
  <div id="app">
    <!-- Common Head Component -->
    <xxx-header></xxx-header>
    <!-- Routing view, equivalent to router-view -->
    <nuxt/>
    <!-- Common Bottom Component -->
    <xxx-footer></xxx-footer>
  </div>
</template>

6. No keep-alive

Because it's server rendering, it doesn't support keep-alive components, so the natural active and de activated lifecycles are gone.

7. Configuring plug-ins

All plug-ins are written in the / plugins directory, for example, vue-lazyload

plugins/lazy-load.js

import Vue from 'vue'
import VueLazyLoad from 'vue-lazyload'

Vue.use(VueLazyLoad, {
  loading: require('~/assets/images/loading.jpg'),
  error: require('~/assets/images/error.jpg')
})

nuxt.config.js

module.expors = {
  plugins = [
    {
      src: "~/plugins/lazy-load",
      ssr: false
    }
  ]
}

8. Using Axios and configuring global interceptors to handle cross-domain

starter-template template, recommended to use @nuxtjs/axios, @nuxtjs/proxy, no need to configure in plugins

Installation dependency

npm install @nuxtjs/axios @nuxtjs/proxy --save

Use and process cross-domain

// nuxt.config.js
module.exports = {
  modules: [ '@nuxtjs/axios' ], // No need to add @nuxtjs/proxy
  axios: {
    proxy: true,
    prefix: '/api', // baseURL
    credentials: true,
  },
  proxy: {
    '/api/': {
      target: 'http://127.0.0.1:2001', //proxy address
      changeOrigin: true,
      pathRewrite: {
        '^/api': ''
      },
    },
  }
}

Use in components

<script>
export default {
  fetch ({ app }) {
    console.log(app.$axios)
  },
  asyncData ({ app }) {
    console.log(app.$axios)
  },
  created () {
    console.log(this.$axios)
  }
}
</script>

So far, we don't need to configure Axios in plugins, but if we want to set up a global interceptor, we need to create a new / plugins/axios.js

export default function (app) {
  let axios = app.$axios; 
 // Basic configuration
  axios.defaults.timeout = 10000
  axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

  // Request callback
  axios.onRequest(config => {})

  // Return callback
  axios.onResponse(res => {})

  // Error callback
  axios.onError(error => {})
}

Then configure it in plugins

module.exports = {
  plugins = [
    {
      src: "~/plugins/axios",
      ssr: false
    },
  ]
}

9. Default Meta Tag

nuxt.config.js

module.exports = {
  head: {
    title: 'your project title',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' }
    ],
    link: [
      { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' }
    ]
  }
}

10. Meta tags specific to page components

<script>
export default {
  head () {
    return {
      meta: 
      [
        {
          name: 'keywords',
          content: 'The strongest King,Eat Chicken Tonight'
        },
      ]
    }
  }
}
</script>

11. Meta Label Filling for Dynamic Routing

Game details page example, because the data is asynchronously acquired, we need to write the data acquisition in the asyncData hook, until the data acquisition success will render the page components.

<script>
export default {
  async asyncData ({ app, params }) {
    let data = await app.$axios.get(`/appinfo/${params.id}`);
    return {
      appname: data.appinfo.appname
    }
  },
  head () {
    return {
      meta: 
      [
        {
          name: 'keywords',
          content: `${this.appname},Infinite Gemstone,Infinite Treasure`
        },
      ]
    }
  }
}
</script>

12. Use Vuex

nuxt integrates vuex itself, so you don't need to install it. You can use it by creating a new index.js in the / store directory

import Vuex from 'vuex'

let store = () => new Vuex.Store({
  state: {
    token: ''
  },
  mutations: {
    setToken (state, token) {
       state.token = token
    }
  }
})

export default store

13. Login status?

In the vue-cli project, we can use vuex-persistedstate It can make the state of vuex persistent, page refresh will not be lost, the principle of course is the local Storage! Of course, I prefer to use it. vue-cookies To save token, the question arises. How can the nuxt project save the login status? Of course, we can use both of the above methods, but there is a problem. Because there are no windows objects in the create hook (both cookie s and local Storage need windows objects), when you need to determine whether token exists, you have to mount it, which means you can't do it at the moment when the page comes in. Knowing whether or not you have logged in will result in a slow half-shot display of usernames and components hidden

nuxt is very friendly. It provides fetch hooks and nuxtServerInit. Both hooks run on the server side and we can quickly operate the store.

14. Use of fetch

If the page component sets the fetch method, it will be invoked before the component is loaded each time (before the server or switch to the target route). This method needs to cooperate with the server.

<script>
export default {
  async fetch ({ app, store, params }) {
    let { data } = app.$axios.get('/token');
    store.commit('setToken', data.token);
  }
}
</script>

15. nuxtServerInit

Ultimate Invincible Method

import Vuex from 'vuex'

let store = () => new Vuex.Store({
  state: {
    token: ''
  },
  mutations: {
    setToken (state, token) {
       state.token = token
    }
  },
  actions: {
    nuxtServerInit({ commit }, { req }) {
      let cookie = req.headers.cookie;

      // Turn cookie s into json objects (implement this method yourself)
      let token = cookieparse(cookie).token;
      commit('setToken', token);
    },
  }
})

export default store

16. Encapsulating your own global approach

 let xielikang = function () {

  /**
   * @method Printing Information Method
   * @param {String} msg information
   */
  let message = function (msg) {
    msg && console.log(msg)
  }

  let otherfn = function (msg) {}

  return {
    message,
    otherfn
  }

}

Vue.prototype.$kang= xielikang

Component invocation

<script>
export default {
  created() {
    this.$kang.message('What's wrong with you, little brother?')
  }
}
</script>

By the way, don't forget to configure in plugins, you can go back to Section 7 to see the configuration.

17. Global Style

nuxt.config.js

module.exports = {
  css: ['~/assets/stylesheets/main.min.css']
}

18. Use Element-UI

Or do you create element-ui.js in the plugins folder?

// Global introduction
import Vue from 'vue'
import ElementUI from 'element-ui'

Vue.use(ElementUI)

// On-demand introduction
import { Button, Loading, MessageBox } from 'element-ui'

Vue.use(Button)
Vue.prototype.$loading = Loading.service
Vue.prototype.$msgbox = MessageBox

nuxt.config.js

module.exports = {
  css: ['element-ui/lib/theme-chalk/index.css'],
  plugins: [
    {
      src: "~/plugins/element",
      ssr: true
    }
  ]
}

18. How to use sass preprocessor

Installation dependency

npm install node-sass sass-loader --save

Use in components (no additional configuration is required)

<style lang="scss" scoped>

</style>

19. Use of fetch, asyncData, validate

It can only be used by page components, that is, components in pages directory, rather than components in components directory.

20. Traditional deployment

npm run build && npm run start

21. pm2 deployment

It allows you to permanently keep your applications active, reload them without downtime, and don't need the traditional. nuxt folder deployed. The deployment method is as hot as the production environment.

npm install pm2 -g
npm run build
pm2 start ./node_modules/nuxt/bin/nuxt-start

This is the end of this article. This is the pit that we are treading on at present. If there are any mistakes, please point out.

Welcome all front-end enthusiasts to pay attention to my personal Wechat Public Number. I will often share the latest, practical front-end articles and techniques. I wish you a thorough understanding on the road of front-end development!



Author: Can't write the front end
Link: https://www.jianshu.com/p/840169ba92e6
Source: Brief Book
The copyright of the brief book belongs to the author. For any form of reprinting, please contact the author for authorization and indicate the source.

Posted by ErcFrtz on Wed, 24 Jul 2019 03:23:49 -0700