最近在開發 element3 的時候,遇到了一個問題,打包後的代碼會報錯,和在 dev 壞境下的代碼行爲不一致。前端
調研後發現這個問題可能小夥伴們都會遇到 !! 因此趕忙寫了篇文章記錄下來,讓你們少掉一點頭髮vue
element3 社區羣有小夥伴反饋了一個問題:git
組件 Tab 在 dev 壞境下邏輯一切正常,可是在 prod 壞境下就報錯了github
潛意識裏面發現這個問題沒那麼簡單,由於以前也有小夥伴說在 prod 壞境下某些組件報錯api
趕忙要到 demo,先跑了 dev 環境。嗯,沒啥問題markdown
而後又跑了 prod 壞境。 嗯,果真出現問題了數據結構
ok, 出現問題就好辦了,接着查看了一下報錯信息ide
發如今 prod 壞境下 ctx 這個對象的數據結構發生改變了oop
這是在 dev 壞境下:spa
這是在 prod 壞境下:
好,問題咱們已經定位好了,其實問題就已經解決了一半了
那咱們剩下的其實只須要弄明白兩個點
咱們先來看看如何繞過這個問題
先找到問題代碼,在 element3/Tabs.vue 這個組件內
這裏的邏輯就是經過 provide 給全部子組件提供當前組件的實例對象
可是問題就發生在這裏,咱們經過上面的案例已經知道,組件實例對象在 dev 和 prod 壞境下 ctx 對象的數據結構是不一致的。
而後看一下在哪裏使用的,找到 element3/TabPane.vue 這個組件內
這個代碼寫的真的是醜呀,這也正是我要重寫全部組件的緣由所在!
那咱們怎麼繞過這個問題呢? 咱們已知組件實例對象的 ctx 是會變的,那麼咱們能不能在 Tab 組件中只提供 TabPane 中用到的數據呢?咱們只要不用到 ctx 是否是就 ok 了
來 咱們先來試一試
稍微統計了一下會涉及到如下幾個數據
那咱們回到 Tab 組件中只提供 TabPane 用到的數據吧
回來 TabPane 改下使用方式
這樣咱們就繞過了 ctx 的使用
好,問題修完了 咱們打個包 驗證一下 有沒有問題吧
打包成功,接着把生成的文件放到報錯的 demo 裏面執行一下
先驗證 dev 壞境
控制檯安安靜靜 ,不錯不錯
在看看 prod 壞境
歐耶,完美解決
好 問題雖然解決了,可是還不能停,咱們還要深刻探索一下 vue3 的源碼,搞懂兩個問題
要想知道這個問題,其實只要找到生成 ctx 的代碼邏輯就能夠了
很簡單的邏輯,就是判斷是否爲 dev 壞境,而後作邏輯處理
基於源碼裏面的註釋咱們也已經瞭解到了
這個 ctx 就是爲了便於在開發模式下經過控制檯檢查
而到了 prod 模式下,它就會變成一個空對象了
而在 vue 中定義 ctx 的註釋中瞭解到,這個是公共實例的代理 target,而且還包含了一些經過 options 注入的屬性以及用戶自定義的屬性
那咱們就驗證一下用 options api 寫的時候它是什麼樣子的
dev 環境下的輸出結果
prod 壞境下的輸出結果
果真 vue 把咱們在 methods 中聲明好的方法掛載到了 ctx 上,因此咱們訪問起來仍是沒有問題的
可是沒有看到 count,盲猜的話應該是在對應的 proxy handler 內處理的
其實到這裏我又產生了一個問題,就是 vue 裏面是怎麼處理的這個邏輯。
這個問題就留着下回在講吧~ 怕大家太長不看
so,咱們如今就已經得出了一個結論:
在之後的開發中千萬不要在 setup 中調用 getCurrentInstance().ctx 來獲取組件內部數據
最後來總結一下,咱們從問題出發,發現問題,定位問題,解決問題,最後深刻問題。
而且最終獲得告終論:在 setup 中不能夠調用 getCurrentInstance().ctx 來獲取組件內部數據,由於在 prod 會被幹掉
你學到了嗎?
若是這篇文章你有所獲的話,請幫我點個贊