Nuxt開發經驗分享css
本文章基於starter-template模板進行講解,面向有vue-cli開發經驗的寶寶html
vue init nuxt-community/starter-template
官方文檔vue
簡單來講,Nuxt就是基於Vue的一個應用框架,採用服務端渲染,讓你的SPA應用(Vue)也能夠擁有SEOnode
衆所周知,Vue的生命週期全都跑在客戶端(瀏覽器),而Nuxt的生命週期有些在服務端(Node),客戶端,甚至兩邊都在:ios
1. 紅框、黃框內的週期都不存在Window對象vuex
<script> export default { asyncData() { console.log(window) // 服務端報錯 }, fetch() { console.log(window) // 服務端報錯 }, created () { console.log(window) // undefined }, mounted () { console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …} } } </script>
2. 配置錯誤頁面vue-cli
你能夠經過編輯 layouts/error.vue 文件來定製化錯誤頁面.npm
<template> <div class="container"> <h1 v-if="error.statusCode === 404">頁面不存在</h1> <h1 v-else>應用發生錯誤異常</h1> <nuxt-link to="/">首 頁</nuxt-link> </div> </template> <script> export default { props: ['error'], layout: 'blog' // 你能夠爲錯誤頁面指定自定義的佈局 } </script>
3. 自定義Loading頁面element-ui
nuxt.config.jsjson
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. 校驗參數
若是校驗失敗,則自動跳轉到錯誤頁面
<script> export default { validate({ params, query }) { return /^d+$/.test(params.id) // must be number } } </script>
5. Header、Footer等公共組件放哪?
你們都知道,vue-cli入口文件是app.vue,在nuxt開發當中則是./layout/default.vue
<template> <div id="app"> <!-- 公共頭部組件 --> <xxx-header></xxx-header> <!-- 路由視圖,至關於router-view --> <nuxt/> <!-- 公共底部組件 --> <xxx-footer></xxx-footer> </div> </template>
6. 沒有keep-alive
因爲是服務端渲染,因此不支持組件的keep-alive,那天然activated、deactivated這兩個生命週期也沒了
7. 配置插件
全部插件都寫在/plugins目錄下,這裏以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. 使用Axios,並配置全局攔截器,處理跨域
starter-template模板,推薦使用@nuxtjs/axios、@nuxtjs/proxy,不須要在plugins配置
安裝依賴
npm install @nuxtjs/axios @nuxtjs/proxy --save
使用、處理跨域
// nuxt.config.js module.exports = { modules: [ '@nuxtjs/axios' ], // 不須要加入@nuxtjs/proxy axios: { proxy: true, prefix: '/api', // baseURL credentials: true, }, proxy: { '/api/': { target: 'http://127.0.0.1:2001', // 代理地址 changeOrigin: true, pathRewrite: { '^/api': '' }, }, } }
組件中使用
<script> export default { fetch ({ app }) { console.log(app.$axios) }, asyncData ({ app }) { console.log(app.$axios) }, created () { console.log(this.$axios) } } </script>
到此爲止,咱們並不須要在plugins配置axios,可是若是要設置全局攔截器,那麼就要新建一個/plugins/axios.js
export default function (app) { let axios = app.$axios; // 基本配置 axios.defaults.timeout = 10000 axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded' // 請求回調 axios.onRequest(config => {}) // 返回回調 axios.onResponse(res => {}) // 錯誤回調 axios.onError(error => {}) }
而後在plugins配置它
module.exports = { plugins = [ { src: "~/plugins/axios", ssr: false }, ] }
9. 默認Meta標籤
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' } ] } }
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標籤
<script> export default { head () { return { meta: [ { name: 'keywords', content: '最強王者,今晚吃雞' }, ] } } } </script>
11. 動態路由的Meta標籤填充
遊戲詳情頁面舉例子,因爲數據是異步獲取的,咱們須要把數據獲取寫在asyncData鉤子,待數據獲取成功纔會渲染該頁面組件
<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},無限寶石,無限元寶` }, ] } } } </script>
12. 使用Vuex
nuxt本身集成了vuex,因此不須要安裝,在/store目錄下新建index.js便可使用
import Vuex from 'vuex' let store = () => new Vuex.Store({ state: { token: '' }, mutations: { setToken (state, token) { state.token = token } } }) export default store
13. 登陸狀態?
vue-cli項目中,咱們能夠用vuex-persistedstate,它可使vuex的狀態持久化,頁面刷新都不會丟失,原理固然是localStorage啦!固然我更喜歡用vue-cookies進行保存token,問題來了,nuxt項目怎麼保存登陸狀態呢?固然上面這兩種方法咱們均可以使用,可是有個問題,因爲在created鉤子中不存在window對象(獲取cookie、localStorage都須要window對象),當你須要判斷是否存在token的時候,你必需要在mounted進行操做,這說明頁面進來的一瞬間你沒法得知是否已經登陸了,這會致使顯示用戶名、組件顯示於隱藏都慢半拍
nuxt很是友好,它提供了fetch鉤子,還有nuxtServerInit,這兩個鉤子都運行在服務端而且咱們能很快速地操做store
14. fetch的使用
若是頁面組件設置了fetch方法,它會在組件每次加載前被調用(在服務端或切換至目標路由以前),此方法須要跟服務端的人員配合
<script> export default { async fetch ({ app, store, params }) { let { data } = app.$axios.get('/token'); store.commit('setToken', data.token); } } </script>
15. nuxtServerInit
終極無敵方法
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; // 將cookie轉成json對象(本身實現該方法) let token = cookieparse(cookie).token; commit('setToken', token); }, } }) export default store
16. 封裝屬於本身的全局方法
let xielikang = function () { /** * @method 打印信息方法 * @param {String} msg 信息 */ let message = function (msg) { msg && console.log(msg) } let otherfn = function (msg) {} return { message, otherfn } } Vue.prototype.$kang= xielikang
組件調用
<script> export default { created() { this.$kang.message('小老弟,你怎麼回事') } } </script>
對了,別忘了在plugins中配置,能夠回到第7小節查看配置
17. 全局樣式
nuxt.config.js
module.exports = { css: ['~/assets/stylesheets/main.min.css'] }
18. 使用Element-UI
仍是plugins文件夾新建element-ui.js
// 全局引入 import Vue from 'vue' import ElementUI from 'element-ui' Vue.use(ElementUI) // 按需引入 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. 如何使用sass預處理器
安裝依賴
npm install node-sass sass-loader --save
組件中使用(不須要其餘的配置了)
<style lang="scss" scoped> </style>
19. fetch、asyncData、validate使用範圍
只能在頁面組件使用,也就是pages目錄下的組件,而不是components目錄下的組件,要有所區分
20. 傳統部署
npm run build && npm run start
21. pm2部署
它容許您永久保持應用程序活躍,無需停機便可從新加載它們,並不須要傳統部署的.nuxt文件夾,該部署方法也跟生產環境同樣含熱更新
npm install pm2 -g
npm run build
pm2 start ./node_modules/nuxt/bin/nuxt-start