創建nuxt項目


英文官網地址: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:資源目錄:放置用於組織未編譯的靜態資源如 LESSSASS 或 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,你就可以使用該函數(例如在asyncDatafetch中)。 ctx-example-component.vue:

export default {
  asyncData (context) {
    context.app.myInjectedFunction('ctx!')
  }
}

同時注入

如果您需要同時在contextVue實例,甚至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,或者Vuexactions/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 模塊:

 

 

 
        

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM