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

Vue拖拽組件開發(fā)實例詳解

 更新時間:2018年05月11日 15:08:51   作者:其實我很乖乖  
本文重點給大家介紹Vue拖拽組件開發(fā)實例,拖拽的原理是手指在移動的過程中,實時改變元素的位置即top和left值,使元素隨著手指的移動而移動。對實例代碼感興趣的朋友跟隨腳本之家小編一起學習吧

為什么選擇Vue?

主要原因:對于前端開發(fā)來說,兼容性是我們必須要考慮的問題之一。我們的項目不需要兼容低版本瀏覽器。項目本身也是一個數(shù)據(jù)驅(qū)動型的。加之,Vue本身具有以下主要特性:

•使用虛擬DOM;
•輕量級框架;
•高效的數(shù)據(jù)綁定;
•靈活的組件系統(tǒng);
•完整的開發(fā)生態(tài)鏈。

這就是我們?yōu)槭裁催x擇Vue框架的一些原因。

為什么要封裝成一個Vue組件?

主要目的是可提高代碼的復用性和可維護性。

•復用性:組件化后,一些樣式和邏輯均通過配置參數(shù)的方式去差異化體現(xiàn),所以參數(shù)的可配置性提高了組件的復用率和靈活性。

•可維護性:組件化后,組件內(nèi)部的邏輯只對組件負責,外部的邏輯只通過配置參數(shù)適配,所以提高了代碼的邏輯清晰度,可以快速定位代碼出現(xiàn)問題的地方。

組件化搭建頁面圖示:

上圖可看出,在Vue中,所謂組件化搭建頁面,簡單來說,頁面實際上是由一個個功能獨立的組件搭建而成。這些組件之間可以組合、嵌套,最終形成了我們的頁面。

組件構成

下面是一個完成的組件構成:

// 組件內(nèi)模板
// 組件內(nèi)邏輯代碼
<script type="text/javascript"></script>
// 組件內(nèi)封裝的樣式
<style lang="scss" scoped></style>

開發(fā)Vue移動拖拽組件為例

拖拽原理

手指在移動的過程中,實時改變元素的位置即top和left值,使元素隨著手指的移動而移動。

拖拽實現(xiàn)

•開始拖動時:獲取到接觸點相對于整個視圖區(qū)的坐標clientX,clientY;獲取元素距離視圖上側(cè)和左側(cè)的距離 initTop,initLeft;計算接觸點距離元素上側(cè)和左側(cè)的距離 elTop = clientY - initTop, elLeft = clientX - initLeft;
•拖動過程中:通過 currTop = clientY - elTop, currLeft = clientX - elLeft實時獲取元素距離視圖上側(cè)和左側(cè)的距離值,并賦值給元素,使元素跟著手指的移動而動起來;
•拖動結(jié)束,定位元素。

Vue中的實現(xiàn)

使用Vue,最大的不同之處是我們幾乎不去操作DOM,要充分利用Vue的數(shù)據(jù)驅(qū)動來實現(xiàn)拖拽功能。本例中,我們只需在垂直方向上拖動元素,所以只需考慮垂直方向的移動即可。

上圖中,通過data中的dragList渲染拖拽區(qū)域列表,代碼如下:

template:
<div class="drag-title">拖拽可調(diào)整順序</div>
<ul class="drag-list">
 <li class="drag-item">{{item.txt}}</li>
</ul>
script:
 
export default {
data() {
return {
dragList:null
}
},
created() {
this.dragList = [
{
isDrag: false,
txt: '列表1',
isShow: false
}
...
]
},
}

假設我們將元素從位置1拖至位置3,本質(zhì)上是數(shù)組的順序發(fā)生了改變。這就有必要提一下Vue的最大特性:數(shù)據(jù)驅(qū)動。

所謂的數(shù)據(jù)驅(qū)動就是當數(shù)據(jù)發(fā)生變化時,通過修改數(shù)據(jù)狀態(tài),使用戶界面發(fā)生相應的改變,開發(fā)者不需要手動的去修改DOM。

Vue的數(shù)據(jù)驅(qū)動是通過MVVM這種框架來實現(xiàn)的,MVVM框架主要包含3個部分:Model、View、Viewmodel。

– Model:數(shù)據(jù)部分;
– View:視圖部分;
– Viewmodel:連接視圖與數(shù)據(jù)的中間件。

順著這個思路走下去,我們知道:

– oldIndex:元素在數(shù)組中的初始索引index;
– elHeight:單個元素塊的高;
– currTop = clientY - elTop:元素在拖動過程中距離可視區(qū)上側(cè)距離;
– currTop - initTop > 0:得知元素是向上拖拽;
– currTop - initTop < 0:得知元素是向下拖拽。

我們以向下拖拽來說:

