最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

??Vue3 自定義公共組件的實(shí)現(xiàn)實(shí)例

 更新時(shí)間:2025年11月24日 08:34:52   作者:Rysxt  
本文主要介紹了??Vue3 自定義公共組件的實(shí)現(xiàn)實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

???一 環(huán)境準(zhǔn)備與項(xiàng)目初始化??

  • 使用 ??Vite?? 快速搭建 Vue3 項(xiàng)目,選擇 ??Vue?? 模板:
    • 創(chuàng)建項(xiàng)目:npm create vite@latest my-component-lib --template vue
    • 進(jìn)入目錄:cd my-component-lib
    • 安裝依賴:npm install

推薦采用 monorepo 風(fēng)格組織組件庫(kù)源碼,便于多組件維護(hù)與發(fā)布:

新建目錄:packages/(組件源碼)、src/(示例與文檔)

示例結(jié)構(gòu):

my-component-lib/
├── packages/
│   ├── button/
│   │   └── index.vue
│   └── index.js
├── src/
├── package.json
└── vite.config.js

packages/index.js 統(tǒng)一導(dǎo)出組件,便于全局注冊(cè)與按需引入。

??二 編寫一個(gè)可復(fù)用的按鈕組件??

  • 組件功能:支持 ??size??、??type??、??disabled??,通過 ??插槽?? 自定義內(nèi)容,點(diǎn)擊時(shí) ??emit('click')??。
  • 組件代碼:packages/button/index.vue
    <template>
      <button
        :class="['zd-btn', sizeClass, typeClass, { 'is-disabled': disabled }]"
        :disabled="disabled"
        @click="handleClick"
      >
        <slot />
      </button>
    </template>
    
    <script setup>
    import { computed } from 'vue'
    
    const props = defineProps({
      size: {
        type: String,
        default: 'middle',
        validator: v => ['large', 'middle', 'small', 'mini'].includes(v)
      },
      type: {
        type: String,
        default: 'default',
        validator: v => ['default', 'primary', 'success', 'warning', 'danger', 'info', 'text'].includes(v)
      },
      disabled: {
        type: Boolean,
        default: false
      }
    })
    
    const emit = defineEmits(['click'])
    
    const sizeClass = computed(() => `zd-btn--${props.size}`)
    const typeClass = computed(() => `zd-btn--${props.type}`)
    
    const handleClick = (e) => {
      if (!props.disabled) emit('click', e)
    }
    </script>
    
    <style scoped>
    .zd-btn {
      border: none;
      border-radius: 4px;
      padding: 0 16px;
      font-family: inherit;
      cursor: pointer;
      transition: all 0.2s ease;
      outline: none;
    }
    .zd-btn:disabled {
      cursor: not-allowed;
      opacity: 0.6;
    }
    .zd-btn--large  { height: 48px; font-size: 16px; }
    .zd-btn--middle { height: 40px; font-size: 14px; }
    .zd-btn--small  { height: 32px; font-size: 13px; }
    .zd-btn--mini  { height: 24px; font-size: 12px; }
    
    .zd-btn--default { background: #fff; border: 1px solid #d9d9d9; color: #333; }
    .zd-btn--default:hover:not(.is-disabled) { border-color: #c0c0c0; background: #f5f5f5; }
    .zd-btn--primary { background: #409eff; color: #fff; border: 1px solid #409eff; }
    .zd-btn--primary:hover:not(.is-disabled) { background: #66b1ff; border-color: #66b1ff; }
    .zd-btn--success { background: #67c23a; color: #fff; border: 1px solid #67c23a; }
    .zd-btn--warning { background: #e6a23c; color: #fff; border: 1px solid #e6a23c; }
    .zd-btn--danger  { background: #f56c6c; color: #fff; border: 1px solid #f56c6c; }
    .zd-btn--info   { background: #909399; color: #fff; border: 1px solid #909399; }
    .zd-btn--text   { background: transparent; border: none; color: #409eff; }
    .zd-btn--text:hover:not(.is-disabled) { background: rgba(64,158,255,0.1); }
    </style>
  • 入口導(dǎo)出:packages/index.js
    import { App } from 'vue'
    import ZdButton from './button/index.vue'
    
    const components = [ZdButton]
    
    const install = (app) => {
      components.forEach(c => app.component(c.name || c.displayName, c))
    }
    
    export { ZdButton, install }
    export default { install }
  • 本地測(cè)試:在 src/main.js 全局注冊(cè)并使用
    import { createApp } from 'vue'
    import App from './App.vue'
    import ZdComponentLib from '../packages/index.js'
    
    createApp(App).use(ZdComponentLib).mount('#app')
    <template>
      <zd-button type="primary" size="large" @click="onClick">Primary</zd-button>
    </template>
    
    <script setup>
    const onClick = () => alert('clicked')
    </script>
  • 要點(diǎn)
    • 使用 ??defineProps / defineEmits?? 聲明式 API,類型清晰。
    • 通過 ??validator?? 約束枚舉值,減少錯(cuò)誤用法。
    • 使用 ??scoped?? 樣式避免泄漏,必要時(shí)用 ??CSS 變量?? 支持主題定制。

??三 組件庫(kù)打包與發(fā)布到 npm??

  • 庫(kù)模式構(gòu)建配置:vite.config.js
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import { resolve } from 'path'
    
    export default defineConfig({
      plugins: [vue()],
      build: {
        lib: {
          entry: resolve(__dirname, 'packages/index.js'),
          name: 'MyUILib',
          fileName: (fmt) => `my-ui.${fmt}.js`
        },
        rollupOptions: {
          external: ['vue'],
          output: {
            globals: { vue: 'Vue' }
          }
        }
      }
    })
  • 入口包配置:package.json(建議獨(dú)立包名與版本管理)
    {
      "name": "@your-org/vue3-ui",
      "version": "1.0.0",
      "type": "module",
      "main": "dist/my-ui.umd.js",
      "module": "dist/my-ui.es.js",
      "files": ["dist", "packages"],
      "types": "dist/types/index.d.ts",
      "scripts": {
        "dev": "vite",
        "build": "vite build",
        "preview": "vite preview"
      },
      "peerDependencies": { "vue": "^3.0.0" },
      "keywords": ["vue3", "components", "ui"],
      "author": "Your Name",
      "license": "MIT"
    }
  • 類型聲明(可選,提升 TS 體驗(yàn)):dist/types/index.d.ts
    import type { DefineComponent } from 'vue'
    export const ZdButton: DefineComponent<{
      size?: 'large' | 'middle' | 'small' | 'mini'
      type?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text'
      disabled?: boolean
    }, {}, {}, {}, {
      click: [MouseEvent]
    }>
    export const install: any
    export default { install }
  • 發(fā)布流程
    • 登錄 npm:npm login(確保源為官方倉(cāng)庫(kù))
    • 構(gòu)建:npm run build
    • 發(fā)布:npm publish --access public
  • 其他項(xiàng)目使用
    • 全局注冊(cè):app.use(MyUILib)
    • 按需引入:import { ZdButton } from '@your-org/vue3-ui'(并單獨(dú)引入樣式文件,如有)。

??四 使用方式與最佳實(shí)踐??

  • 兩種引入方式
    • 全局注冊(cè):適合通用 UI 組件,減少重復(fù) import。
      import { createApp } from 'vue'
      import App from './App.vue'
      import MyUILib from '@your-org/vue3-ui'
      app.use(MyUILib).mount('#app')
    • 按需引入:減小打包體積,配合構(gòu)建工具自動(dòng)引入(如 unplugin-vue-components)。
      <template>
        <zd-button type="primary">Hello</zd-button>
      </template>
      
      <script setup>
      import { ZdButton } from '@your-org/vue3-ui'
      </script>
  • 組件設(shè)計(jì)要點(diǎn)
    • Props:明確 ??類型??、??默認(rèn)值??、??校驗(yàn)器??,保持 API 穩(wěn)定。
    • 事件:語義化命名(如 ??click??、??change??),必要時(shí)透?jìng)魇录?duì)象與業(yè)務(wù)數(shù)據(jù)。
    • 插槽:優(yōu)先使用默認(rèn)插槽與具名插槽提升可定制性。
    • 樣式:優(yōu)先 ??scoped??;跨組件主題用 ??CSS 變量??;對(duì)外提供主題變量文件。
    • 可訪問性:支持鍵盤操作、焦點(diǎn)管理、ARIA 屬性。
    • 表單組件:優(yōu)先支持 ??v-model??,遵循原生表單元素交互約定。
  • 簡(jiǎn)單測(cè)試示例(Jest + Vue Test Utils)
    import { mount } from '@vue/test-utils'
    import { ZdButton } from '@your-org/vue3-ui'
    
    test('emits click when not disabled', async () => {
      const wrapper = mount(ZdButton)
      await wrapper.trigger('click')
      expect(wrapper.emitted('click')).toHaveLength(1)
    })
    
    test('does not emit click when disabled', async () => {
      const wrapper = mount(ZdButton, { props: { disabled: true } })
      await wrapper.trigger('click')
      expect(wrapper.emitted('click')).toBeUndefined()
    })
  • 常見問題與排查
    • 事件未觸發(fā):檢查是否被 ??disabled?? 攔截或事件綁定寫法是否正確。
    • 樣式?jīng)_突:確認(rèn)使用 ??scoped?? 或命名規(guī)范(BEM)。
    • 全局污染:避免在組件內(nèi)使用過多樣式全局選擇器。
    • 按需引入樣式缺失:確認(rèn)是否單獨(dú)引入組件樣式文件或配置了樣式自動(dòng)引入插件。

到此這篇關(guān)于??Vue3 自定義公共組件的實(shí)現(xiàn)實(shí)例的文章就介紹到這了,更多相關(guān)??Vue3 自定義公共組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解vue父子模版嵌套案例

    詳解vue父子模版嵌套案例

    本篇文章主要介紹了詳解vue父子模版嵌套案例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • vue/cli?配置動(dòng)態(tài)代理無需重啟服務(wù)的操作方法

    vue/cli?配置動(dòng)態(tài)代理無需重啟服務(wù)的操作方法

    vue-cli是vue.js的腳手架,用于自動(dòng)生成vue.js+webpack的項(xiàng)目模板,分為vue?init?webpack-simple?項(xiàng)目名和vue?init?webpack?項(xiàng)目名兩種,這篇文章主要介紹了vue/cli?配置動(dòng)態(tài)代理,無需重啟服務(wù),需要的朋友可以參考下
    2022-05-05
  • vue 通過base64實(shí)現(xiàn)圖片下載功能

    vue 通過base64實(shí)現(xiàn)圖片下載功能

    這篇文章主要介紹了vue 通過base64實(shí)現(xiàn)圖片下載功能,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下
    2020-12-12
  • Vue el-table復(fù)選框全部勾選及勾選回顯功能實(shí)現(xiàn)

    Vue el-table復(fù)選框全部勾選及勾選回顯功能實(shí)現(xiàn)

    這篇文章主要介紹了Vue el-table復(fù)選框全部勾選及勾選回顯功能實(shí)現(xiàn),本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • vue+iview實(shí)現(xiàn)文件上傳

    vue+iview實(shí)現(xiàn)文件上傳

    這篇文章主要為大家詳細(xì)介紹了vue+iview實(shí)現(xiàn)文件上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Vue動(dòng)態(tài)表單的應(yīng)用詳解

    Vue動(dòng)態(tài)表單的應(yīng)用詳解

    這篇文章主要為大家詳細(xì)介紹了Vue動(dòng)態(tài)表單的應(yīng)用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • VUE項(xiàng)目中調(diào)用高德地圖的全流程講解

    VUE項(xiàng)目中調(diào)用高德地圖的全流程講解

    這篇文章主要介紹了VUE項(xiàng)目中調(diào)用高德地圖的全流程講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue嵌入第三方頁面幾種常見方法

    vue嵌入第三方頁面幾種常見方法

    在Vue中嵌入第三方頁面可以采用多種方法,例如使用<iframe>、Vue插件、動(dòng)態(tài)加載第三方腳本或WebComponents,不同方法適用于不同類型的內(nèi)容和項(xiàng)目需求,如<iframe>適用于整個(gè)網(wǎng)頁,而動(dòng)態(tài)腳本和WebComponents適合特定功能,選擇合適的方法可以有效整合外部資源
    2024-09-09
  • 詳解項(xiàng)目升級(jí)到vue-cli3的正確姿勢(shì)

    詳解項(xiàng)目升級(jí)到vue-cli3的正確姿勢(shì)

    這篇文章主要介紹了詳解項(xiàng)目升級(jí)到vue-cli3的正確姿勢(shì),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-01-01
  • vue解決跨域問題的幾種常用方法(CORS)

    vue解決跨域問題的幾種常用方法(CORS)

    在Vue中解決跨域問題有多種方法,今天通過本文給大家介紹幾種比較常見的方法,對(duì)vue解決跨域問題感興趣的朋友跟隨小編一起看看吧
    2023-05-05

最新評(píng)論

曲松县| 大同市| 尼勒克县| 佳木斯市| 千阳县| 高州市| 宜丰县| 湘潭市| 喀什市| 万荣县| 阳西县| 邵东县| 鄄城县| 伊宁市| 大连市| 文安县| 肥乡县| 雅安市| 广丰县| 苍山县| 左权县| 马关县| 十堰市| 沙湾县| 阿坝| 克什克腾旗| 嵩明县| 四子王旗| 牡丹江市| 沙河市| 五原县| 临朐县| 凤台县| 嘉义县| 沙河市| 洛南县| 班玛县| 峨山| 阿克苏市| 文成县| 衡阳市|