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

Vue3 實現(xiàn)雙盒子定位Overlay的示例

 更新時間:2020年12月22日 09:11:55   作者:helloCat  
這篇文章主要介紹了Vue3 實現(xiàn)雙盒子定位Overlay的示例,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下

在 Vue 3 中,使用 <Teleport> 可以很優(yōu)雅的把某個組件渲染到根節(jié)點之外的節(jié)點,同時使其渲染的內(nèi)容不喪失響應式和對應的生命周期函數(shù)調(diào)用。那么基于此,用 <Teleport> 實現(xiàn)相對于某一元素的 Overlay 。 實際上,這篇文章跟 Vue3 的關系不大,只是通過 Vue3 講解一類 Overlay 的設計方法。

原理

要實現(xiàn)相對于某一元素的 Overlay 需要依靠兩個元素,Origin 和 Panel,Origin 表示相對于的元素,而 Panel 表示 Overlay 本身,實現(xiàn)方法主要有兩種。

文本流定位法,基于 position 的 absolute 和 relative 特性,將 Panel 形成相對于 Origin 的位置來定位的方式。
Overlay 基于 Origin 做固定偏移的雙盒子定位法,也就是本文需要講解的方法。
實現(xiàn) 首先,通過<Teleport>,能夠建立頂層 Overlay,也就是在根節(jié)點創(chuàng)建一個新的節(jié)點。

setup(_, ctx) {
 const originRef = ref<HTMLElement>();
 const panelRef = ref<HTMLElement>();
 const panelStyle = ref<CSSProperties>({ position: 'absolute' });
 // ...
 return () => (
  <>
   <div ref={originRef}>origin</div>

   <Teleport to="#cdk-overlay-anchor">
     <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, height: '100vh', width: '100vw' pointerEvents: 'none'}}>
      <div ref={panelRef} style={panelStyle.value}>
       <div style={{height: '100px', width: '100px' border: '1px solid black'}} />
      </div>
     </div>
   </Teleport>
  </>
 );
}

拿到這兩者的 dom ref 后,需要通過實時計算 Origin 的盒子的大小和位置,來獲得 Panel 的相對偏移。在 Vue 中,元素只有在 mounted 后才能獲取得到,所以可以通過 composition-api 的 onMouted 來獲取具體元素。然后再在 生命周期中 進行計算。

計算兩個盒子的相對位置

如何計算 Origin 的大小和位置,以及獲取其變化后的監(jiān)聽。Origin 的大小和位置,通過 getBoundingClientRect 這一 API 來獲取,這一就可以開始計算 Overlay 的相對位置。假設我們要把 Overlay 放在 Origin 的正下方,計算函數(shù)應該是這樣的。

const panelStyle = ref<CSSProperties>({ position: 'absolute' });

onMounted(() => {
 const origin = originRef.value;
 const panel = panelRef.value;
 if (!origin || !panel) {
  return ;
 }

 const calculate = () => {
  const rect = origin.getBoundingClientRect();
  // 原點為 origin 元素的底邊中央正下方
  const originX = rect.left + (rect.width / 2);
  const originY = rect.bottom;

  // panel的坐標為到原點的偏移
  const panelRect = panel.getBoundingClientRect();
  const panelX = originX - panelRect.width / 2;
  const panelY = originY;

  // 設置 panel 數(shù)據(jù),觸發(fā)節(jié)點變更
  panelStyle.value.left = `${panelX}px`;
  panelStyle.value.top = `${panelY}px`;
 };
});

當然,你還可以計算各個不同方向的 Panel 坐標(比如,正左、正上、正下等),排列組合一下,一共有種27不同的情況(每個點依賴于兩個變量 X 和 Y;每個變量有三種不同的情況,左、中、右,或者,上、中、下)。

監(jiān)聽盒子的變化

在這里,我們將使用瀏覽器自帶的API 來對他們進行監(jiān)聽。通過 MutationObserver 和 ResizeObserver,可以很輕松的監(jiān)聽 Origin 和 Panel 的大小和位置變化。

首先是監(jiān)聽 Origin 的大小和位置變化,這里采用的是 MutationObserver,因為導致位置變化的原因只能是 style,所以只需要監(jiān)聽 style 的變化即可。

const origin$ = new MutationObserver(calculate);
origin$.observe(origin, {
 // 只需要拿到 attribute 的 style 的變化即可
 attributeFilter: ['style'],
});

Panel 只需要監(jiān)聽其大小的變化,大小變化有一個更加完美的API, ResizeObserver。

const panel$ = new ResizeObserver(calculate);
panel$.observe(panel);

然后,需要在dom銷毀前取消監(jiān)聽。

// dom銷毀前取消監(jiān)聽
onBeforeUnmount(() => {
 origin$.disconnect();
 panel$.disconnect();
});

監(jiān)聽窗口事件

為了能夠正確的獲取變化,我們需要監(jiān)聽兩個事件:resize 和 scroll.

