記一次給 vue 3.x 搭建腳手架遇到的問題之組件編寫

勞動節就好好在家寫代碼了,畢竟咱們如今居家就是在爲國家作貢獻,並且勞動節不勞動和鹹魚有什麼區別,手動🐶保命。前端

前言

vue 3 剛出幾個月,如今是一步一個坑,可是坑仍是要填的,畢竟生活仍是要繼續的麼。vue

目前 vue 3.x 基本上是已經能夠工做了,剛出不久的那段時間還看👀到掘金上有人說生產上有 3.x ,對這種大佬只能佩服,畢竟新東西出來,光是想一想出了問題,這麼解決就是很是頭疼的事情python

好比我如今搭個腳手架基本就是一路爬過來的,還好目前還沒開始深刻開發,出的都是周邊配套和類型這些小問題。react

另外說和 react 很像的,我只能說,這不光是像,大家的代碼估計均可以拷過來改改就能用了呢,看下完整的函數式組件的代碼webpack

不過 vue 的雙向數據綁定用的很舒服,這個纔是最主要的,畢竟手寫 set 真的麻煩。git

讀書人的事情這麼能叫抄呢?這叫借鑑,這叫共同進步 --- by 魯迅github

不過這種事情其實說多了也沒意義,好比 python 和 js 或其餘語言之間,你敢說沒有互相借鑑。web

並且前端的口號不就是:「走別人的路,讓別人無路可走」,咱們要團結一致,畢竟前端這個崗位真的很容易被替代掉,咱們求發展,求穩定,技術人用實力說話,才能讓這個崗位越走越遠。vue-router

目前的腳手架的開發進度

基本上已經能夠支持你跑,可是打包工具還在糾結,我喜歡 rollupjs,可是項目已經引入了 webpack,到底要不要再引一個新的,還在思考中typescript

  • 支持 [typescript][typescript] 語法開發
  • 支持 [storybook][storybook] 構建 UI 組件
  • 支持 [lerna][lerna] 管理工程
  • 支持 [prettier][prettier] 格式化代碼
  • 支持 [typedoc][typedoc] 自動生成 api 文檔
  • 支持主題與組件分離
  • 支持使用 sass,採用 bem 的方式編寫樣式
  • 支持 rollup 或 webpack 構建工具打包

問題列表

問題一:選擇 vue 包

這個不算問題,主要是第一次爲了這麼選擇包而頭疼,之前寫 vue 組件,基本就是直接引入 vue 就好了,其餘交給構建工具處理。

可是看到 vue 3 支持模塊化了,就想着把 @vue/compiler-dom 做爲框架依賴引入,項目中引入 vue ,結果坑到了本身。

中間出現了一些很詭異的事情,因此我如今不論是項目仍是組件庫都直接引入的 vue@next,還有和 vue2 選擇主文件的問題,不過這個目前應該都明白應該這麼選擇了

問題二:初期使用障礙,類型定義的問題

這個目前比較頭大的時候,要麼變成 AnyScript,要麼別名一堆,雖然還有 js 可選,可是都有火了,爲何還要吃生的,不知道 0202 年開始禁野味了麼。

咱們在這裏舉個🌰,好比你的組件庫是這樣導出的

import type { App, Component, Plugin } from 'vue'

// Component 是一個複合類型,裏面已經有 函數組件的定義了, 照理說應該沒問題的
const Components: Component[] = [
  // Button 是一個純函數組件,可是在這裏就會出現簽名不一致的狀況
  Button as  Component
]

// app 不是之前的 Vue 類了
function install(app: App<any>) {
  Components.forEach(Component => {
    app.component(Component.name as string, Component)
  })
}

export default {
  version: process.env.VERSION || 'dev',
  install: install
// vue 沒有暴露 PluginInstallFunction 類型
// 只有 Plugin 類型,在定義類型的的時候就只能進行聯合聲明了
} as { version: string } & Plugin
複製代碼

看着沒有報錯,信心滿滿,而後代碼裏面你就很放心的開始用了

import VueUI from 'vue-next-ui'

const app = createApp(App)

app.use(VueUI)
複製代碼

然而實際是會告訴你類型有問題,就算你改爲這樣導出也沒用

export default {
  install(app: App<any>): void {
    Components.forEach(Component => {
      app.component(Component.name as string, Component)
    })
  }
} as Plugin
複製代碼

就算你直接改 d.ts 也沒用,可是 vue-router@next 就能夠,不明覺厲。

這裏想說的是,後面這樣不兼容的問題還有不少,多是多方緣由,但狀況就是這樣,因此後面有的忙了。

類型問題能夠參考下個人處理:

方式一:@ts-ignore 一把梭

@ts-ignore 一把梭只有對你的代碼很是自信才應該這樣作,通常推薦已經進行判斷以後,還存在類型簽名問題時使用。

方式二:顯示轉換

其實還可使用 anyany 大法是真好用,就和 eval 同樣,誰用誰知道

問題三:尤大大已經說過,vue 3 已經沒有任何類了

這個問題這麼說呢,大家看下這段代碼和 vue 2.x 比比

import { createApp, reactive, h } from 'vue'

import App from './App.vue'
import router from './router'

const store = reactive({
  // global state
})

const app = createApp({
  render() {
    // h 已是全局函數了
    return h(App)
  }
})

// 如今 config 在 app 上,意不意外
app.config.errorHandler = () => {}

// 常常往 Vue.prototype 掛東西的行爲能夠停停了
// 如今應該推薦這樣玩
app.provide('state', store)

// 全局組件註冊也在這裏
app.component('page', Page)

// 如今 router 是這樣用的
// 並且不須要再把 router 做爲參數丟進 app 中了
app.use(router)

// 之前全部帶 $ 符號的大部分都已經去除前綴了
app.mount('#app')
複製代碼

寫法自己沒大問題,可是想當於之前的 hack 手段,你們能夠停下了,由於沒有原型能夠給你們玩了,主要是習慣問題

基本上適應下就行了,惟一比較麻煩的是組件那塊。

問題三:jsx 和 render 的問題

ps: 模板不算哈,那個編譯支持的,我說的是手動寫的狀況下

1. 如今更新須要 flag 支持

在 babel 插件沒有跟上的狀況,寫的特別難受,由於 vue3 的響應式數據是須要 flag 支持的,也就是若是沒有 flag,那你的數據就是個純數據,沒有任何響應式變化。

要下面這樣寫,帶 flag 才行,這個值的說明,看直播的應該都瞭解過了。

之因此拿這個說明是由於寫通用組件的時候,這種手寫 render 的狀況其實挺多的,這樣對於開發者來講,不借助官方的插件,多是一個不小的挑戰

2. 子元素不支持數組了

另外不知道爲何不支持直接傳遞數組了,你若是傳遞就會給你提示

這個其實挺麻煩的,由於你須要包一層,下面的寫法才能夠

或者無聊翻人家 api,找一可能的掛上去,我就找到了 createSlots 的,但其實不用也能夠的,大家等官方出文檔再說吧。

不過比較好的是,終於有了 renderSlot 方法,不用再每次手動寫判斷了,👏👏🎉🎉

結束

其實還有周邊的問題,好比大家看到的 storybook 實際上是我把官方的下過來,直接改上去的,還好人家寫的比較好,否則又要頭疼了

另外類型其實還有包自己的問題,我已經提了一個了,可是仍是有好多,不過畢竟剛出,仍是能夠理解的,但願 vue 能越走越遠吧,畢竟不是全部人都能認同同一個框架的,只有適合的纔是好的。

最後獻上我未完成的腳手架地址:✈️飛機

相關文章
相關標籤/搜索