iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
Modern Web

蓋一個自己的 Nuxt 3 UI Module系列 第 10

元件製作 tooltip

  • 分享至 

  • xImage
  •  

有時讀文章時,遇到一些專有名詞不太理解,只要把滑鼠游標移動到字詞上面就會跳出一個框框告訴讀者字詞的意思,這個好用的小工具就是 tooltip !

範例:bootstrap5 tooltip 元件

範例:bootstrap5 tooltip 元件

有些地方需要給使用者更詳盡的資訊,但又不能佔到版面時,tooltip 就是一個很棒的解決方法。

實作

  • 實作時 tooltip 要注意的是 tip 顯示的地方不能被視窗裁切掉,抑或是被其他元素給遮擋住。

  • step1: 安裝 vue-tippy

    npm install vue-tippy@v6
    
  • step2: 新建立一個 plugins 資料夾,並新增 vue-tippy.ts

    按照官方的說明,這樣就可以開始使用嚕

    // plugins/vue-tippy.vue
    import { defineNuxtPlugin } from '#imports'
    
    import VueTippy from 'vue-tippy'
    import 'tippy.js/dist/tippy.css'
    
    export default defineNuxtPlugin(nuxtApp => {
      nuxtApp.vueApp.use(VueTippy)
    })
    
  • step3: 接下來把剛剛掛載的 vue-tippy 元件調整成自己比較常用的樣子~

    tippy 本身提供了許多控制的屬性,我們可以在定義 interface 時一併帶入,這樣可以增加他的可控性與多樣性,例如動畫效果或是 tippy 出現位置的設定。

    // components/global/tippy.vue
    <script lang="ts" setup>
    import { defineProps, withDefaults } from 'vue'
    
    export interface TooltipPropsType {
      /** 預設 button 標題 */
      title?: string
      /**  tooltip 呈現內容  */
      content?: string
      /** 預設 button 樣式 */
      btnClass?: string
      /** tooltip 出現位置 */
      placement?: string
      /** 是否開啟箭頭 */
      arrow?: boolean
      /** tooltip 動畫呈現位置(需在 /plugins/vue-tippy.ts 引入對應的 css) */
      animation?: 'scale' | 'scale-subtle' | 'scale-extreme' |
      'perspective-extreme' | 'perspective-subtle' | 'perspective' |
      'shift-away-extreme' | 'shift-away-subtle' | 'shift-away' | 'shift-toward-extreme' |
      'shift-toward-subtle' | 'shift-toward' | 'fade'
      /** 觸發方式 */
      trigger?: 'mouseenter' | 'click'
      /** 延遲出現時間(毫秒) */
      delay?: number
      /** 動畫持續時間 */
      duration?: number
    }
    
    withDefaults(defineProps<TooltipPropsType>(), {
      title: 'button\'s title ',
      content: 'The content of the tippy!',
      btnClass: 'btn-outline-dark',
      placement: 'top',
      animation: 'scale',
      trigger: 'mouseenter',
      delay: 0
    })
    
    </script>
    
    <template>
      <tippy
        v-if="$slots.default"
        :placement="placement"
        :arrow="arrow"
        :animation="animation"
        :trigger="trigger"
        :delay="delay"
        :duration="duration"
      >
        <button
          v-if="$slots.button"
          class="inline-block"
        >
          <slot name="button" />
        </button>
        <button
          v-else
          class="btn"
          :class="btnClass"
        >
          {{ title }}
        </button>
    
        <template #content>
          <slot />
        </template>
      </tippy>
    
      <button
        v-else
        v-tippy="{
          placement: placement,
          arrow: arrow,
          animation: animation,
          trigger: trigger,
          delay: delay,
          duration: duration
        }"
        :content="content"
        class="btn"
        :class="btnClass"
      >
        {{ title }}
      </button>
    </template>
    
    • 這邊要注意的是引入動畫效果後要記得在 plugins/vue-tippy.vue 的部份引入該動畫效果。
      引入的位置是 tippy.js

      import { defineNuxtPlugin } from '#imports'
      
      import VueTippy from 'vue-tippy'
      import 'tippy.js/animations/perspective.css'
      import 'tippy.js/animations/scale-extreme.css'
      import 'tippy.js/animations/scale-subtle.css'
      import 'tippy.js/animations/scale.css'
      import 'tippy.js/animations/shift-away-extreme.css'
      import 'tippy.js/animations/shift-away.css'
      import 'tippy.js/animations/shift-toward.css'
      import 'tippy.js/dist/tippy.css'
      
      export default defineNuxtPlugin(nuxtApp => {
        nuxtApp.vueApp.use(VueTippy)
      })
      
  • 如此就完成囉!會選用 vue-tippy 是因為他提供了多元的效果與設定,且不會被視窗或其他元素給遮擋住 :)

    image.gif


上一篇
元件製作 tab
下一篇
元件製作 layout
系列文
蓋一個自己的 Nuxt 3 UI Module16
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言