– 首先,我們要在拖拽結(jié)束事件touchend中判斷元素從拖動開始到拖動結(jié)束時拖動的距離。若小于某個設定的值,則什么也不做;
– 然后,在touchmove事件中判斷,若(currTop - initTop) % elHeight>= elHeight/2成立,即當元素拖至另一個元素塊等于或超過1/2的位置時,即可將元素插入到最新的位置為newIndex = (currTop - initTop) / elHeight + oldIndex。
– 最后,若手指離開元素,那么我們在touchend事件中,通過this.dragList.splice(oldIndex, 1),this.dragList.splice(newIndex, 0, item)重新調(diào)整數(shù)組順序。頁面會根據(jù)最新的dragList渲染列表。

寫到這里,我們儼然已經(jīng)用Vue實現(xiàn)了移動端的拖拽功能。但是拖拽體驗并不好,接下來,我們對它進行優(yōu)化。

優(yōu)化點:我們希望,在元素即將可能落到的位置,提前留出一個可以放得下元素的區(qū)域,讓用戶更好的感知拖拽的靈活性。

方案:(方案已被驗證是可行的)將li的結(jié)構做一下修改,代碼如下:

<ul>
 <li class="drag-item">
<div class="leave-block"></div>
// 向上拖拽時留空
<div class="">{{item.txt}}</div>
<div class="leave-block"></div>
// 向下拖拽時留空</li>
</ul>

•拖拽開始:將元素的定位方式由static設置為absolute,z-index設置為一個較大的值,防止元素二次拖拽無效;

•拖拽過程中:將元素即將落入新位置的那個li下div的item.isShow設置為true,其他li下div的item.isShow均設置為false;

•拖拽結(jié)束:將所有l(wèi)i下div的item.isShow 均設置為false,將元素定位方式由absolute設置為static。

貼一段偽代碼:

touchStart(e){
// 獲取元素距離視口頂部的初始距離
initTop = e.currentTarget.offsetTop;
// 開始拖動時,獲取鼠標距離視口頂部的距離
initClientY = e.touches[0].clientY;
// 計算出接觸點距離元素頂部的距離
elTop = e.touches[0].clientY - initTop;
},
touchMove(index, item, e){
// 將拖拽結(jié)束時,給元素設置的static定位方式移除,防止元素二次拖拽無效
e.target.classList.remove('static');
// 給拖拽的元素設置絕對定位方式
e.target.classList.add('ab');
// 獲取元素在拖拽過程中距離視口頂部距離
currTop = e.touches[0].clientY - elTop;
// 元素在拖拽過程中距離視口頂部距離賦給元素
e.target.style.top = currTop ;
// 獲取元素初始位置
oldIndex = index;
// 獲取拖拽元素
currItem = item;
// 若元素已經(jīng)拖至區(qū)域外
if(e.touches[0].clientY > (this.dragList.length) * elHeight){
// 將元素距離上側(cè)的距離設置為拖動區(qū)視圖的高
currTop = (this.dragList.length) * elHeight;
return;
}
// 向下拖拽
if(currTop > initTop ){
// 若拖拽到大于等于元素的一半時,即可將元素插入到最新的位置
if((currTop - initTop) % elHeight>= elHeight / 2){
// 計算出元素拖到的最新位置
newIndex = Math.round((currTop - initTop) / elHeight) + index;
// 確保新元素的索引不能大于等于列表的長度
if(newIndex < this.dragList.length){
// 將所有列表留空處隱藏
for(var i = 0;i< this.dragList.length;i++){
this.dragList[i].isShow = false;
}
// 將元素即將拖到的新位置的留空展示
this.dragList[newIndex].isShow = true;
}
else {
return;
}
}
}
// 向上拖拽,原理同上
if(currTop < initTop){ ... } }, touchEnd(e){ // 若拖動距離大于某個設定的值,則按照上述,執(zhí)行相關代碼 if(Math.abs(e.changedTouches[0].clientY - initClientY ) > customVal){
this.dragList.splice(oldIndex, 1);
this.dragList.splice(newIndex, 0, currItem);
for(var i = 0;i< this.dragList.length;i++){
this.dragList[i].isShow = false;
this.dragList[i].isShowUp = false;
}
}
e.target.classList.remove('ab');
e.target.classList.add('static');
}

優(yōu)化后,如下圖所示:

以上便是用Vue實現(xiàn)移動端拖拽組件的過程。我們知道,有些項目是需要在PC端用Vue實現(xiàn)此功能。這里簡單提一下PC與移動端的區(qū)別如下:

•PC端可以使用的事件組有兩種:第一種:H5新特性draggable,dragstart,drag,dragend;第二種:mousedown,mousemove,mouseup;

•PC端獲取鼠標坐標是通過e.clientX,clientY,區(qū)別于移動端的e.touches[0].clientX,e.touches[0].clientY。

小結(jié)

本文從Vue拖拽組件開發(fā)為例,剖析Vue組件的結(jié)構、開發(fā)思路、Vue的數(shù)據(jù)驅(qū)動等,對Vue組件化的原理,進行了更深入的理解。 并將Vue實現(xiàn)拖拽的方案提供給大家學習研究。

