這里給大家分享我在網(wǎng)上總結(jié)出來的一些知識,希望對大家有所幫助
1. 需求分析
實現(xiàn)一個CMS內(nèi)容管理系統(tǒng),在后臺進行內(nèi)容編輯,在官網(wǎng)更新展示內(nèi)容。
關(guān)于后臺的編輯功能,大致分為兩部分:組件拖拽預(yù)覽
、組件內(nèi)容編輯實時預(yù)覽
。
對于組件拖拽預(yù)覽,用戶可以在含有各種功能組件的列表中,選擇需要的組件進行拖拽。將組件拖拽到預(yù)覽畫布中后,可以在畫布中預(yù)覽組件的內(nèi)容。
對于組件內(nèi)容編輯實時預(yù)覽,用戶可以點擊編輯按鈕,顯示對應(yīng)組件的內(nèi)容編輯信息。當(dāng)修改組件內(nèi)容時,在畫布中可以實時預(yù)覽組件的變化。
2. 實現(xiàn)步驟
2.1 關(guān)于拖拽組件庫的選擇
關(guān)于拖拽組件庫,在github
上有很多,最熱門的當(dāng)屬vuedraggable
這個庫。
它基于Sortable.js
,擁有完整的中文文檔,所以很多朋友在做拖拽功能時,都會優(yōu)先考慮它。
但是,我在使用的過程中,在組件拖拽、取消組件拖拽這里,遇到了一些小問題。不知道是我操作的問題,還是庫本身存在BUG,所以最終沒有選用它。
于是我發(fā)現(xiàn)了,一個更加好用的拖拽庫vue-draggable-next
。
它的出現(xiàn)是參考了vuedraggable
這個庫,所以說很多用法很相似,但是使用起來較之更加友善??偨Y(jié)為一個詞,自由。
下面我們的拖拽功能實現(xiàn),就是利用了vue-draggable-next
這個庫。
如果你對拖拽底層原理感興趣,并且有空余時間,勞請閱至第三部分拖拽原理總結(jié)。
2.2 拖拽功能代碼實例
?
模版和邏輯中代碼都分為了三部分:組件列表
、預(yù)覽畫布
、內(nèi)容編輯
。
布局時,樣式根據(jù)需求自定義,此處只是提供了功能的基本邏輯實現(xiàn)。
使用時,關(guān)于拖拽組件的需求,根據(jù)文檔中提供的屬性和事件的描述,靈活配置完善。
vue-draggable-next
庫文檔地址:https://github.com/anish2690/vue-draggable-next
安裝依賴:
npm?install?vue-draggable-next //or yarn?add?vue-draggable-next
模板代碼:
<template> ??<div?style="display:?flex;cursor:?pointer;"> ????<!--?組件列表?左側(cè)?--> ????<div?style="width:30vw;padding:30px;height:300px;border:?1px?solid?#000;text-align:?center"> ??????<h1>組件列表</h1> ??????<VueDraggableNext?:list="componentNameList"?:group="{?name:?'people',?pull:?'clone',?put:?false?}"?:sort="false"> ????????<div?v-for="element?in?componentNameList"?:key="element.name"> ??????????<div?style="padding:?10px;background:?#ccc;margin-bottom:?10px"> ????????????<el-button>?{{?element.name?}}</el-button> ??????????</div> ????????</div> ??????</VueDraggableNext> ????</div> ????<!--?預(yù)覽畫布?中間?--> ????<div?style="width:30vw;padding:30px;height:300px;border:?1px?solid?#000;text-align:?center"> ??????<h1>預(yù)覽畫布</h1> ??????<VueDraggableNext?:list="componentList"?group="people"?:sort="false"> ????????<div?v-for="(element,?index)?in?componentList"?:key="element.name"> ??????????<div> ????????????<el-button?@click="changeComponent(element)"?size="small">編輯</el-button> ????????????<el-button?@click="deleteComponent(index)"?size="small">刪除</el-button> ??????????</div> ??????????<component?:is="element.component"?:details="element.details"></component> ????????</div> ??????</VueDraggableNext> ????</div> ????<!--?內(nèi)容編輯?右側(cè)?--> ????<div?style="width:30vw;padding:30px;height:300px;border:?1px?solid?#000;text-align:?center"> ??????<h1>內(nèi)容編輯</h1> ??????<div?v-for="(nowDetails,?index)?in?nowComponentDetail.details"?:key="index"> ????????{{?nowDetails.key?}}:?<el-input?clearable?v-model="nowDetails.value"?/> ??????</div> ????</div> ??</div> ?? </template>
<script?setup> import?{markRaw,?reactive,?ref,?watch,?nextTick}?from?"vue"; //?引入需要拖拽的組件 import?About?from?"@/views/AboutView.vue" //?引入拖拽庫 import?{?VueDraggableNext?}?from?"vue-draggable-next"; //?組件列表數(shù)據(jù) const?componentNameList?=?[ ??{ ????//?組件ID ????componentId:0, ????//?組件名 ????name:'關(guān)于組件', ????//?組件描述 ????description:?'關(guān)于組件', ????//?組件信息 ????component:?markRaw(About), ????//?組件需要編輯內(nèi)容 ????details:?About.props.details.default ??}, ??{ ????componentId:1, ????name:'關(guān)于組件1', ????description:?'關(guān)于組件1', ????component:markRaw(About), ????details:?About.props.details.default ??}, ]; //?預(yù)覽畫布數(shù)據(jù) let?componentList?=?reactive([]); watch(componentList,?()?=>?{ ??console.log(componentList,?'componentList') }) //?畫布中刪除的點擊事件 const?deleteComponent?=?(index)?=>?{ ??componentList.splice(index,?1); }; //?內(nèi)容編輯數(shù)據(jù) let?nowComponentDetail?=?ref({}); //?畫布中編輯的點擊事件 const?changeComponent?=?(element)?=>?{ ????nowComponentDetail.value?=?element; }; </script>
2.3?功能組件代碼實例(參考)
此處提供了組件列表中,任意功能組件的編寫實例,組件的具體功能根據(jù)需求自定義。特別注意,組件Props
中details
對象屬性的結(jié)構(gòu)寫法,要靈活應(yīng)用。模版代碼:
<template> ??<div?style="padding:?10px;background:?pink;margin-bottom:?10px"> ????{{?props.details.content?}} ??</div> </template>
邏輯代碼:
<script?setup> import?{?defineProps?}?from?"vue"; const?props?=?defineProps({ ????details:?{ ??????type:?Object, ??????default:?{ ????????content:?{ ??????????key:?'內(nèi)容', ??????????value:?"我是About", ????????}, ????} ??} }) </script>
3. 問題詳解
3.1?拖拽實現(xiàn)的底層原理
拖拽的實現(xiàn)原理可以簡單描述為以下幾個步驟:
-
觸發(fā)拖拽
:通過監(jiān)聽鼠標(biāo)或觸摸事件,當(dāng)用戶按下鼠標(biāo)左鍵或觸摸屏幕時,表示開始拖拽操作。 -
記錄拖拽信息
:在拖拽開始時,記錄拖拽起始位置(鼠標(biāo)或觸摸點的坐標(biāo)),以及需要拖拽的元素的初始位置(相對于文檔的坐標(biāo))。 -
更新拖拽元素位置
:在拖拽過程中,通過監(jiān)聽鼠標(biāo)移動或觸摸滑動事件,計算鼠標(biāo)或觸摸點的當(dāng)前位置,并根據(jù)鼠標(biāo)或觸摸點的位置變化,更新拖拽元素的位置。這可以通過修改元素的 CSS 屬性(如?left?和?top)或使用 CSS 變換(如?translateX?和?translateY)來實現(xiàn)。 -
處理拖拽結(jié)束
:當(dāng)用戶釋放鼠標(biāo)左鍵或觸摸結(jié)束時,表示拖拽結(jié)束。此時可以執(zhí)行一些操作,如更新拖拽元素的最終位置、觸發(fā)事件或回調(diào)函數(shù)等。
以下是拖拽實現(xiàn)的基本原理代碼實例:
//?獲取拖拽元素 const?draggableElement?=?document.getElementById('draggable'); //?記錄拖拽起始位置和拖拽元素的初始位置 let?startX,?startY,?initialX,?initialY; //?監(jiān)聽鼠標(biāo)按下事件 draggableElement.addEventListener('mousedown',?dragStart); draggableElement.addEventListener('touchstart',?dragStart); //?監(jiān)聽鼠標(biāo)移動事件 document.addEventListener('mousemove',?drag); document.addEventListener('touchmove',?drag); //?監(jiān)聽鼠標(biāo)釋放事件 document.addEventListener('mouseup',?dragEnd); document.addEventListener('touchend',?dragEnd); //?拖拽開始事件處理程序 function?dragStart(event)?{ ??event.preventDefault(); ??if?(event.type?===?'touchstart')?{ ????startX?=?event.touches[0].clientX; ????startY?=?event.touches[0].clientY; ??}?else?{ ????startX?=?event.clientX; ????startY?=?event.clientY; ??} ??initialX?=?draggableElement.offsetLeft; ??initialY?=?draggableElement.offsetTop; } //?拖拽事件處理程序 function?drag(event)?{ ??event.preventDefault(); ??if?(event.type?===?'touchmove')?{ ????const?currentX?=?event.touches[0].clientX?-?startX; ????const?currentY?=?event.touches[0].clientY?-?startY; ????draggableElement.style.left?=?initialX?+?currentX?+?'px'; ????draggableElement.style.top?=?initialY?+?currentY?+?'px'; ??}?else?{ ????const?currentX?=?event.clientX?-?startX; ????const?currentY?=?event.clientY?-?startY; ????draggableElement.style.left?=?initialX?+?currentX?+?'px'; ????draggableElement.style.top?=?initialY?+?currentY?+?'px'; ??} } //?拖拽結(jié)束事件處理程序 function?dragEnd()?{ ??//?執(zhí)行拖拽結(jié)束后的操作 }
3.2?關(guān)于vue-draggable-next?庫的功能總結(jié)
?
vue-draggable-next?
庫特點和功能的補充說明:文章來源:http://www.zghlxwxcb.cn/news/detail-760308.html
-
基于 Vue 3
:vue-draggable-next?是為 Vue.js 3 版本設(shè)計的拖拽庫,充分利用了 Vue 3 的響應(yīng)式系統(tǒng)和組合式 API。 -
輕量級和簡單易用
:該庫的代碼量較少,易于理解和使用。它提供了一組簡單的指令和組件,可以輕松地將拖拽功能集成到 Vue.js 應(yīng)用程序中。 -
支持多種拖拽模式
:vue-draggable-next?支持多種拖拽模式,包括自由拖拽、列表拖拽、網(wǎng)格拖拽等。您可以根據(jù)需求選擇適合的拖拽模式。 -
自定義拖拽樣式和行為
:該庫允許您自定義拖拽元素的樣式和行為。您可以定義拖拽時的樣式、占位符元素、限制拖拽的范圍等。 -
事件和回調(diào)支持
:vue-draggable-next?提供了一組事件和回調(diào)函數(shù),可以在拖拽過程中監(jiān)聽和處理各種事件。例如,您可以監(jiān)聽拖拽開始、拖拽結(jié)束、拖拽元素排序等事件,并執(zhí)行相應(yīng)的操作。 -
支持觸摸設(shè)備
:該庫對觸摸設(shè)備提供了良好的支持,可以在移動設(shè)備上實現(xiàn)流暢的拖拽交互。
本文轉(zhuǎn)載于:
https://juejin.cn/post/7297093747703005235
如果對您有所幫助,歡迎您點個關(guān)注,我會定時更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進步。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-760308.html
到了這里,關(guān)于記錄--Vue3問題:如何實現(xiàn)組件拖拽實時預(yù)覽功能?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!