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

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

 更新時(shí)間:2022年09月15日 16:16:47   作者:韓振方  
這篇文章主要介紹了Vue3?實(shí)現(xiàn)一個(gè)自定義toast?小彈窗,本文通過實(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è)之前一直沒有辦法解決,所以干脆自己手寫了一個(gè)使用方法高度類似ionic_Toast的組件。

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

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

下面是正文:

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

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

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

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

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

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

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

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

官方在上文也提到了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的語法題而已,僅此而已,并沒有什么特別之處。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

來驗(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è)定寬度呢?我們來給它設(shè)定100px的寬度。

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

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

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

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

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

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

四. Toast居中的思路

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

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

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

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

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

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

我們就可以在后面給這個(gè)組件傳遞參數(shù)來控制具體的位置在哪里。 這個(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的,但是我們最終展示到頁面的是真實(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的渲染過程,所以我們也同時(shí)需要用到這個(gè)函數(shù)。

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

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

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

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

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

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

但是好像不太對(duì)勁啊,怎么報(bào)錯(cuò)了呢?看一下報(bào)錯(cuò)信息,原來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ù)需要。(想更深入了解原理的可以翻看源碼,不再過多贅述。)

七. 如何傳遞props?

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

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

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

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

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

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

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

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

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

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

然后在App.vue文件引入

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

效果如下:

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

十一. 增加淡出的效果

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

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

這里需要注意??!你的動(dòng)畫持續(xù)時(shí)間要和dismiss()函數(shù)的setTimeout參數(shù)一致,不然會(huì)出現(xiàn)意想不到的效果。動(dòng)畫結(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)插件,通常用來校驗(yàn)語法或代碼的書寫風(fēng)格。這篇文章主要介紹了vue項(xiàng)目關(guān)閉eslint校驗(yàn),需要的朋友可以參考下
    2018-03-03
  • 解決vue單頁面應(yīng)用打包后相對(duì)路徑、絕對(duì)路徑相關(guān)問題

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

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

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

    這篇文章主要介紹了關(guān)于axios配置多個(gè)請(qǐng)求地址(打包后可通過配置文件修改),具有很好的參考價(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使用中遇到的問題小結(jié)

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

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

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

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

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

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

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

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

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

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

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

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

最新評(píng)論

眉山市| 清丰县| 宣汉县| 陇西县| 大渡口区| 定边县| 岳池县| 丰县| 麟游县| 江北区| 绥滨县| 广元市| 璧山县| 泸州市| 祁连县| 镇宁| 西贡区| 宁蒗| 望都县| 南平市| 台前县| 西峡县| 开阳县| 汉寿县| 建宁县| 鄱阳县| 乌拉特前旗| 佛坪县| 都安| 锡林浩特市| 广昌县| 连云港市| 荆州市| 通榆县| 怀仁县| 大渡口区| 绥宁县| 成安县| 丹江口市| 长阳| 上思县|