// 為了能夠在滾動事件捕獲前進行計算,帶有滾動條的子元素也會因此觸發(fā)計算
window.addEventListener('scroll', calculate, true);
window.addEventListener('resize', calculate);
最后,仍然要在銷毀前取消事件。

// dom銷毀前取消監(jiān)聽
onBeforeUnmount(() => {
 window.removeEventListener('scroll', calculate, true);
 window.removeEventListener('resize', calculate);
});

至此,已經(jīng)完成基本的雙盒子定位法的 Overlay 的設計。

小結

通過雙盒子定位來構建的 Overlay 能夠有效規(guī)避 CSS 帶來的問題 zindex 等一系列相關的問題,只用通過計算盒子之間的相對偏移,就能讓 Panel 附著于 Origin 上,這樣,實現(xiàn)類似下拉或者 Tooltip 等功能的時候,就會非常有用。同時,附上一個簡單例子,希望能帶來一些啟發(fā)。

以上就是Vue3 實現(xiàn)雙盒子定位Overlay的示例的詳細內(nèi)容,更多關于vue3 實現(xiàn)Overlay的資料請關注腳本之家其它相關文章!

相關文章

  • Vue刷新后頁面數(shù)據(jù)丟失問題的解決過程

    Vue刷新后頁面數(shù)據(jù)丟失問題的解決過程

    在做vue項目的過程中有時候會遇到一個問題,就是進行F5頁面刷新的時候,頁面的數(shù)據(jù)會丟失,這篇文章主要給大家介紹了關于Vue刷新后頁面數(shù)據(jù)丟失問題的解決過程,需要的朋友可以參考下
    2022-11-11
  • 詳解vue-router2.0動態(tài)路由獲取參數(shù)

    詳解vue-router2.0動態(tài)路由獲取參數(shù)

    本篇文章主要介紹了詳解vue-router2.0動態(tài)路由獲取參數(shù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • element-ui時間日期選擇器限制選擇范圍的幾種場景

    element-ui時間日期選擇器限制選擇范圍的幾種場景

    這篇文章主要給大家介紹了關于element-ui時間日期選擇器限制選擇范圍的幾種場景,一般在實際開發(fā)場景中我們需要對時間選擇做一些限制,如不能選擇今天之前的時間、不能選擇今天以后的日期、限制日期不能大于開始日期等等,需要的朋友可以參考下
    2023-08-08
  • 使用Vant如何實現(xiàn)數(shù)據(jù)分頁,下拉加載

    使用Vant如何實現(xiàn)數(shù)據(jù)分頁,下拉加載

    這篇文章主要介紹了使用Vant實現(xiàn)數(shù)據(jù)分頁及下拉加載方式。具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Vue.js組件使用props傳遞數(shù)據(jù)的方法

    Vue.js組件使用props傳遞數(shù)據(jù)的方法

    這篇文章主要為大家詳細介紹了Vue.js組件使用props傳遞數(shù)據(jù)的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • 通過實例講解vue組件之間的傳值

    通過實例講解vue組件之間的傳值

    通過Vuex共享數(shù)據(jù),官方給出的跨多組件傳遞數(shù)據(jù)的解決方案,下面這篇文章主要給大家介紹了關于vue組件之間傳值的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • 親自動手實現(xiàn)vue日歷控件

    親自動手實現(xiàn)vue日歷控件

    這篇文章主要記錄了親自動手實現(xiàn)vue日歷控件的詳細過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • uniapp小程序上傳文件webapi后端項目asp.net完整代碼

    uniapp小程序上傳文件webapi后端項目asp.net完整代碼

    在uniapp中,實現(xiàn)文件上傳功能也變得非常簡單,下面這篇文章主要給大家介紹了關于uniapp小程序上傳文件webapi后端項目asp.net的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-07-07
  • Vue自定義過濾器格式化數(shù)字三位加一逗號實現(xiàn)代碼

    Vue自定義過濾器格式化數(shù)字三位加一逗號實現(xiàn)代碼

    這篇文章主要介紹了Vue自定義過濾器格式化數(shù)字三位加一逗號的實現(xiàn)代碼,需要的朋友可以參考下
    2018-03-03
  • ElementUI中el-tabs事件綁定的具體使用

    ElementUI中el-tabs事件綁定的具體使用

    本文主要介紹了ElementUI中el-tabs事件綁定的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04

最新評論

隆德县| 花垣县| 安化县| 突泉县| 中方县| 乡城县| 凤翔县| 泾川县| 阜阳市| 会同县| 茌平县| 屏东市| 乌拉特后旗| 西宁市| 酉阳| 庆城县| 太湖县| 广南县| 克什克腾旗| 大足县| 乡城县| 永春县| 上杭县| 扬州市| 峨边| 昭通市| 项城市| 三门县| 海阳市| 宿州市| 泉州市| 定襄县| 泾源县| 塘沽区| 曲阜市| 桂林市| 江安县| 通山县| 教育| 铜山县| 南江县|