用 vuetify-loader 提升 Vue 开发体验

2021-09-14 14:50:01

vuetify-loader 不止用在vuetify,在其他vue工程中,一样好用

参考地址  用 vuetify-loader 提升 Vue 开发体验



好久沒寫文章,心血來潮發一篇

重點先放三遍

  • 不用 Vuetify 也可以用 vuetify-loader 哦

  • 不用 Vuetify 也可以用 vuetify-loader 哦

  • 不用 Vuetify 也可以用 vuetify-loader 哦

const vuetify = 'vue' + 'buetify'

現在已經有許多基於 Vue 的 UI 框架、元件庫都提供方便易用且客製化的方案,
從 Vuetify 的命名可以看到是為了美化 Vue 而存在,美化範圍不只限於 UI,也包含程式碼和開發體驗。

今天主要和大家分享 vuetify-loader 如何提升 SFC 開發體驗。

如果你也思考過以下問題,你可以考慮使用 vuetify-loader 來少寫一些程式碼。

  1. 你寫了很多共用的元件,且在專案中被頻繁地使用

  2. 該如何確保被棄用的元件,在建置時不會被打包

  3. 如何用命名規範來管理元件

重複且頻繁的在專案各處引入相同的元件

舉例來說,專案中有一個 BaseButton 這個基本的按鈕元件,當我在不同的元件中使用時會是這樣:

  • PageA.vue

<template>
    <base-button>Click me!</base-button>
</template>
import BaseButton from '@/components/BaseButton'
export default {
    components: {
        BaseButton
    }
}

這個作法很普通,但是當有十個頁面時就需要引入 10 次 BaseButton,並且加入到 components 物件中

隨著這樣的 UI 元件慢慢變多,一個頁面就需要引入一堆基礎元件,犧牲的就是前端工程師的開發體驗,下面舉個例:

  • PageB.vue

<template>
    <base-button>Click me!</base-button>
    <base-tooltip></base-tooltip>
    <base-input></base-input>
    <base-alert></base-alert>
    <base-container>
        <base-layout>
            <base-flex>
                ...
            </base-flex>
        </base-layout>
    </base-container>
</template>
import BaseButton from '@/components/BaseButton'
import BaseTooltip from '@/components/BaseTooltip'
import BaseInput from '@/components/BaseInput'
import BaseAlert from '@/components/BaseAlert'
import BaseContainer from '@/components/BaseContainer'
import BaseLayout from '@/components/BaseLayout'
import BaseFlex from '@/components/BaseFlex'

export default {
    components: {
        BaseButton,
        BaseTooltip,
        BaseInput,
        BaseAlert,
        BaseContainer,
        BaseLayout,
        BaseFlex
    }
}

同樣的道理,有十個以上的頁面,每個頁面都要引入這麼多基礎元件時,犧牲的就是前端工程師的開發體驗。

這也衍生一個問題,當我要移除 BaseButton 這個元件時,不只要移除在 template 中的

  • <base-button>Click me!</base-button>

同時也要移除 script 中的

  • import BaseButton from '@/components/BaseButton'

  • components: { BaseButton }

如果我忘了移除 js 中的引用,

此時專案若有使用 Eslint,他可能會好心的提醒你:

The "BaseButton" component has been registered but not used.eslint(vue/no-unused-components)

萬一不幸的事情發生了,我沒有使用 Eslint,又忘了移除 script 中的引用,就「可能」會在無形中增加了專案的 bundle size。

看到這裡有些人可能想到不錯的解決辦法

將共用元件註冊為全域元件,避免不斷重複引入元件

時常看到的解決範例:

  • main.js

import Vue from 'vue'
import BaseButton from '@/components/BaseButton'
import BaseTooltip from '@/components/BaseTooltip'
import BaseInput from '@/components/BaseInput'
import BaseAlert from '@/components/BaseAlert'
import BaseContainer from '@/components/BaseContainer'
import BaseLayout from '@/components/BaseLayout'
import BaseFlex from '@/components/BaseFlex'

