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

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

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

前言:

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

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

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

下面是正文:

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

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

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

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

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

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

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

是不是覺(jué)得和剛剛Vue官方寫(xiě)的很相似?

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

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

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

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

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

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

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

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

從而可以引出官方的標(biāo)準(zhǔn)解釋?zhuān)?/p>

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

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

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

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

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

4.這時(shí)候我們需要用到offsetWidth

1.額外技能補(bǔ)充 offsetWidth

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

2.具體什么意思呢?我們隨手寫(xiě)一個(gè)很簡(jiǎn)單的template。

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

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

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

來(lái)驗(yàn)證一下猜想,我們?cè)O(shè)置一下字體大小為15px

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

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

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

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

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

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

但是我明明有還有10px的border?。∧睦锶チ??

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

驗(yàn)證一下,我們改變一下box-size的類(lèi)型。

可以看出來(lái),offsetWidth就變成了100px+10px+10px

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

四. Toast居中的思路

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

具體變量和代碼如下:不過(guò)多贅述

然后我們需要通過(guò)一個(gè)計(jì)算屬性動(dòng)態(tài)的計(jì)算出該組件的樣式;

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

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

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

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

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

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

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

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

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

增加了一個(gè)duration選項(xiàng),也就是持續(xù)時(shí)間,效果為T(mén)oast,在頁(yè)面出現(xiàn)多少秒后自動(dòng)消失。

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

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

這樣變量myToast就是一個(gè)Vnode了。

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

但是好像不太對(duì)勁啊,怎么報(bào)錯(cuò)了呢?看一下報(bào)錯(cuò)信息,原來(lái)render() 函數(shù)需要接收兩個(gè)參數(shù)。第一個(gè)參數(shù)是Vnode,第二個(gè)參數(shù)是套在Vnode的真實(shí)dom。

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

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

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

七. 如何傳遞props?

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

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

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

八. 掛載真實(shí)DOM到頁(yè)面上

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

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

編寫(xiě)dismiss() 方法。非常簡(jiǎn)單,直接移除這個(gè)節(jié)點(diǎn)即可。

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

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

忘了寫(xiě)message屬性了,我們補(bǔ)充一下

然后在App.vue文件引入

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

效果如下:

3.測(cè)試一下 position:top。

十一. 增加淡出的效果

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

在tailwind.config.js下設(shè)置全局動(dòng)畫(huà)樣式。

這里需要注意??!你的動(dòng)畫(huà)持續(xù)時(shí)間要和dismiss()函數(shù)的setTimeout參數(shù)一致,不然會(huì)出現(xiàn)意想不到的效果。動(dòng)畫(huà)結(jié)束了,結(jié)果組件又出現(xiàn)啦。

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

?最終效果如下:

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

相關(guān)文章

  • vue項(xiàng)目關(guān)閉eslint校驗(yàn)

    vue項(xiàng)目關(guān)閉eslint校驗(yàn)

    eslint是一個(gè)JavaScript的校驗(yàn)插件,通常用來(lái)校驗(yàn)語(yǔ)法或代碼的書(shū)寫(xiě)風(fēng)格。這篇文章主要介紹了vue項(xiàng)目關(guān)閉eslint校驗(yàn),需要的朋友可以參考下
    2018-03-03
  • 解決vue單頁(yè)面應(yīng)用打包后相對(duì)路徑、絕對(duì)路徑相關(guān)問(wèn)題

    解決vue單頁(yè)面應(yīng)用打包后相對(duì)路徑、絕對(duì)路徑相關(guān)問(wèn)題

    這篇文章主要介紹了解決vue單頁(yè)面應(yīng)用打包后相對(duì)路徑、絕對(duì)路徑相關(guān)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • 關(guān)于axios配置多個(gè)請(qǐng)求地址(打包后可通過(guò)配置文件修改)

    關(guān)于axios配置多個(gè)請(qǐng)求地址(打包后可通過(guò)配置文件修改)

    這篇文章主要介紹了關(guān)于axios配置多個(gè)請(qǐng)求地址(打包后可通過(guò)配置文件修改),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 一文教你vue3 watch如何停止監(jiān)視

    一文教你vue3 watch如何停止監(jiān)視

    這篇文章主要為大家詳細(xì)介紹了vue3中watch如何停止監(jiān)視,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • Element-plus使用中遇到的問(wèn)題小結(jié)

    Element-plus使用中遇到的問(wèn)題小結(jié)

    表格數(shù)據(jù)是websocket通信獲取的數(shù)據(jù),首次獲取20條數(shù)據(jù),以后新增訂閱獲取一條,新增一條則向上滑動(dòng)顯示最新數(shù)據(jù),本文給大家介紹Element-plus使用中遇到的問(wèn)題小結(jié),感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Vue通過(guò)字符串關(guān)鍵字符實(shí)現(xiàn)動(dòng)態(tài)渲染input輸入框

    Vue通過(guò)字符串關(guān)鍵字符實(shí)現(xiàn)動(dòng)態(tài)渲染input輸入框

    這篇文章主要為大家詳細(xì)介紹了Vue如何通過(guò)字符串關(guān)鍵字符實(shí)現(xiàn)動(dòng)態(tài)渲染input輸入框。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-12-12
  • vue.js打包項(xiàng)目后頁(yè)面出現(xiàn)空白的解決辦法

    vue.js打包項(xiàng)目后頁(yè)面出現(xiàn)空白的解決辦法

    這篇文章主要介紹了vue.js打包項(xiàng)目后頁(yè)面出現(xiàn)空白的解決辦法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-11-11
  • vue如何調(diào)用瀏覽器分享功能詳解

    vue如何調(diào)用瀏覽器分享功能詳解

    這篇文章主要給大家介紹了關(guān)于vue如何調(diào)用瀏覽器分享的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 詳解vue父子組件間傳值(props)

    詳解vue父子組件間傳值(props)

    本篇文章主要介紹了詳解vue父子組件間傳值(props),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • 五分鐘理解keep?alive用法及原理

    五分鐘理解keep?alive用法及原理

    這篇文章主要為大家介紹了keep?alive用法及原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評(píng)論

视频| 巩义市| 东兴市| 葫芦岛市| 钟祥市| 隆子县| 汨罗市| 金溪县| 西乌珠穆沁旗| 营山县| 陆川县| 法库县| 东丽区| 冕宁县| 象山县| 洛浦县| 通许县| 常德市| 新疆| 莱芜市| 洪洞县| 云阳县| 喀喇沁旗| 金堂县| 邯郸县| 开封县| 施秉县| 吉林市| 汶上县| 肃南| 响水县| 稷山县| 瑞金市| 雷波县| 宜川县| 池州市| 南召县| 革吉县| 临泽县| 永修县| 龙山县|