欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3?實現(xiàn)一個自定義toast?小彈窗功能

 更新時間:2022年09月15日 16:16:47   作者:韓振方  
這篇文章主要介紹了Vue3?實現(xiàn)一個自定義toast?小彈窗,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

前言:

前兩天在項目中很多場景下都需要用到一個toast彈窗,項目使用的是ionic+tialwind_Css,ionic也有自帶的toast彈窗,雖然大部分場景下直接調(diào)用它提供的api已經(jīng)能滿足需求了,但是它彈窗的高度,(也就是彈窗出現(xiàn)的位置)并不是高度自定義的,并且彈窗的z-index在我們項目中會和一些組件沖突,但是這個之前一直沒有辦法解決,所以干脆自己手寫了一個使用方法高度類似ionic_Toast的組件。

這個組件也是我第一次在vue3下實現(xiàn)的,也查閱了很多網(wǎng)上相關(guān)的文章,也受到很多啟發(fā)靈感,所以自己吸取精華去其糟粕來完成了一版?zhèn)€人感覺使用起來很方便的一個版本,特來記錄一下實現(xiàn)的過程,希望可以幫助到遇到同樣迷惑的人。

tips:(本篇文章不會上手就教你樣式怎么寫,代碼怎么寫,而是會幫你逐漸一步步理解相關(guān)額外的知識。會以“假如我是一個初學(xué)者,如果當(dāng)時有人這樣告訴我的話,我就大概能聽明白”的角度去解釋。所以篇幅較長,如果想直接看組件的實現(xiàn),可直接跳轉(zhuǎn)到標(biāo)題三)

下面是正文:

一. 前置任務(wù):JSX和渲染函數(shù)的概念

想要完成這個需求,你需要了解一下標(biāo)題的那兩個概念。官方文檔在這里,里面的話語太過于“專業(yè)和官方”,導(dǎo)致我剛開始看的時候非常迷惑,所以在這里我會幫你去理解里面的一些很官方的言語,讓你快速有個認(rèn)知。

原地址在這里:vue官方文檔JSX和渲染函數(shù)。

我們暫且還不需要去深入理解渲染機制的整個流程。所以官方下面?zhèn)€鏈接暫且不要去查閱,會讓你越來越頭暈。 但在這里我要說明一點,接下來講的內(nèi)容都是建立在我默認(rèn)你對虛擬DOM的概念有一定的了解。

緊接就寫到了Vue為我們提供了一個函數(shù),來創(chuàng)建vnodes。在閱讀這個頁面的時候,一定注意官方在每個代碼右上角的文件類型。

這里需要插個必須要了解的題外話,了解React的同學(xué)一定知道JSX這種寫法

Vue里JSX的概念和React的JSX的概念是極其相似的。Vue也是借鑒了React的這個思想,這里我們重點看畫線的這句話。(不熟悉react的小伙伴也不要擔(dān)心,本文實現(xiàn)的Toast并沒有使用到JSX和babel。)

是不是覺得和剛剛Vue官方寫的很相似?

官方在上文也提到了h是什么。如果我們把h換成createVnode(),是不是就和React.createElement的用法及其相似了呢?

其實不管是Vue的h(),還是React.createElement() 它們最終要達到的目的只有一個:創(chuàng)建虛擬DOM。而這也對應(yīng)了Vue中createVnode的Vnode其實就是virtual node的意思。函數(shù)名的直接翻譯其實也就是創(chuàng)建虛擬節(jié)點。而JSX只是創(chuàng)建虛擬dom的語法題而已,僅此而已,并沒有什么特別之處。

二. createVnode函數(shù)的意義

現(xiàn)在我們在 .Vue文件寫如下代碼。

非常簡單的結(jié)構(gòu),一個id是"hanzhenfang"的div標(biāo)簽,標(biāo)簽內(nèi)容是我的名字。ok,這樣寫的話,vue就會幫我們將這個結(jié)構(gòu)轉(zhuǎn)換為虛擬dom。 本質(zhì)上是使用了

h("div",{id:"hanzhenfang"},"韓振方")

h()可以有多個參數(shù),

