不會 webpack 還想學 vue 工程化開發 的福音
熟悉jQuery開發的,學習vue的簡單使用是沒用啥問題的,但是學習vue的工程化開發方式,往往會遇到各種問題,比如:
webpack、node、npm、cnpm、yarn、腳手架、開發環境、測試環境、生產環境、各種安裝、各種建立。
好在 vue3 不容易報錯了,想當初 vue2.x 的時候各種報錯,看到錯誤就只能乾瞪眼,這都是啥?好像是webpack的報錯。
當初學 vue2 就卡在了建立專案上,各種嘗試居然一個專案都沒跑起來。
如果能像jQuery那樣,直接開魯那多好呀!
各種陰差陽錯+機緣巧合的情況下,弄出來了這種在 CND 模式下仿工程化開發的方式。一開始只是想方便我做線上演示,後來各種完善,發現還是應該有點搞頭了。再加上大神在弄vite,似乎也是對webpack比較頭疼。。。
好了不墨跡了,開始說我的做法。
vue全家桶和UI庫的載入方式
這個很傳統了,官方也支援。
<script src="https://unpkg.com/vue@3.0.5/dist/vue.global.js"></script>
<script src="https://unpkg.com/vue-router@4.0.3/dist/vue-router.global.js"></script>
<script src="https://unpkg.com/vuex@4.0.0-rc.2/dist/vuex.global.js"></script>
<link href="https://unpkg.com/element-plus@1.0.2-beta.30/lib/theme-chalk/index.css" rel="stylesheet">
<script src="https://unpkg.com/element-plus@1.0.2-beta.30/lib/index.full.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
瀏覽器會對js檔案做快取,第一次有點慢,後快取後就快了。
某網站有時候會卡一下,不卡的話還是很快的。
js程式碼的載入方式
<script type="module" src="src/main.js?v=4"></script>
聽說vite也是這麼載入的。好吧就是從vite建立的專案裡copy來的。
要加上 type="module" 否則載入不了。
資料夾結構和程式碼編寫風格
資料夾當然是把工程化的拿過來之間用了,挺簡潔明瞭的。
因為瀏覽器也支援 import 的方式載入js,那麼也就是說,CDN方式下也可以用import載入。那麼js程式碼方面也不會有太大的差別。
我們來對比一下:
左面是CND的專案,右面是工程化的專案。
- 資料夾結構完全一致,
- js檔案都能對應上
- vue檔案拆分成 html + js 兩個檔案(app.vue除外)
main.js
/*
import store from './store/index.js?v=1'
import router from './router/index.js?v=1'
import App from './app.js?v=1'
// 建立vue3的例項
const app = Vue.createApp(App)
.use(store)
.use(router)
.use(ElementPlus)
.mount('#app')
*/
const ver = window.__ver || ''
Promise.all([
import('./store/index.js' + ver),
import('./router/index.js' + ver),
import('./app.js' + ver),
]).then((res) => {
// 建立vue3的例項
const app = Vue.createApp(res[2].default)
.use(res[0].default) // 掛載vuex
.use(res[1].default) // 掛載路由
.use(ElementPlus) // 載入ElementPlus
.mount('#app') // 掛載Vue的app例項
})
註釋掉的程式碼,和工程化裡的程式碼是一致的,只是這種方式只支援常量,所以想把版本加在url地址上面就比較麻煩。
所以改為了這種非同步的方式,這樣可以把版本號給拼接上去。這樣更新瀏覽器的js快取就方便多了。
app.js
export default {
name: 'app',
setup() {
do something...
return {
}
}
}
工程化專案裡面是App.vue,對應的是網頁裡 id=“app” 的div。
這裡改成純js檔案的形式,因為模板就是index.html的div。
好吧,其實是main.js裡面的載入方式不知道要怎麼改。。。
router
const routes = [
{
path: '/',
name: 'Home',
component: () => myImport('views/home')
},
{
path: '/About',
name: 'About',
component: () => myImport('views/About')
},
{
path: '/component',
name: 'component',
component: () => myImport('views/component')
},
{
path: '/store',
name: 'store',
component: () => myImport('views/store')
}
]
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes
})
export default router
-
動態路由
這裡採用動態路由的方式,另外換成了我自己封裝的函式,可以載入html和js檔案,然後變成動態元件的方式,這樣元件就可以被路由載入了。 -
路徑設定問題
本來想把html和js檔案放在一個資料夾裡面,就可以用同一個url載入了,結果和我想的不一樣。
由於載入 html 和載入 js 的路徑規則不太一樣,再加上路由導航的原因,
所以只好用 src 作為分隔標識,統一從src開始計算路徑。
myImport
// 直接放在Window裡面好了。。。
window.myImport = (url) => {
return new Promise((resolve, reject) => {
const ver = window.__ver || ''
const baseUrl = window.__basrUrl || '/src/'
// 先載入js
import(baseUrl + url + '.js' + ver).then((resjs) => {
const js = resjs.default
if (js.template === '') {
// 如果模板是空的,表示需要載入html作為模板
axios.get(baseUrl + url + '.html' + ver).then((resHTML) => {
js.template = resHTML.data
resolve(js)
})
} else {
// 否則直接使用js註冊元件
resolve(js)
}
})
})
}
一開始還想做個外掛掛到vue上面,後來試了半天沒成功。
然後覺得自己挺傻的,cnd環境,一個靜態函式,直接掛在Window上面不就行了嗎。
-
載入 js 和 html
先用 import 非同步載入 js,目的是便於拼接url,然後判斷是否有template。
如果有的話,就不載入html了。
如果沒有的話,在用axios載入html,然後設定給template,這樣就變成了一個標準的js元件。 -
是否會重複載入?
元件自帶快取機制,第一次會載入,以後就不會重複載入了。
store
import { Set_Count } from './mutation-types.js'
export default Vuex.createStore({
state: {
count: 0,
myObject: {
time: '現在的時間:'
},
myArray: [1,2,2,3,4]
},
getters: {
getAddCount: (state) => {
return state.count + 1
}
},
mutations: {
// 計數器
setCount(state, num = 1) {
state.count += num
},
[Set_Count](state, num = 1) {
state.count += num
}
},
actions: {
},
modules: {
}
})
基本上沒啥區別。
如何方便的寫模板
直接看圖,更清晰一些。
一邊寫js程式碼,另一邊寫模板。這樣也是很方便的。
一開始想在瀏覽器裡面直接載入vue檔案,然後處理成js元件。
想了半天,理論上應該可以,但是我這水平估計夠嗆,所以採用了這種折中的方式。
元件裡面載入元件
- defineAsyncComponent
這個是Vue提供的非同步元件,如果在工程化裡面,可以直接載入vue檔案。
我在cnd裡面試了一下,沒成功。所以只好用純js元件的方式。
動態路由不需要套這個,但是非同步元件就要套上,否則沒有效果。
搭一個梯子
這樣做專案和 jQuery 的風格挺像的,檔案copy過來,建立個網站就可以開魯了。
同時程式碼編寫方式又採用工程化的方式,熟悉之後可以方便的切換的工程化的開發方式。
就好像在 jQuery 與 vue 的工程化直接搭了一個梯子,應該大概可以方便我們翻過去吧。
便於除錯
-
設定斷點看狀態。
-
看成員
-
進到內部了,好吧其實我都看不懂。。。
js檔案的快取問題
快取是個好東東,避免我們重複載入js檔案,加快頁面顯示速度,但是如果我們的js改了,瀏覽器卻還是在用快取怎麼辦?
我們可以設定一個版本號,載入檔案後面就可以。當更新的時候,改一下版本號,就可以重新載入了。
原始碼
https://github.com/naturefwvue/nf-vue-cnd/tree/main/cnd/project-template
線上演示
https://naturefwvue.github.io/nf-vue-cnd/cnd/project-template/
一開始可能會有的卡,第一次點導航會載入檔案,所以會慢一點,以後就好了。好像應該加一個載入中的狀態。