首先,給自己打打氣!
Let us not look back in anger, nor forward in fear, but around in awareness.
-- 不怒然回首,不恐懼前行,活著,就是現(xiàn)在。
補(bǔ)充一個(gè)關(guān)于腳手架的概念,引用自 編程中的腳手架是什么意思
這里是stackoverflow上的一個(gè)回答:
Scaffolding is a meta-programming method of building database-backed software applications. It is a technique supported by some model-view-controller frameworks, in which the programmer may write a specification that describes how the application database may be used. The compiler uses this specification to generate code that the application can use to create, read, update and delete database entries, effectively treating the template as a "scaffold" on which to build a more powerful application.
譯:“腳手架”是一種元編程的方法,用于構(gòu)建基于數(shù)據(jù)庫(kù)的應(yīng)用。許多MVC框架都有運(yùn)用這種思想。程序員編寫一份specification(規(guī)格說(shuō)明書),來(lái)描述怎樣去使用數(shù)據(jù)庫(kù);而由(腳手架的)編譯器來(lái)根據(jù)這份specification生成相應(yīng)的代碼,進(jìn)行增、刪、改、查數(shù)據(jù)庫(kù)的操作。我們把這種模式稱為"腳手架",在腳手架上面去更高效的建造出強(qiáng)大的應(yīng)用!
Nuxt 項(xiàng)目目錄結(jié)構(gòu)圖

1. main.css
使用 nuxt 要有意識(shí),很多文件需要去 nuxt.config.js 這里配置才能生效。這個(gè)是原 SPA 項(xiàng)目的全局樣式文件,遷移后是這樣引入的:
// nuxt.config.js
css: ['./assets/css/main.css'],
2. flexible.js
這是一個(gè)比較 simple 的 flexible 文件
// static/js/flexible.js
var rootResize = function() {
var baseFontSize = 20
var baseWidth = 5120
var minWidth = 1920
var clientWidth = document.documentElement.clientWidth || window.innerWidth
var innerWidth = Math.max(Math.min(clientWidth, baseWidth), minWidth)
var rem = clientWidth / (baseWidth / baseFontSize)
if (innerWidth == 5120 || innerWidth == 1920) {
rem = innerWidth / (baseWidth / baseFontSize)
}
document.querySelector('html').style.fontSize = rem + 'px'
}
rootResize()
window.onresize = function() {
rootResize()
}
巨坑,我原本把 flexible 文件當(dāng)做 plugin 引入了,如下,這是一個(gè)錯(cuò)誤示范:
// nuxt.config.js
plugins: [
{
src: '@/static/js/flexible.js', ssr: false
}
],
這里的 ssr 一定要設(shè)置為 false, 否則會(huì)報(bào)一個(gè)叫 document is not defined 的錯(cuò)。倒也不是不可以生效,不過(guò)它是有一個(gè)延遲生效的問(wèn)題。
?。?!最優(yōu)解決方案是,添加 head 配置:
// nuxt.config.js
head: {
// title, meta, link etc.
script: [{ src: '/js/flexible.js', type: 'text/javascript', charset: 'utf-8' }]
},
劃重點(diǎn),重點(diǎn),重點(diǎn)?。?!這里的 src 路徑一定要寫 static 下面的絕對(duì)路徑就好,也就是 /js/flexible.js but not /static/js/flexible.js
3. axios
nuxt 自帶 axios "@nuxtjs/axios"
添加配置:
// nuxt.config.js
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios',
],
axios: {
proxy: true,
prefix: '/api/',
credentials: true
},
proxy: {
'/api/': {
target: 'http://my-api/',
pathRewrite: {
'^/api/': '/',
changeOrigin: true
}
}
},
以上配置都是針對(duì) vue 文件的,所以在 vue 組件中可以使用 this.$axios 來(lái)調(diào)用。
- 組件文件中使用:
// *.vue
this.$axios.get('/getInfo').then((res)=>{
console.log(res)
})
- stats.js 等其他文件中使用:
// middleware/stats.js
import axios from 'axios'
export default function({ route }) {
return axios.post('http://my-stats-api.com', {
params,
})
}
4. eventBus
// plugins/bus-inject.js
import Vue from 'vue'
export default (ctx, inject) => {
const bus = new Vue()
inject('bus', bus)
}
組件中觸發(fā)事件:
// app.vue
this.$axios
.get('/getData')
.then(response => {
let res = response.data || {}
this.$bus.$emit('data', res)
})
.catch(error => {
console.log(error)
})
組件中接收事件:
// sub.vue
this.$bus.$on('data', (res)=>{
console.log(res)
})
5. wordcloud echarts の詞云
// plugins/echarts.js
import Vue from 'vue'
import echarts from 'echarts'
import wordCloud from 'echarts-wordcloud'
Vue.prototype.$echarts = echarts
Vue.prototype.$echarts.wordCloud = wordCloud
// nuxt.config.js
plugins: [
...
{ src: '@/plugins/echarts', ssr: false }
...
],
同樣,ssr: false 一定要寫,否則會(huì)報(bào) error: window is not defined
6. 本機(jī) ip 訪問(wèn)替代 localhost
// package.json
"config": {
"nuxt": {
"host": "0.0.0.0",
"port": 3000
}
}
7. BMap api 百度 Map 的 api key
// nuxt.config.js
head:{
// title, meta, link etc.
script: [
...
{
src:
'http://api.map.baidu.com/api?v=2.0&ak=key...'
}
...
]
}
8. iframe 的問(wèn)題
這個(gè)坑是很奇怪的,在 SPA 模式開發(fā)一個(gè)項(xiàng)目,我會(huì)把寫好的頁(yè)面以 iframe 的形式串聯(lián)到一起,and by then it worked well. 可是到了 SSR 莫名其妙的出現(xiàn)了類似線程阻塞的問(wèn)題,倒是不需要糾結(jié),只要改成組件引入即可。
出現(xiàn)這個(gè)問(wèn)題的原因應(yīng)該是,如果是 iframe 的方式引入,首先需要這個(gè)頁(yè)面已經(jīng)渲染完成,然后再通過(guò) iframe 引入。所以導(dǎo)致了阻塞問(wèn)題。
9. 打包與部署
9.1 本地打包
首先執(zhí)行打包命令:
yarn build
yarn build 之前需要將所有的 console.log 刪除或注釋,or else 有可能會(huì)報(bào) console 的錯(cuò)而導(dǎo)致打包失敗。
如果打包成功了,啟動(dòng)打包后的項(xiàng)目:
yarn start
本地啟動(dòng)沒(méi)有問(wèn)題就可以進(jìn)行下一步了。
9.2 服務(wù)器部署
9.2.1 服務(wù)器安裝 node.js,Linux 系統(tǒng)下安裝 node.js,請(qǐng)移步至https://segmentfault.com/a/1190000017866964
9.2.2 服務(wù)器創(chuàng)建并 cd 到目錄 local/deploy/front,將以下文件復(fù)制到該文件夾下:

然后執(zhí)行:
yarn install -production
成功后:

居然還沒(méi)結(jié)束,因?yàn)闆](méi)有啟用「進(jìn)程守衛(wèi)」
9.2.3 安裝 pm2
安裝 pm2 參考 https://www.cnblogs.com/minrh/p/9770890.html
然后 cd 到項(xiàng)目目錄下,執(zhí)行以下:
# yarn
pm2 start yarn --name "my-nuxt" -- start
# npm
pm2 start npm --name "my-nuxt" -- run start
*** 這里的 my-nuxt 是 package.json 里 name 的名稱。