Vue.component('BaseButton', BaseButton)
Vue.component('BaseTooltip', BaseTooltip)
Vue.component('BaseInput', BaseInput)
Vue.component('BaseAlert', BaseAlert)
Vue.component('BaseContainer', BaseContainer)
Vue.component('BaseLayout', BaseLayout)
Vue.component('BaseFlex', BaseFlex)

這方法相比在各處不斷地引用基礎元件有更好的開發體驗,也讓開發專案時可以更多的專注在商業邏輯上

但是這並沒有辦法主動避免棄用的元件在建置時不小心被打包的問題

如果 BaseButton 是一個被棄用的元件,我需要在專案中透過全域搜尋 BaseButton 或 base-button,確認沒有任何地方用到這個元件後,回到 main.js 移除以下兩行代碼:

import BaseButton from '@/components/BaseButton'
Vue.component('BaseButton', BaseButton)

同樣的問題是如果我忘了移除,那 BaseButton 元件就「肯定」會增加專案的 bundle size,並且不會有 Eslint 的提示。

那有沒有方法或工具能同時兼顧開發體驗、專注開發商業邏輯,又能避免棄用元件建置時被打包呢?

本文的重點 vuetify-loader

vuetify-loader 是一個 webpack 的套件,用於自動引用 Vuetify 的元件

可以參考 vuetify-loader 文件的 Automatic Imports

很少有 UI 框架自帶 tree shaking 功能的,這也是我喜歡 Vuetify 的原因之一

你可以在設置 webpack plugins new VuetifyLoaderPlugin 時,帶入 match 函式,
所有的元件中的每一個 tag 會執行一次 match 函式,參數有:

  • originalTag: tag 如何被使用的,例如 <base-button>Click me!</base-button> 就會是 base-button

  • kebabTag : 將 originalTag 轉為 kebab-case

  • camelTag : 將 originalTag 轉為 PascalCase

  • path : SFC 的相對路徑

  • component : 該 tag 所在的那個元件被解析後的物件,主要包含 SFC 的三個區塊 (template, script, style)

可以根據這些參數組合出適合專案的自動引入元件功能

match 需要回傳一個長度為 2 的陣列:

第一個元素會被插入在該元件的 components 屬性中

第二個元素為自動引用該元件的路徑

以下用 Vue CLI 3 建立的專案做為範例:

vue.config.js

const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin')

module.exports = {
  configureWebpack: {
    plugins: [
      new VuetifyLoaderPlugin({
        match (originalTag, { kebabTag, camelTag, path, component }) {
          if (kebabTag.startsWith('base-')) {
            return [camelTag, `import ${camelTag} from '@/components/${camelTag}.vue'`]
          }
        }
      })
    ]
  }
}

這邊解釋一下上面這段程式碼的效果
我用 BaseButton 做舉例:
如果在 PageA.vue 中使用

<template>
    <BaseButton>Click me!</BaseButton>
    或
    <base-button>Click me!</base-button>
</template>

在 script 中不必再寫:

import BaseButton from '@/components/BaseButton'
export default {
    components: {
        BaseButton
    }
}

在每一個元件中,若有 tag 的使用為 BaseButton 或 base-button 皆符合 kebabTag.startsWith('base-') 的這個條件。
此時回傳長度為 2 的陣列

return ['BaseButton', `import BaseButton from '@/components/BaseButton.vue'`]

vuetify-loader 接著自動在 PageA.vue 元件中,引用 BaseButton

當有天 BaseButton 被棄用時,我只需要直接移除 PageA 中的

<BaseButton>Click me!</BaseButton>

<base-button>Click me!</base-button>

我甚至不需要意識到 BaseButton 已經被棄用,也不會造成多餘的引入

因為刪掉 template 中的 tag,同時 vuetify-loader 也移除了對 BaseButton 元件的引入

注意:這個範例的 import 條件判斷只有以 PascalCase 方式命名,且放在 @/components/ 底下的元件才會被正確引入,當然你也可以寫適合自己專案的客製化條件

