[vue] vue服務端渲染nuxt.js
- 2019 年 10 月 3 日
- 筆記
初始化
使用腳手架工具 create-nuxt-app 快速創建
npx create-nuxt-app <項目名> npx create-nuxt-app <项目名>
執行一些選擇
- 在集成的伺服器端框架之間進行選擇:
- 選擇您喜歡的 UI 框架:
- 選擇您喜歡的測試框架:
- 選擇你想要的 Nuxt 模式 (Universal or SPA)
- 添加 axios module 以輕鬆地將 HTTP 請求發送到您的應用程式中。
- 添加 EsLint 以在保存時程式碼規範和錯誤檢查您的程式碼。
- 添加 Prettier 以在保存時格式化/美化您的程式碼。
Nuxt.js 特點
- 基於 Vue.js
- 自動程式碼分層
- 服務端渲染
- 強大的路由功能,支援非同步數據
- 靜態文件服務
- ES6/ES7 語法支援
- 打包和壓縮 JS 和 CSS
- HTML 頭部標籤管理
- 本地開發支援熱載入
- 集成 ESLint
- 支援各種樣式預處理器: SASS、LESS、 Stylus 等等
基本 nuxt 配置
修改 pages/index.vue
<h1 class="title">Hello world</h1> 在 localhost:3000 可以看到更新效果
Nuxt 目錄結構
|-- .nuxt // Nuxt自動生成,臨時的用於編輯的文件,build |-- assets // 用於組織未編譯的靜態資源入LESS、SASS 或 JavaScript |-- components // 用於自己編寫的Vue組件,比如滾動組件,日曆組件,分頁組件 |-- layouts // 布局目錄,用於組織應用的布局組件,不可更改。 |-- middleware // 用於存放中間件 |-- pages // 用於存放寫的頁面,我們主要的工作區域 |-- plugins // 用於存放JavaScript插件的地方 |-- static // 用於存放靜態資源文件,比如圖片 |-- store // 用於組織應用的Vuex 狀態管理。 |-- .editorconfig // 開發工具格式配置 |-- .eslintrc.js // ESLint的配置文件,用於檢查程式碼格式 |-- .gitignore // 配置git不上傳的文件 |-- nuxt.config.json // 用於組織Nuxt.js應用的個性化配置,已覆蓋默認配置 |-- package-lock.json // npm自動生成,用於幫助package的統一性設置的,yarn也有相同的操作 |-- package-lock.json // npm自動生成,用於幫助package的統一性設置的,yarn也有相同的操作 |-- package.json // npm包管理配置文件 | 別名 | 目錄 |
|---|---|
| ~ 或 @ | srcDir |
| ~~ 或 @@ | rootDir |
在您的 vue 模板中, 如果你需要引入 assets 或者 static 目錄, 使用 ~/assets/your_image.png 和 ~/static/your_image.png 方式。
配置 IP 和埠
在根目錄下的 package.json 里對 config 項進行配置
"config":{ "nuxt":{ "host":"127.0.0.1", "port":"1818" } }, 配置全局 css
定義一個全局的 CSS 來初始化我們的頁面渲染,這裡使用 normailze.css。
新建 assets/css/normalize.css
修改 nuxt.config.js
css: ["element-ui/lib/theme-chalk/index.css", "~assets/css/normailze.css"], 修改 webpack 配置
在 nuxt.config.js 中可以對 webpack 配置進行覆蓋
build: { loaders:[ { test:/.(png|jpe?g|gif|svg)$/, loader:"url-loader", query:{ limit:10000, name:'img/[name].[hash].[ext]' } } ], /* ** Run ESLint on save */ extend (config, { isDev, isClient }) { if (isDev && isClient) { config.module.rules.push({ enforce: 'pre', test: /.(js|vue)$/, loader: 'eslint-loader', exclude: /(node_modules)/ }) } } } 寫一個 demo
編寫一個測試 demo (找個網站抄抄),來看看基本流程
npm install iview --save 或 vue add iview (需要vue-cli支援) 引入並配置 iview
想要加入其它的配置,可以在 nuxt.config.js 的 plugins 配置項中加入,同時在 plugins 文件夾下加入引入邏輯。例如:
nuxt.config.js
{src: '~plugins/iview', ssr: true} 同時新建 plugins/iview.js
import Vue from 'vue' import iView from 'iview' Vue.use(iView) import 'iview/dist/styles/iview.css' 修改默認布局
可通過添加 layouts/default.vue 文件來擴展應用的默認布局
<template> <div class="layout"> ...... </div> </template> 傳統的 spa 使用的
,但在 nuxtjs 中使用 組件顯示頁面的主體內容.created 和 data 中的邏輯,是在服務端載入時處理的,並不是瀏覽器端,瀏覽器端的邏輯比如 window 或 location 等對象要在 mounted 中寫,否則會報錯.head 中定義一些元數據,這些元數據會被爬蟲抓取到,可以在每一個頁面中自定義.
添加靜態資源
網上隨便下張圖片,然後新建 pages/index
<template> <div class="container"> <div> <Card v-for="i in 5" :key="i" :style="{width:'100%',marginBottom:'15px'}"> <div style="text-align:center"> <img src="~/static/image/cat.jpg" height="300px" /> <h3>A high quality UI Toolkit based on Vue.js</h3> </div> </Card> </div> </div> </template> @和~都可以用來引入圖片
nuxt 的路由使用
nuxt 中的基礎路由是根據 pages 的目錄結構來生成的.例如 pages/index.vue 就是{name:'index',path:'/',component:'pages/index.vue'}, 同理 pages/books/index.vue 就是{name:'books',path:'/books',component:'pages/books/index.vue'}
修改 layout/default.vue
<Menu mode="horizontal" theme="dark" active-name="1"> <div class="layout-logo"></div> <div class="layout-nav"> <MenuItem name="1"> <Icon type="ios-navigate"></Icon> <nuxt-link to="/">首頁</nuxt-link> </MenuItem> <MenuItem name="2"> <Icon type="ios-keypad"></Icon>發現 </MenuItem> <MenuItem name="3"> <nuxt-link to="/books">小書</nuxt-link> </MenuItem> </div> </Menu> Nuxt.js 推薦nuxt-link標籤來構建路由體系
asyncData 方法獲取數據
使用 asyncData 的方法,使得我們可以在設置組件的數據之前能非同步獲取或處理數據。asyncData 方法會在組件(限於頁面組件)每次載入之前被調用。它可以在服務端或路由更新之前被調用。 在這個方法被調用的時候,第一個參數被設定為當前頁面的上下文對象,你可以利用 asyncData 方法來獲取數據,Nuxt.js 會將 asyncData 返回的數據融合組件 data 方法返回的數據一併返回給當前組件。由於 asyncData 方法是在組件 初始化 前被調用的,所以在方法內是沒有辦法通過 this 來引用組件的實例對象。
npm install axios --save 在http://myjson.com/上創建假偽數據
{ "data": [ { "name": "Cesium基礎功能-鷹眼地圖。附帶源碼下載" }, { "name": "iOS開發簡記(7):網路請求模組" }, { "name": "iOS開發簡記(7):網路請求模組" }, { "name": "(難度Hard) Problem 132. Palindrome Partitioning II(迴文串拆分II)" }, { "name": "iOS 13適配問題" }, { "name": "Cesium基礎功能-氣泡彈窗。附帶源碼下載" }, { "name": "重學Android:是讓人耳目一新的 Jetpack MVVM 精講啊!" }, { "name": "iOS開發簡記(6):storyboard的使用" }, { "name": "最熟悉的陌生人:5 分鐘快速理解 HTTP2" } ] } 複製粘貼,點擊保存,獲取地址https://api.myjson.com/bins/f1bdx
新建 pages/index.vue
<template> <div class="container"> <div> <Card v-for="(item,index) in books" :key="index" :style="{width:'100%',marginBottom:'15px'}"> <div style="text-align:center"> <img src="~/static/image/cat.jpg" height="300px" /> <h3>{{ item.name }}</h3> </div> </Card> </div> </div> </template> <script> import axios from 'axios' export default { async asyncData(){ let {data}=await axios.get('https://api.myjson.com/bins/f1bdx') return {info: data} } } </script> Nuxt 頁面 meta 設置
Nuxt.js 為頁面提供的特殊配置項。其中 head 配置當前頁面的 Meta 標籤, 詳情參考 頁面頭部配置 API。
head: { title: '一本書 - 首頁', meta: [ { hid: 'description', name: 'description', content: 'website description' }, { name: 'keywords', content: '一本書,碼農,技術,vue,node,nuxt,前端' } ] }, 打開網頁->刷新->右鍵查看,效果就顯示出來了,這也是 nuxt 的一大優點
添加頁面切換特效
全局動畫默認使用 page 來進行設置,例如現在我們為每個頁面都設置一個進入和退出時的漸隱漸現的效果。我們可以先在根目錄的 assets/css 下建立一個 main.css 文件。
.page-enter-active, .page-leave-active { transition: opacity 2s; } .page-enter, .page-leave-active { opacity: 0; } 然後在 nuxt.config.js 里加入一個全局的 css 文件就可以了。
css:['assets/css/main.css'], 目前官方設定nuxt-link組件製作跳轉鏈接才有動畫
製作一個詳情頁
修改 pages/books/index.vue
<Row type="flex" gutter="10" justify="start" class="code-row-bg"> <Col v-for="i in 10" :key="i" span="6"> <Card style="width:100%"> <nuxt-link :to="'/books/'+i"> <div style="text-align:center"> <img style="width:100%" src="https://img3.doubanio.com/view/subject/m/public/s6974202.jpg" /> <h3>史蒂夫·喬布斯傳</h3> </div> </nuxt-link> </Card> </Col> </Row> 在 Nuxt.js 裡面定義帶參數的動態路由,需要創建對應的以下劃線作為前綴的 Vue 文件 或 目錄。也就是要麼創建_id.vue,要麼創建_id/index.vue
新建 pages/books/_id.vue
<template> <div> <Card style="width:100%"> <div style="text-align:center"> <img style="width:100%" src="https://img3.doubanio.com/view/subject/m/public/s6974202.jpg" /> <h3>史蒂夫·喬布斯傳</h3> <p>當前id : {{ id }}</p> </div> </Card> </div> </template> <script> export default { validate({ params }) { return /^[0-9]+$/.test(params.id) }, data() { return { id: this.$route.params.id } }, head() { return { title: '史蒂夫·喬布斯傳', meta: [{ hid: 'description', name: 'books', content: '史蒂夫·喬布斯傳' }] } } } </script> 給整個網站添加 head
Nuxt.js 允許你在 nuxt.config.js 里定義應用所需的所有默認 meta 標籤,在 head 欄位里配置就可以了
新建 root/app.html
<!DOCTYPE html> <html lang="en"> <head> {{ HEAD }} </head> <body> {{ APP }} </body> </html> nuxt 實際上已經將開發的一些需求都準備好了,使用 nuxt 進行 vue 服務端渲染能夠極大的提高開發效率
最後打包
靜態應用部署
npm run generate 參考