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

如何使用Vue3設計實現(xiàn)一個Model組件淺析

 更新時間:2022年08月06日 08:12:34   作者:Chang愛學習  
v-model在Vue里面是一個語法糖,數(shù)據(jù)的雙向綁定,本質(zhì)上還是通過 自定義標簽的attribute傳遞和接受,下面這篇文章主要給大家介紹了關(guān)于如何使用Vue3設計實現(xiàn)一個Model組件的相關(guān)資料,需要的朋友可以參考下

一、組件設計

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

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

這時候就沒必要寫兩個組件,只需要根據(jù)傳入的參數(shù)不同,組件顯示不同內(nèi)容即可

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

二、需求分析

實現(xiàn)一個Modal組件,首先確定需要完成的內(nèi)容:

  • 遮罩層
  • 標題內(nèi)容
  • 主體內(nèi)容
  • 確定和取消按鈕

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

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

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

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

三、實現(xiàn)流程

首先看看大致流程:

  • 目錄結(jié)構(gòu)
  • 組件內(nèi)容
  • 實現(xiàn) API 形式
  • 事件處理
  • 其他完善

目錄結(jié)構(gòu)

Modal組件相關(guān)的目錄結(jié)構(gòu)

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

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

組件內(nèi)容

首先實現(xiàn)modal.vue的主體顯示內(nèi)容大致如下

<Teleport to="body" :disabled="!isTeleport">
    <div v-if="modelValue" class="modal">
        <div
             class="mask"
             :style="style"
             @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 內(nèi)置組件進行包裹,其相當于傳送門,將里面的內(nèi)容傳送至body之上

并且從DOM結(jié)構(gòu)上來看,把modal該有的內(nèi)容(遮罩層、標題、內(nèi)容、底部按鈕)都實現(xiàn)了

關(guān)于主體內(nèi)容

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

可以看到根據(jù)傳入content的類型不同,對應顯示不同得到內(nèi)容

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

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

// 字符串
<Modal v-model="show"
       title="演示 content"
       content="hello world~" />

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

  • h 函數(shù)
$modal.show({
  title: '演示 h 函數(shù)',
  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>
    );
  }
});

實現(xiàn) API 形式

那么組件如何實現(xiàn)API形式調(diào)用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實現(xiàn)

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的形式調(diào)用全局 API

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

而在 Vue3 的 setup 中已經(jīng)沒有 this概念了,需要調(diào)用app.config.globalProperties掛載到全局

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

事件處理

下面再看看看Modal組件內(nèi)部是如何處理「確定」「取消」事件的,既然是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
  };
}

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

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

下面再來目睹下_hub是如何實現(xiàn)

// index.ts
app.config.globalProperties.$modal = {
    show({
        /* 其他選項 */
        onConfirm,
        onCancel
    }) {
        /* ... */

        const { props, _hub } = instance;

        const _closeModal = () => {
            props.modelValue = false;
            container.parentNode!.removeChild(container);
        };
        // 往 _hub 新增事件的具體實現(xiàn)
        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) {
                        // 發(fā)生錯誤時,不關(guān)閉彈框
                        console.error(err);
                        props.loading = false;
                    }
                } else {
                    _closeModal();
                }
            } else {
                _closeModal();
            }
        },
            'on-cancel'() {
                onCancel && onCancel();
                _closeModal();
            }
    });
}
};

其他完善

關(guān)于組件實現(xiàn)國際化、與typsScript結(jié)合,大家可以根據(jù)自身情況在此基礎(chǔ)上進行更改

總結(jié)

到此這篇關(guān)于如何使用Vue3設計實現(xiàn)一個Model組件的文章就介紹到這了,更多相關(guān)Vue3設計實現(xiàn)Model組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue?過濾、模糊查詢及計算屬性?computed詳解

    vue?過濾、模糊查詢及計算屬性?computed詳解

    計算屬性是vue里面為了簡化在模板語法中對響應式屬性做計算而存在的,這篇文章主要介紹了vue?過濾、模糊查詢(計算屬性?computed),需要的朋友可以參考下
    2022-11-11
  • 一篇超詳細的Vue-Router手把手教程

    一篇超詳細的Vue-Router手把手教程

    這篇文章主要給大家介紹了關(guān)于Vue-Router的相關(guān)資料,vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,適合用于構(gòu)建單頁面應用,本文通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-08-08
  • 一文弄懂Vite 配置文件

    一文弄懂Vite 配置文件

    Vite?構(gòu)建環(huán)境分為開發(fā)環(huán)境和生產(chǎn)環(huán)境,不同環(huán)境會有不同的構(gòu)建策略,本文就來介紹下Vite 配置文件,具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • Vue實現(xiàn)當前頁面刷新的4種方法舉例

    Vue實現(xiàn)當前頁面刷新的4種方法舉例

    我們在開發(fā)vue的頁面的時候,有時候會遇到需要刷新當前頁面功能,但是vue框架自帶的router是不支持刷新當前頁面功能,下面這篇文章主要給大家介紹了關(guān)于Vue實現(xiàn)當前頁面刷新的4種方法,需要的朋友可以參考下
    2023-04-04
  • vue數(shù)據(jù)雙向綁定的注意點

    vue數(shù)據(jù)雙向綁定的注意點

    這篇文章主要為大家詳細介紹了vue數(shù)據(jù)雙向綁定的注意點,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • Vue中用props給data賦初始值遇到的問題解決

    Vue中用props給data賦初始值遇到的問題解決

    這篇文章主要介紹了Vue中用props給data賦初始值遇到的問題解決,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11
  • tauri和vue通信的問題解決方案示例詳解

    tauri和vue通信的問題解決方案示例詳解

    這篇文章主要為大家介紹了tauri和vue通信的問題解決方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • vue3中?provide?和?inject?用法及原理

    vue3中?provide?和?inject?用法及原理

    這篇文章主要介紹vue3中?provide?和?inject?用法及原理,provide?和?inject可以?解決多次組件傳遞數(shù)據(jù)的問題,下面文章是具體的用法和實現(xiàn)原理,具有一定的參考價值,需要的朋友可以參考一下,希望對大家有所幫助
    2021-11-11
  • vue項目中實現(xiàn)的微信分享功能示例

    vue項目中實現(xiàn)的微信分享功能示例

    這篇文章主要介紹了vue項目中實現(xiàn)的微信分享功能,結(jié)合實例形式分析了基于vue.js實現(xiàn)的微信分享功能具體定義與使用方法,需要的朋友可以參考下
    2019-01-01
  • vue+element項目中過濾輸入框特殊字符小結(jié)

    vue+element項目中過濾輸入框特殊字符小結(jié)

    這篇文章主要介紹了vue+element項目中過濾輸入框特殊字符小結(jié),本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08

最新評論

吉木乃县| 林周县| 盐津县| 正蓝旗| 叶城县| 桃园县| 潮安县| 博野县| 焦作市| 江津市| 安新县| 达拉特旗| 高州市| 乌鲁木齐县| 镇沅| 西乌珠穆沁旗| 遵化市| 凤阳县| 恩施市| 凤台县| 苏州市| 乌海市| 长海县| 奇台县| 崇信县| 忻城县| 肥西县| 建平县| 琼结县| 扬中市| 合作市| 桑植县| 鄂尔多斯市| 阜南县| 上思县| 汾西县| 白水县| 闸北区| 遂宁市| 牡丹江市| 绵竹市|