總結:

vuetify-loader 的 match 函式提供自動引入元件的功能,伴隨兩項優點:

  • 避免頻繁引入相同的基礎元件,使專案開發能專注在商業邏輯,並提升開發體驗

  • 避免棄用元件在建置時被打包

最後,很重要說三次

  • 不用 Vuetify 也可以用 vuetify-loader 哦

  • 不用 Vuetify 也可以用 vuetify-loader 哦

  • 不用 Vuetify 也可以用 vuetify-loader 哦

你心動了嗎? 快去使用看看 vuetify-loader

歡迎留言提問、補充或一起討論,
如果我的分享對你有幫助,可以順手按個讚,我會更有動力。


  • 2019-03-17 22:19:28

    动态更新Toolbar Menu以及Menu中同时显示文字和图标

    我们经常会有这样的需求,在切换Fragment或者点击某个按钮后动态更新Toolbar上Menu项.但是onCreateOptionsMenu方法只在创建Activity的时候调用一次,以后就不再调用了,所以就不能在onCreateOptionsMenu中做处理了。 不过系统提供了另外的一个方法onPrepa

  • 2019-03-26 19:25:01

    Android studio 打包后安装闪退 Fatal Signal 6(SIGABRT)...

    项目上线前打包安装后闪退,查了很多原因,比如混淆文件的内容,第三方库不加入混淆等等,均未成功,后来关闭混淆打包后运行成功,原因可能是依赖工程中的库文件不能被混淆,关闭本工程混淆开关后,依赖工程的混淆开关也要关闭,关闭混淆后如果怕被反编译,可使用百度开发平台的app加固,加固的同时还能使用多渠道打包工具。

  • 2019-03-26 19:29:05

    Android NDK开发Crash错误定位

     在Android开发中,程序Crash分三种情况:未捕获的异常、ANR(Application Not Responding)和闪退(NDK引发错误)。其中未捕获的异常根据logcat打印的堆栈信息很容易定位错误。ANR错误也好查,Android规定,应用与用户进行交互时,如果5秒内没有响应用户的操作,则会引发ANR错误,并弹出一个系统提示框,让用户选择继续等待或立即关闭程序。并会在/data/anr目录下生成一个traces.txt文件,记录系统产生anr异常的堆栈和线程信息。如果是闪退,这问题比较难查, --------------------- 作者:xyang0917 来源:CSDN 原文:https://blog.csdn.net/xyang81/article/details/42319789 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2019-04-01 22:46:39

    电子签章的实施方案

    WORD/EXCEL签章模块,该部分实现与WORD/EXCEL的无缝结合,并提供给用户简单直观的菜单和工具条来实现文档签章验证等各种操作,其中,KHSC-64智能密码钥匙是签章模块中用户证书和图章的载体

  • 2019-04-01 22:48:25

    如何用 Java 对 PDF 文件进行电子签章

    印章是我国特有的历史文化产物,古代主要用作身份凭证和行驶职权的工具。它的起源是由于社会生活的实际需要。早在商周时代,印章就已经产生。如今的印章已成为一种独特的,融实用性和艺术性为一体的艺术瑰宝。传统的印章容易被坏人、小人私刻;从而新闻鲜有报道某某私刻公章,侵吞国家财产。随着计算机技术、加密技术及图像处理技术的发展,出现了电子签章。电子签章是电子签名的一种表现形式,利用图像处理技术、数字加密技术将电子签名操作转化为与纸质文件盖章操作相同的可视效果,同时利用电子签名技术保障电子信息的真实性和完整性以及签名人的不可否认性

  • 2019-04-01 22:59:22

    Android Studio 3.0 利用cmake搭建jni环境(很详细哦)

    我用的Android Studio是3.0的版本,然后想搭建一下jni的环境。这里把自己遇到的问题和注意点都记录下。 首先是需要在android studio里面安装最基本的环境。 打开Default Preference里面查看SDK Tool选项。