vue項目與nuxt.js實在有着太多的不同,例如項目結構變化很大,router.js沒了,vuex store寫法有變化,router鈎子沒了等等。老項目畢竟也有一些體量,這么折騰我可接受不了,不過經過一番調查,我發現這些問題不是不可以解決。因此雖然遷移是要遷移的,但是要盡量保持vue-cli 3項目的風味,以最小的改動完成遷移。為此我做了很多調查,本文的目的就在於此。
1、重建項目
沒啥可說的,直接掏出命令行開始吧,npx create-nuxt-app my-project
,這是官網get started文檔的操作。
我們的原則是盡量和vue cli3項目一致。選項基本上選默認,除了eslint打開。值得注意的是有個axios module,這就是個this.$axios插件,我個人目前認為沒啥用,也不影響一般的axios使用方式。
2、eslint配置、及三方依賴插件安裝
把.eslintrc.js對照着修改一下,完了別忘記安裝包:npm install --save-dev @vue/eslint-config-standard
把依賴復制,安裝即可
3、重要的來了。值得注意的是nuxt默認的srcDir就是根路徑,所以我們只需要直接把之前項目的src里面的內容拷貝過來,放至根目錄,把原先的靜態文件拷貝過來放置static目錄。
4、最重要的是:使用代碼router,而不是nuxt自動生成的導航配置
nuxt.js一個很大不同是router.js沒了,按官方的說法是使用目錄自動動態生成router.js。我覺得其實還可以,但沒有必要那么精巧。老項目遷移,寫都寫了,直接拿過來就是。好在可以改,nuxt.js官方提供了一個插件:nuxt-community/router-module
將其加入項目:npm install --save @nuxtjs/router
然后修改配置文件:modules里面加入
modules: [ '@nuxtjs/router' ],
之前項目的router.js需要寫在 根目錄 / 下,需要略微改變寫法,導出為createRouter函數:
// 只需要加上這樣即可
export function createRouter () { const router = new Router({ mode: 'history', routes }) return router }
還有一個重要的是,需要移除所有異步加載
有可能你像我一樣碰到了這樣的報錯,然后一臉懵逼:render function or template not defined in component: anonymous
我排查了半天,發現是router.js中異步加載的鍋(當然前提是router.js按照上文移植過來了),所以直接改成引入即可
import guest from '@/views/carnival/guest' import partner from '@/views/carnival/partner'
5、Router全局鈎子
有兩種辦法,第一種是寫nuxt plugin直接拿router對象
export default ({ app }) => { app.router.beforeEach(async function (to, from, next) { } }
然后在nuxt.config.js配置里加上
plugins: [ '@/plugins/route' ],
但這種辦法如果在beforeEach里面做請求拿數據,就會引起DOM渲染不同步的警告(nuxt.js v2.3.4)。只要發出請求,不做任何其他事情,就會出錯(其實這是非常不科學的)。順便提一句,這里通過app.store可以拿到store
第二種辦法,也是nuxt.js官方推薦的辦法,是寫middleware:
我在middleware下寫一個router-guards.js
export default async function ({ store, route, redirect, req }) { console.log('hello') // let ret = await axios.get(`...`)
}