英文官網地址:https://zh.nuxtjs.org/
中文官網地址:https://www.nuxtjs.cn/
github上的一個基於nuxt的服務端渲染項目:https://github.com/Sandop/NuxtPC
創建一個nuxt項目:確保安裝了npx(npx在NPM版本5.2.0默認安裝了):
npx create-nuxt-app nuxtDemo
之后會讓選擇ui框架,服務器什么的,我選擇的element-ui和express服務器,我喜歡做spa項目,就選擇了搭建一個spa項目(后面才發現,用nuxt的目的是解決seo的問題,就不要用spa模式了,用這個框架就用那個universal模式就行)
安裝之后,生成項目目錄如下,無選擇的spa頁面
和vue-cli相似
cd到創建好的項目,npm run dev 運行項目
assets:資源目錄:放置用於組織未編譯的靜態資源如 LESS
、SASS
或 JavaScript
。
components:組件目錄
layouts:布局目錄,剛創建項目自帶一個default.vue的自定義目錄,什么內容都沒有,就放了個<nuxt/>視圖容器,這是所有組件頁面都默認的布局,當然可以自定義布局,可以在具體頁面通過layout指定頁面使用的布局
middleware:中間件目錄
pages:頁面目錄,nuxt會根據這個文件目錄自動生成路由!!
plugins:插件目錄,根vue.js應用
實例化之前需要運行的 Javascript 插件。
static:靜態文件目錄,用於存放應用的靜態文件,此類文件不會被 Nuxt.js 調用 Webpack 進行構建編譯處理。 服務器啟動的時候,該目錄下的文件會映射至應用的根路徑 /
下
store:Store目錄,用於組織應用的 Vuex 狀態樹 文件。 Nuxt.js 框架集成了 Vuex 狀態樹 的相關功能配置,在 store
目錄下創建一個 index.js
文件可激活這些配置。
nuxt.config.js :用於組織Nuxt.js 應用的個性化配置,以便覆蓋默認配置。
package.json:用於描述應用的依賴關系和對外暴露的腳本接口。
配置:
Nuxt.js 默認的配置涵蓋了大部分使用情形,可通過 nuxt.config.js 來覆蓋默認的配置。
配置文檔:https://zh.nuxtjs.org/guide/configuration
路由:
文檔地址:https://zh.nuxtjs.org/guide/routing
Nuxt.js 依據 pages
目錄結構自動生成 vue-router 模塊的路由配置。
要在頁面之間使用路由,我們建議使用<nuxt-link>
標簽。
視圖:
模板
定制化默認的 html 模板,只需要在應用根目錄下創建一個 app.html
的文件。
默認模板為:可以在模板中添加ie條件表達式
<!DOCTYPE html> <html {{ HTML_ATTRS }}> <head {{ HEAD_ATTRS }}> {{ HEAD }} </head> <body {{ BODY_ATTRS }}> {{ APP }} </body> </html>
布局
默認布局是創建項目時自動生成的layouts/default.vue
layouts
目錄中的每個文件 (頂級) 都將創建一個可通過頁面組件中的 layout
屬性訪問的自定義布局。
錯誤頁面:
你可以通過編輯
layouts/error.vue
文件來定制化錯誤頁面.