這段代碼是在<template>標(biāo)簽內(nèi)寫的,它底層其實還是使用了h() 函數(shù)去實現(xiàn)的。說白了就是,React選用JSX來作為渲染虛擬dom函數(shù)的語法糖。而<template>標(biāo)簽是Vue采用的渲染虛擬dom的語法糖。

從而可以引出官方的標(biāo)準(zhǔn)解釋:

你可能會疑問了,既然模板可以實現(xiàn)這樣的功能,那我直接寫模版不就完事了嗎?還需要寫什么h() 函數(shù)呢?因為有的場景確實是模板做不到的。這也就是我為什么會寫這篇文章的原因,因為這個toast需求使用的場景很多很多,我總不能在每個地方都引入一個組件通過v-if來控制它的顯示和關(guān)閉吧?非常繁瑣和麻煩。

三. 編寫Toast組件(不使用tsx)

1.首先創(chuàng)建一個toast.vue文件寫出大致樣式。由于是使用tailwindCss,所以樣式書寫的方式可能和傳統(tǒng)的在style標(biāo)簽寫樣式不太一樣,但是原理是一樣的,不用擔(dān)心。實現(xiàn)如下:

2.toast在絕大場景下都是居中的,并且脫離文檔流,位于整個頁面的最頂部,所以我這里采用了傳統(tǒng)的絕對定位的方案。

3.絕對定位最簡單居中方案不過與設(shè)置top和left各50%。但是我們不要忽略了一點,偏移的時候,我們還要減去自身寬度和高度的一半,才可以做到完全居中。但是處于復(fù)用性考慮,我們的toast的寬度是不能設(shè)置固定寬度的,具體的寬度是由當(dāng)時文字的大小決定的。

4.這時候我們需要用到offsetWidth

1.額外技能補充 offsetWidth

1.先讓我們看看MDN如何解釋的。

2.具體什么意思呢?我們隨手寫一個很簡單的template。

我們現(xiàn)在不加任何Css屬性,來查看一下offsetWidth是什么值。

不要把調(diào)試工具只當(dāng)成console.log的地方,一定利用好這個工具。我們選擇剛剛寫的元素,點擊調(diào)試工具選項欄的Properties標(biāo)簽。

可以看到offsetWidth目前是20(注意,這是一個十進制的number類型,并不帶單位,并且是一個只讀屬性,無法直接更改。) 20是怎么來的呢?其實它就是我們設(shè)置的字體大小。

來驗證一下猜想,我們設(shè)置一下字體大小為15px

3.現(xiàn)在給這個div加上10px寬度的border。

別著急看offsetWidth的值,我們根據(jù)它的定義猜想一下。

應(yīng)該等于15px的字體大小+10px?