P.S. 牢記一點,切勿在Vue中過多得操作DOM,要能深入理解Vue數(shù)據(jù)驅(qū)動的核心思想。

相關文章

  • 在vue中使用防抖和節(jié)流,防止重復點擊或重復上拉加載實例

    在vue中使用防抖和節(jié)流,防止重復點擊或重復上拉加載實例

    今天小編就為大家分享一篇在vue中使用防抖和節(jié)流,防止重復點擊或重復上拉加載實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • ElementUI?Upload源碼組件上傳流程解析

    ElementUI?Upload源碼組件上傳流程解析

    這篇文章主要為大家介紹了ElementUI?Upload源碼組件上傳流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Vue3?TypeScript?實現(xiàn)useRequest詳情

    Vue3?TypeScript?實現(xiàn)useRequest詳情

    本文介紹了Vue3?TypeScript實現(xiàn)useRequest詳情,useRequest可能是目前社區(qū)中最強大,最接地氣的請求類?Hooks了??梢愿采w99%的網(wǎng)絡請求場景,無論是讀還是寫,無論是普通請求還是分頁請求,無論是緩存還是防抖節(jié)流,通通都能支持,關于其介紹需要的小伙伴可以參考一下
    2022-05-05
  • 基于vue.js實現(xiàn)的分頁

    基于vue.js實現(xiàn)的分頁

    本文主要給大家介紹基于vue的分頁原生寫法,代碼分為html部分和js部分,簡單易懂,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2018-03-03
  • Vue項目每次發(fā)版后要清理瀏覽器緩存問題解決辦法

    Vue項目每次發(fā)版后要清理瀏覽器緩存問題解決辦法

    最近項目更新頻繁,每次一更新客戶都說還跟之前的一樣,一查原因是因為客戶沒有清空瀏覽器的緩存,所以為了方便客戶看到最新版本,開始調(diào)研再發(fā)布新版本后自動清理緩存,這篇文章主要給大家介紹了關于Vue項目每次發(fā)版后要清理瀏覽器緩存問題的解決辦法,需要的朋友可以參考下
    2024-02-02
  • 在vue中使用vue-echarts-v3的實例代碼

    在vue中使用vue-echarts-v3的實例代碼

    這篇文章主要介紹了在vue中使用vue-echarts-v3的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09
  • Vue3實現(xiàn)Emoji表情的四種方案

    Vue3實現(xiàn)Emoji表情的四種方案

    聊天工具的項目開發(fā)到了表情功能,由于目前會話的輸入?yún)^(qū)域使用的是 textarea 而非富文本編輯器,所以表情功能也需要兼顧 textarea 進行開發(fā),本文給大家簡單聊聊幾種表情的實現(xiàn)方,感興趣的小伙伴一起來看看吧
    2025-01-01
  • Element-plus側(cè)邊欄踩坑的問題解決

    Element-plus側(cè)邊欄踩坑的問題解決

    本文主要介紹了Element-plus側(cè)邊欄踩坑的問題解決,主要解決了el-menu直接嵌套el-menu-item菜單,折疊時不會出現(xiàn)文字顯示和小箭頭無法隱藏的問題,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • Vue?element實現(xiàn)權限管理業(yè)務流程詳解

    Vue?element實現(xiàn)權限管理業(yè)務流程詳解

    目前本人再使用vue-element-admin項目時都是通過直接刪除一些用不上的路由來進行側(cè)邊欄的清除,但是其實有一個更加好的辦法來對項目的側(cè)邊欄顯示的內(nèi)用進行管理,就是權限管理,其實也不知道這個方法好不好,原理上來說時跟直接刪除該路由的方式時一樣的
    2022-08-08
  • VUE中如何優(yōu)雅實現(xiàn)爺孫組件的數(shù)據(jù)通信

    VUE中如何優(yōu)雅實現(xiàn)爺孫組件的數(shù)據(jù)通信

    所謂祖孫組件,也就是3層嵌套的組件,下面這篇文章主要給大家介紹了關于VUE中如何優(yōu)雅實現(xiàn)爺孫組件的數(shù)據(jù)通信的相關資料,需要的朋友可以參考下
    2022-04-04

最新評論

阿城市| 阳原县| 布拖县| 革吉县| 且末县| 金寨县| 金沙县| 鸡东县| 崇仁县| 闻喜县| 江北区| 湘西| 浠水县| 新闻| 阜康市| 彰化市| 容城县| 崇文区| 临高县| 扬中市| 邵东县| 澄江县| 富顺县| 兰州市| 玉山县| 若尔盖县| 马边| 辛集市| 呼伦贝尔市| 宜兰县| 西和县| 志丹县| 泰兴市| 卢湾区| 交城县| 防城港市| 牙克石市| 兴义市| 郴州市| 健康| 鄂伦春自治旗|