91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用Vue3設計實現一個Model組件

發布時間:2022-08-08 15:46:47 來源:億速云 閱讀:139 作者:iii 欄目:開發技術

本篇內容主要講解“怎么使用Vue3設計實現一個Model組件”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么使用Vue3設計實現一個Model組件”吧!

    一、組件設計

    組件就是把圖形、非圖形的各種邏輯均抽象為一個統一的概念(組件)來實現開發的模式

    現在有一個場景,點擊新增與編輯都彈框出來進行填寫,功能上大同小異,可能只是標題內容或者是顯示的主體內容稍微不同

    這時候就沒必要寫兩個組件,只需要根據傳入的參數不同,組件顯示不同內容即可

    這樣,下次開發相同界面程序時就可以寫更少的代碼,意義著更高的開發效率,更少的 Bug和更少的程序體積

    二、需求分析

    實現一個Modal組件,首先確定需要完成的內容:

    • 遮罩層

    • 標題內容

    • 主體內容

    • 確定和取消按鈕

    主體內容需要靈活,所以可以是字符串,也可以是一段 html 代碼

    特點是它們在當前vue實例之外獨立存在,通常掛載于body之上

    除了通過引入import的形式,我們還可通過API的形式進行組件的調用

    還可以包括配置全局樣式、國際化、與typeScript結合

    三、實現流程

    首先看看大致流程:

    • 目錄結構

    • 組件內容

    • 實現 API 形式

    • 事件處理

    • 其他完善

    目錄結構

    Modal組件相關的目錄結構

    ├── plugins
    │   └── modal
    │       ├── Content.tsx // 維護 Modal 的內容,用于 h 函數和 jsx 語法
    │       ├── Modal.vue // 基礎組件
    │       ├── config.ts // 全局默認配置
    │       ├── index.ts // 入口
    │       ├── locale // 國際化相關
    │       │   ├── index.ts
    │       │   └── lang
    │       │       ├── en-US.ts
    │       │       ├── zh-CN.ts
    │       │       └── zh-TW.ts
    │       └── modal.type.ts // ts類型聲明相關

    因為 Modal 會被 app.use(Modal) 調用作為一個插件,所以都放在plugins目錄下

    組件內容

    首先實現modal.vue的主體顯示內容大致如下

    <Teleport to="body" :disabled="!isTeleport">
        <div v-if="modelValue" class="modal">
            <div
                 class="mask"
                 :
                 @click="maskClose && !loading && handleCancel()"
                 ></div>
            <div class="modal__main">
                <div class="modal__title line line--b">
                    <span>{{ title || t("r.title") }}</span>
                    <span
                          v-if="close"
                          :title="t('r.close')"
                          class="close"
                          @click="!loading && handleCancel()"
                          >?</span
                        >
                </div>
                <div class="modal__content">
                    <Content v-if="typeof content === 'function'" :render="content" />
                    <slot v-else>
                        {{ content }}
                    </slot>
                </div>
                <div class="modal__btns line line--t">
                    <button :disabled="loading" @click="handleConfirm">
                        <span class="loading" v-if="loading"> ? </span>{{ t("r.confirm") }}
                    </button>
                    <button @click="!loading && handleCancel()">
                        {{ t("r.cancel") }}
                    </button>
                </div>
            </div>
        </div>
    </Teleport>

    最外層上通過Vue3 Teleport 內置組件進行包裹,其相當于傳送門,將里面的內容傳送至body之上

    并且從DOM結構上來看,把modal該有的內容(遮罩層、標題、內容、底部按鈕)都實現了

    關于主體內容

    <div class="modal__content">
        <Content v-if="typeof content==='function'"
                 :render="content" />
        <slot v-else>
            {{content}}
        </slot>
    </div>

    可以看到根據傳入content的類型不同,對應顯示不同得到內容

    最常見的則是通過調用字符串和默認插槽的形式

    // 默認插槽
    <Modal v-model="show"
           title="演示 slot">
        <div>hello world~</div>
    </Modal>
    
    // 字符串
    <Modal v-model="show"
           title="演示 content"
           content="hello world~" />

    通過 API 形式調用Modal組件的時候,content可以使用下面兩種

    • h 函數

    $modal.show({
      title: '演示 h 函數',
      content(h) {
        return h(
          'div',
          {
            style: 'color:red;',
            onClick: ($event: Event) => console.log('clicked', $event.target)
          },
          'hello world ~'
        );
      }
    });
    • JSX

    $modal.show({
      title: '演示 jsx 語法',
      content() {
        return (
          <div
            onClick={($event: Event) => console.log('clicked', $event.target)}
          >
            hello world ~
          </div>
        );
      }
    });

    實現 API 形式

    那么組件如何實現API形式調用Modal組件呢?

    在Vue2中,我們可以借助Vue實例以及Vue.extend的方式獲得組件實例,然后掛載到body上

    import Modal from './Modal.vue';
    const ComponentClass = Vue.extend(Modal);
    const instance = new ComponentClass({ el: document.createElement("div") });
    document.body.appendChild(instance.$el);

    雖然Vue3移除了Vue.extend方法,但可以通過createVNode實現

    import Modal from './Modal.vue';
    const container = document.createElement('div');
    const vnode = createVNode(Modal);
    render(vnode, container);
    const instance = vnode.component;
    document.body.appendChild(container);

    在Vue2中,可以通過this的形式調用全局 API

    export default {
        install(vue) {
           vue.prototype.$create = create
        }
    }

    而在 Vue3 的 setup 中已經沒有 this概念了,需要調用app.config.globalProperties掛載到全局

    export default {
        install(app) {
            app.config.globalProperties.$create = create
        }
    }

    事件處理

    下面再看看看Modal組件內部是如何處理「確定」「取消」事件的,既然是Vue3,當然采用Compositon API 形式

    // Modal.vue
    setup(props, ctx) {
      let instance = getCurrentInstance(); // 獲得當前組件實例
      onBeforeMount(() => {
        instance._hub = {
          'on-cancel': () => {},
          'on-confirm': () => {}
        };
      });
    
      const handleConfirm = () => {
        ctx.emit('on-confirm');
        instance._hub['on-confirm']();
      };
      const handleCancel = () => {
        ctx.emit('on-cancel');
        ctx.emit('update:modelValue', false);
        instance._hub['on-cancel']();
      };
    
      return {
        handleConfirm,
        handleCancel
      };
    }

    在上面代碼中,可以看得到除了使用傳統emit的形式使父組件監聽,還可通過_hub屬性中添加 on-cancel,on-confirm方法實現在API中進行監聽

    app.config.globalProperties.$modal = {
       show({}) {
         /* 監聽 確定、取消 事件 */
       }
    }

    下面再來目睹下_hub是如何實現

    // index.ts
    app.config.globalProperties.$modal = {
        show({
            /* 其他選項 */
            onConfirm,
            onCancel
        }) {
            /* ... */
    
            const { props, _hub } = instance;
    
            const _closeModal = () => {
                props.modelValue = false;
                container.parentNode!.removeChild(container);
            };
            // 往 _hub 新增事件的具體實現
            Object.assign(_hub, {
                async 'on-confirm'() {
                if (onConfirm) {
                    const fn = onConfirm();
                    // 當方法返回為 Promise
                    if (fn && fn.then) {
                        try {
                            props.loading = true;
                            await fn;
                            props.loading = false;
                            _closeModal();
                        } catch (err) {
                            // 發生錯誤時,不關閉彈框
                            console.error(err);
                            props.loading = false;
                        }
                    } else {
                        _closeModal();
                    }
                } else {
                    _closeModal();
                }
            },
                'on-cancel'() {
                    onCancel && onCancel();
                    _closeModal();
                }
        });
    }
    };

    到此,相信大家對“怎么使用Vue3設計實現一個Model組件”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    江阴市| 西畴县| 盖州市| 宜春市| 邹平县| 百色市| 威宁| 中宁县| 临武县| 潜山县| 准格尔旗| 峨山| 安图县| 合江县| 囊谦县| 金山区| 上思县| 永宁县| 宽城| 文化| 阜宁县| 昆山市| 卓资县| 崇仁县| 明溪县| 海林市| 遵化市| 台东县| 宝鸡市| 大新县| 尚志市| 玉田县| 阳春市| 汉寿县| 调兵山市| 左云县| 湾仔区| 田林县| 西丰县| 庆城县| 蓝山县|