確定嗎,別忘了border是上下左右都為10px,所以根據(jù)猜想 `offsetWidht=15px + 10px + 10px

4.如果這個div我們自己設(shè)定寬度呢?我們來給它設(shè)定100px的寬度。

我們會發(fā)現(xiàn)offsetWidth的值變成了100

但是我明明有還有10px的border啊!哪里去了?

你是否忘了我們現(xiàn)在大部分情況下使用的都是box-size:border-box呢?設(shè)置的寬度是包含border的。

驗證一下,我們改變一下box-size的類型。

可以看出來,offsetWidth就變成了100px+10px+10px

Tips:不過在本文中不會設(shè)置定寬去限制

四. Toast居中的思路

1.現(xiàn)在我們可以不設(shè)置Toast的寬度,并且拿到根據(jù)文字?jǐn)?shù)量不同所變化的寬度。由于這個屬性是組件掛載完畢以后才有的屬性,那么我們可以在onMounted里拿到。首先需要拿到元素本身,這里采用打ref的方式。

具體變量和代碼如下:不過多贅述

然后我們需要通過一個計算屬性動態(tài)的計算出該組件的樣式;

ok,這樣就實現(xiàn)了居中的效果。并且不管我們?nèi)绾胃淖儍?nèi)容都沒關(guān)系。居中效果是動態(tài)計算獲得的,并不是一開始就寫死的。

五. Toast三個出現(xiàn)位置的思路

有些場景下Toast出現(xiàn)在底部并不是特別合適,所以我們還要考慮出現(xiàn)位置的問題。這里簡單設(shè)計另外兩個,一個中間,一個偏頂部。實現(xiàn)起來也比較簡單。我們讓它toastWrapperStyle計算top的偏移量也是一個動態(tài)計算的就可以了。

我們就可以在后面給這個組件傳遞參數(shù)來控制具體的位置在哪里。 這個目前的代碼還動態(tài)的展示效果,我們慢慢在后面體現(xiàn)。

tips:下面的章節(jié)是本文全篇重點

六*. h()函數(shù)的使用

我們創(chuàng)建一個toastCreator.ts的文件,便于函數(shù)式調(diào)用展示Toast組件。

準(zhǔn)備如下內(nèi)容,這里需要用到前面所提到的h(),還有render(),render你暫且可以理解為給你返回一個真實的DOM。因為h() 是生成虛擬dom的,但是我們最終展示到頁面的是真實dom,我們之前不用在<template>標(biāo)簽內(nèi)不用執(zhí)行render是因為Vue幫你調(diào)用了render()。但是我們在這里相當(dāng)于手動實現(xiàn)一個Vue的渲染過程,所以我們也同時需要用到這個函數(shù)。

同時把同文件夾下剛剛寫好的Toast.vue引入。class相關(guān)的知識不是本文的重點,不了解的需要自行去查閱相關(guān)知識,這點很重要。

增加了一個duration選項,也就是持續(xù)時間,效果為Toast,在頁面出現(xiàn)多少秒后自動消失。

然后我們需要編寫一個這個類本身的方法,名為present()(這里借鑒了ionic的Toast組件的調(diào)用名稱。) 這一步是重點,也是比較難理解的一個點。 1.首先我們需要自己創(chuàng)建一個Vnode,經(jīng)過翻閱官網(wǎng)。(注意我們著重看JS的文件)。

2.我們得知,原來h() 函數(shù)可以直接接收一個組件模板作為參數(shù)。那么我們可以這樣寫:

這樣變量myToast就是一個Vnode了。

3.然后再調(diào)用引入的render() 函數(shù),我們自然而言的會想到這樣寫。

但是好像不太對勁啊,怎么報錯了呢?看一下報錯信息,原來render() 函數(shù)需要接收兩個參數(shù)。第一個參數(shù)是Vnode,第二個參數(shù)是套在Vnode的真實dom。

讓我們創(chuàng)建并且加上一層外殼containner。其實就是一個普通的div標(biāo)簽。如下:

在這里要強調(diào)一下,你創(chuàng)建的虛擬節(jié)點必須包裹一層真實的DOM作為容器。

這樣正好對應(yīng),為什么Vue或者React組項目的根目錄都會有一個.html文件,并且還有一個根div標(biāo)簽的原因。 因為render() 函數(shù)需要。(想更深入了解原理的可以翻看源碼,不再過多贅述。)

七. 如何傳遞props?

Vnode和真實DOM都有了,那我們?nèi)绾蝹鬟fprops呢?

2.這里不賣官子,先給結(jié)果,我們需要改造一下我們剛剛寫的h() 函數(shù)。

這樣即可將調(diào)用構(gòu)造函數(shù)時傳遞的參數(shù)轉(zhuǎn)換為該組件的props。 由于篇幅限制,具體細(xì)節(jié)大家仔細(xì)閱讀為上面貼出來的Vue官方文檔。

八. 掛載真實DOM到頁面上

都是基礎(chǔ)的知識,不過多解釋了,代碼如下:

九. 持續(xù)時間的控制

編寫dismiss() 方法。非常簡單,直接移除這個節(jié)點即可。

持續(xù)時間如何控制呢? 和時間掛鉤,自然而然可以想到setTimout()。實現(xiàn)原理其實也是非常簡單。在特定的時間,調(diào)用dismiss() 方法即可

十. Toast自定義組件的使用方法

忘了寫message屬性了,我們補充一下

然后在App.vue文件引入

隨手寫一個<button>標(biāo)簽。

效果如下:

3.測試一下 position:top。

十一. 增加淡出的效果

我們項目不需要淡入,所以我就沒做,不過和淡出是如出一轍,在這里我講一下大致思路。 只需在dismiss() 函數(shù)執(zhí)行前,增加一個透明效果,這里使用的是增加類名,只不過這個動畫名稱是搭配tailWind來完成的,你也可以使用別的方法,我的方法并不是最好的,原理思路是一致的

在tailwind.config.js下設(shè)置全局動畫樣式。

這里需要注意?。∧愕膭赢嫵掷m(xù)時間要和dismiss()函數(shù)的setTimeout參數(shù)一致,不然會出現(xiàn)意想不到的效果。動畫結(jié)束了,結(jié)果組件又出現(xiàn)啦。

2.再調(diào)用document.doby.removeChild方法之前,讓我們的組件在0.5s內(nèi)透明度變?yōu)?,然后再移除組件,就完美實現(xiàn)了淡出的效果。

?最終效果如下:

到此這篇關(guān)于Vue3 實現(xiàn)一個自定義toast 小彈窗的文章就介紹到這了,更多相關(guān)Vue3 toast小彈窗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue使用echarts實現(xiàn)柱狀圖動態(tài)排序效果

    vue使用echarts實現(xiàn)柱狀圖動態(tài)排序效果

    echarts在前端開發(fā)中實屬必不可缺的大數(shù)據(jù)可視化工具,這篇文章主要為大家詳細(xì)介紹了vue如何使用echarts實現(xiàn)柱狀圖動態(tài)排序效果,感興趣的可以了解下
    2023-10-10
  • vue踩坑日記之params傳遞參數(shù)問題

    vue踩坑日記之params傳遞參數(shù)問題

    這篇文章主要介紹了vue踩坑日記之params傳遞參數(shù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue嵌入第三方頁面幾種常見方法

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

    在Vue中嵌入第三方頁面可以采用多種方法,例如使用<iframe>、Vue插件、動態(tài)加載第三方腳本或WebComponents,不同方法適用于不同類型的內(nèi)容和項目需求,如<iframe>適用于整個網(wǎng)頁,而動態(tài)腳本和WebComponents適合特定功能,選擇合適的方法可以有效整合外部資源
    2024-09-09
  • 詳解IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗解決方案

    詳解IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗解決方案

    這篇文章主要介紹了詳解IOS微信上Vue單頁面應(yīng)用JSSDK簽名失敗解決方案,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 一篇文章帶你了解Vue組件的創(chuàng)建和使用

    一篇文章帶你了解Vue組件的創(chuàng)建和使用

    這篇文章主要為大家介紹了Vue組件的創(chuàng)建和使用,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • vue el-table實現(xiàn)多選框回填的示例代碼

    vue el-table實現(xiàn)多選框回填的示例代碼

    摘要:Vue多選框回填是實現(xiàn)表單數(shù)據(jù)高效處理的常見需求,本文主要介紹了vue el-table實現(xiàn)多選框回填的示例代碼,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • vue項目打包清除console.log的四種方法總結(jié)

    vue項目打包清除console.log的四種方法總結(jié)

    大家在項目開發(fā)的時候,需要看看一些后端接口返回的結(jié)果,會多次使用console.log項目開發(fā)完成打包的時候,發(fā)現(xiàn)控制臺一堆的console.log,非常頭疼,下面這篇文章主要給大家介紹了關(guān)于vue項目打包清除console.log的四種方法,需要的朋友可以參考下
    2023-04-04
  • Vue中sync修飾符分析原理及用法示例

    Vue中sync修飾符分析原理及用法示例

    在vue中,子組件如果想修改父組件的變量,一般做法是通過綁定事件的方法,父組件向子組件傳遞修改變量的方法,子組件觸發(fā)修改變量的方法執(zhí)行,這種方式中規(guī)中矩;另一種方法是使用sync修飾符,此方法可以減少很多代碼量
    2022-08-08
  • vue2 webpack proxy與nginx配置方式

    vue2 webpack proxy與nginx配置方式

    這篇文章主要介紹了vue2 webpack proxy與nginx配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Vue實現(xiàn)模糊查詢的簡單示例

    Vue實現(xiàn)模糊查詢的簡單示例

    在Vue中實現(xiàn)模糊查詢,你可以使用JavaScript的filter和includes方法,結(jié)合Vue的v-for指令,本文給大家舉了一個簡單的示例,并通過代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01

最新評論