這個布局文件不需要包含 <nuxt/>
標簽。你可以把這個布局文件當成是顯示應用錯誤(404,500等)的組件。
舉一個個性化錯誤頁面的例子 layouts/error.vue
:
<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>
頁面:
頁面組件實際上是 Vue 組件,只不過 Nuxt.js 為這些組件添加了一些特殊的配置項(對應 Nuxt.js 提供的功能特性)以便你能快速開發通用應用。
HTML 頭部:
Nuxt.js 使用了 vue-meta
更新應用的 頭部標簽(Head)
and html 屬性
。
Nuxt.js 允許你在 nuxt.config.js
里定義應用所需的所有默認 meta 標簽,在 head
字段里配置就可以了:
一個使用自定義 viewport
和 谷歌字體
的配置示例:
head: { meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' } ], link: [ { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' } ] }
當然也可以引入jquery、bootstrap等第三方庫
引入第三方庫,有npm引入方式和CDN引入方式兩種,可以自己選擇,我一般用CDN引入第三方庫,有利於減少項目體積;
異步數據
Nuxt.js 擴展了 Vue.js,增加了一個叫 asyncData
的方法,使得我們可以在設置組件的數據之前能異步獲取或處理數據。
asyncData 方法:
https://zh.nuxtjs.org/guide/async-data/
asyncData
方法會在組件(限於頁面組件)每次加載之前被調用。它可以在服務端或路由更新之前被調用。 在這個方法被調用的時候,第一個參數被設定為當前頁面的上下文對象,你可以利用 asyncData
方法來獲取數據,Nuxt.js 會將 asyncData
返回的數據融合組件 data
方法返回的數據一並返回給當前組件。
注意:由於asyncData
方法是在組件 初始化 前被調用的,所以在方法內是沒有辦法通過 this
來引用組件的實例對象。
此方法是服務端渲染的關鍵之一,它是在組件初始化之前調用的,方法的第一個參數是上下文對象,里面包括好多對象,如store,res,req,params,query,isDev,route,redirect,error等很有用的信息供我們使用;在這個方法內,要return出一個對象,這個對象會和data合並,能夠直接綁定到模板中,作用方面和data是一樣的;記住,這里面的有數據完成后才會初始化組件,這個很重要,一些DOM操作就不要在這個方法中進行了,因為這個方法進行的時候,還沒有DOM,主要用於拿到初始數據就行。
資源文件
默認情況下 Nuxt 使用 vue-loader、file-loader 以及 url-loader 這幾個 Webpack 加載器來處理文件的加載和引用。對於不需要通過 Webpack 處理的靜態資源文件,可以放置在 static
目錄中。
靜態文件
如果你的靜態資源文件需要 Webpack 做構建編譯處理,可以放到 assets
目錄,否則可以放到 static
目錄中去。
Nuxt 服務器啟動的時候,該目錄下的文件會映射至應用的根路徑 /
下,像 robots.txt
或 sitemap.xml
這種類型的文件就很適合放到 static
目錄中。
你可以在代碼中使用根路徑 /
結合資源相對路徑來引用靜態資源:
<!-- 引用 static 目錄下的圖片 --> <img src="/my-image.png"/> <!-- 引用 assets 目錄下經過 webpack 構建處理后的圖片 --> <img src="~/assets/my-image-2.png"/>
插件
https://zh.nuxtjs.org/guide/plugins
Nuxt.js允許您在運行Vue.js應用程序之前執行js插件。這在您需要使用自己的庫或第三方模塊時特別有用。
使用第三方模塊
我們可以在應用中使用第三方模塊,一個典型的例子是在客戶端和服務端使用 axios 做 HTTP 請求。略
使用 Vue 插件
假如我們想使用 vue-notifications 顯示應用的通知信息,我們需要在程序運行前配置好這個插件。
安裝:npm install --save vue-notification
首先增加文件 plugins/vue-notifications.js
:
import Vue from 'vue' import VueNotifications from 'vue-notification' Vue.use(VueNotifications)
然后, 在 nuxt.config.js
內配置 plugins
如下:
module.exports = { plugins: ['~/plugins/vue-notifications'] }
使用:
在vue文件中:
<notifications group="foo" />
this.$notify({ group: 'foo', title: 'Important message', text: 'Hello user! This is a notification!' });
效果:
ES6 插件
如果插件位於node_modules
並導出模塊,需要將其添加到transpile
構建選項:
module.exports = { build: { transpile: ['vue-notifications'] } }
注入 $root 和 context
有時您希望在整個應用程序中使用某個函數或屬性值,此時,你需要將它們注入到Vue實例(客戶端),context(服務器端)甚至 store(Vuex)。按照慣例,新增的屬性或方法名使用$
作為前綴。
注入 Vue 實例
plugins/vue-inject.js
:
import Vue from 'vue'
Vue.prototype.$myInjectedFunction = string => console.log('This is an example', string)
nuxt.config.js
:
export default { plugins: ['~/plugins/vue-inject.js'] }
這樣,您就可以在所有Vue組件中使用該函數。
這樣,您就可以在所有Vue組件中使用該函數。
export default { mounted () { this.$myInjectedFunction('test') } }
注入 context
context注入方式和在其它vue應用程序中注入類似。
plugins/ctx-inject.js
:
export default ({ app }, inject) => { // Set the function directly on the context.app object app.myInjectedFunction = string => console.log('Okay, another function', string) }
nuxt.config.js
:
export default { plugins: ['~/plugins/ctx-inject.js'] }
現在,只要您獲得context,你就可以使用該函數(例如在asyncData
和fetch
中)。 ctx-example-component.vue
:
export default { asyncData (context) { context.app.myInjectedFunction('ctx!') } }
同時注入
如果您需要同時在context
,Vue
實例,甚至Vuex
中同時注入,您可以使用inject
方法,它是plugin導出函數的第二個參數。 將內容注入Vue實例的方式與在Vue應用程序中進行注入類似。系統會自動將$
添加到方法名的前面。
plugins/combined-inject.js
:
export default ({ app }, inject) => { inject('myInjectedFunction', string => console.log('That was easy!', string)) }
nuxt.config.js
:
export default { plugins: ['~/plugins/combined-inject.js'] }
現在您就可以在context
,或者Vue
實例中的this
,或者Vuex
的actions/mutations
方法中的this
來調用myInjectedFunction
方法。 ctx-example-component.vue
:
export default { mounted () { this.$myInjectedFunction('works in mounted') }, asyncData (context) { context.app.$myInjectedFunction('works with context') } }
store/index.js
:
export const state = () => ({ someValue: '' }) export const mutations = { changeSomeValue (state, newValue) { this.$myInjectedFunction('accessible in mutations') state.someValue = newValue } } export const actions = { setSomeValueToWhatever ({ commit }) { this.$myInjectedFunction('accessible in actions') const newValue = 'whatever' commit('changeSomeValue', newValue) } }
只在客戶端使用的插件
不支持ssr的系統,插件只在瀏覽器里使用,這種情況下下,你可以用 ssr: false
,使得插件只會在客戶端運行。
舉個例子:
nuxt.config.js
:
module.exports = { plugins: [ { src: '~/plugins/vue-notifications', ssr: false } ] }
plugins/vue-notifications.js
:
import Vue from 'vue' import VueNotifications from 'vue-notification' Vue.use(VueNotifications)
例子:
nuxt.config.js
:
export default { plugins: [ { src: '~/plugins/both-sides.js' }, { src: '~/plugins/client-only.js', mode: 'client' }, { src: '~/plugins/server-only.js', mode: 'server' } ] }
傳統命名插件
如果假設插件僅在 客戶端 或 服務器端 運行,則 .client.js
或 .server.js
可以作為插件文件的擴展名應用,該文件將自動包含在相應客戶端或者服務端上。
例子:
nuxt.config.js
:
export default { plugins: [ '~/plugins/foo.client.js', // only in client side '~/plugins/bar.server.js', // only in server side '~/plugins/baz.js' // both client & server ] }
模塊
https://zh.nuxtjs.org/guide/modules
模塊是Nuxt.js擴展,可以擴展其核心功能並添加無限的集成。
模塊列表: https://github.com/topics/nuxt-module
有興趣可以看一下,比較深奧,不適合初級開發者
Vuex 狀態樹
對於每個大項目來說,使用狀態樹 (store) 管理狀態 (state) 十分有必要。這就是為什么 Nuxt.js 內核實現了 Vuex。
普通方式
Nuxt.js允許您擁有一個
store
目錄,其中包含與模塊對應的每個文件。
首先,只需將狀態導出為 函數,將變量和操作作為 store/index.js
中的對象導出:
export const state = () => ({ counter: 0 }) export const mutations = { increment (state) { state.counter++ } }
然后,您可以擁有 store/todos.js
文件:
export const state = () => ({ list: [] }) export const mutations = { add (state, text) { state.list.push({ text, done: false }) }, remove (state, { todo }) { state.list.splice(state.list.indexOf(todo), 1) }, toggle (state, todo) { todo.done = !todo.done } }
Vuex將如下創建:
new Vuex.Store({ state: () => ({ counter: 0 }), mutations: { increment (state) { state.counter++ } }, modules: { todos: { namespaced: true, state: () => ({ list: [] }), mutations: { add (state, { text }) { state.list.push({ text, done: false }) }, remove (state, { todo }) { state.list.splice(state.list.indexOf(todo), 1) }, toggle (state, { todo }) { todo.done = !todo.done } } } } })
在您的 pages/todos.vue
中,使用 todos
模塊:
。