版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第vue3使用自定義指令實(shí)現(xiàn)eldialog拖拽功能示例詳解目錄實(shí)現(xiàn)el-dialog的拖拽功能通過自定義指令實(shí)現(xiàn)拖拽功能實(shí)現(xiàn)拖拽功能使用方式
實(shí)現(xiàn)el-dialog的拖拽功能
這里指的是element-plus的el-dialog組件,一開始該組件并沒有實(shí)現(xiàn)拖拽的功能,當(dāng)然現(xiàn)在可以通過設(shè)置屬性的方式實(shí)現(xiàn)拖拽。
自帶的拖拽功能非常嚴(yán)謹(jǐn),拖拽時判斷是否拖拽出窗口,如果出去了會阻止拖拽。
如果自帶的拖拽功能可以滿足需求的話,可以跳過本文。
通過自定義指令實(shí)現(xiàn)拖拽功能
因?yàn)橐约翰僮鱠om(設(shè)置事件),所以感覺還是使用自定義指令更直接一些,而且對原生組件的影響更小。
我們先定義一個自定義指令_dialogDrag:
importdialogDragfrom'./_dialog-drag'
import{watch}from'vue'
const_dialogDrag={
//mounted
mounted(el:any,binding:any){
//監(jiān)聽dialog是否顯示的狀態(tài)
watch(binding.value,()={
//dialog不可見,退出
if(!binding.value.visible)return
//尋找el-dialog組件
constcontainer=el.firstElementChild.firstElementChild
//已經(jīng)設(shè)置拖拽事件,退出
if(container.onmousemove)return
//等待DOM渲染完畢
setTimeout(()={
//拖拽的“句柄”
const_dialogTitle=el.getElementsByClassName('el-dialog__header')
if(_dialogTitle.length===0){
//還沒有渲染完畢,或則其他原因
console.warn('沒有找到要拖拽的el-dialog',el)
}else{
const{setDialog}=dialogDrag()
constdialogTitle=_dialogTitle[0]
//彈窗
constdialog=el.firstElementChild.firstElementChild.firstElementChild
//通過css尋找el-dialog設(shè)置的寬度
constarr=dialog.style.cssText.split(';')
constwidth=arr[0].replace('%','').replace('--el-dialog-width:','')//
//設(shè)置el-dialog組件、彈窗、句柄、寬度
setDialog(container,dialog,dialogTitle,width)
},300)
*注冊拖拽dialog的自定義指令
*@paramapp
*@paramoptions
constinstall=(app:any,options:any)={
app.directive('dialogDrag',_dialogDrag)
export{
_dialogDrag,
install
這里有兩個比較煩人的地方:
DOM渲染完畢的時機(jī)。執(zhí)行mounted的時候,DOM不一定渲染完畢,如果不使用setTimeout的話,就會找不到DOM,所以用了這種笨辦法。dialog的隱藏。一般情況下,el-dialog初始是隱藏狀態(tài),隱藏了就意味著DOM并不會被渲染出來??墒亲远x指令會在一開始即被執(zhí)行,這時setTimeout的等待時間再長也無用,所以只好監(jiān)聽dialog的狀態(tài)。ref通過template傳遞后,再次傳入組件的話,就會失去ref的那一層的響應(yīng)性,所以只能傳入reactive才行,這樣調(diào)用指令的組件,就會比較別扭,目前沒有想到更好的實(shí)現(xiàn)方式。
實(shí)現(xiàn)拖拽功能
定義指令和實(shí)現(xiàn)拖拽,我分成了兩個文件,我想,盡量解耦一下。
定義一個拖拽函數(shù)(dialogDrag):
/**
*拖拽dialog的函數(shù),目前支持element-plus
exportdefaultfunctiondialogDrag(){
*設(shè)置拖拽事件
*@paramcontainer大容器,比如蒙版。
*@paramdialog被拖拽的窗口
*@paramdialogTitle拖拽的標(biāo)題
*@paramwidth寬度比例
constsetDialog=(container:any,dialog:any,dialogTitle:any,width:number)={
constoldCursor=dialogTitle.style.cursor
//可視窗口的寬度
constclientWidth=document.documentElement.clientWidth
//可視窗口的高度
constclientHeight=document.documentElement.clientHeight
//根據(jù)百分?jǐn)?shù)計算寬度
consttmpWidth=clientWidth*(100-width)/200
//默認(rèn)寬度和高度
constdomset={
x:tmpWidth,
y:clientHeight*15/100//根據(jù)15vh計算
//查看dialog當(dāng)前的寬度和高低
if(dialog.style.marginLeft===''){
dialog.style.marginLeft=domset.x+'px'
}else{
domset.x=dialog.style.marginLeft.replace('px','')*1
if(dialog.style.marginTop===''){
dialog.style.marginTop=domset.y+'px'
}else{
domset.y=dialog.style.marginTop.replace('px','')*1
//記錄拖拽開始的光標(biāo)坐標(biāo),0表示沒有拖拽
conststart={x:0,y:0}
//移動中記錄偏移量
constmove={x:0,y:0}
//經(jīng)過時改變鼠標(biāo)指針形狀
dialogTitle.onmouseover=()={
dialogTitle.style.cursor='move'//改變光標(biāo)形狀
//鼠標(biāo)按下,開始拖拽
dialogTitle.onmousedown=(e:any)={
start.x=e.clientX
start.y=e.clientY
dialogTitle.style.cursor='move'//改變光標(biāo)形狀
//鼠標(biāo)移動,實(shí)時跟蹤dialog
container.onmousemove=(e:any)={
if(start.x===0){//不是拖拽狀態(tài)
return
move.x=e.clientX-start.x
move.y=e.clientY-start.y
//初始位置+拖拽距離
dialog.style.marginLeft=(domset.x+move.x)+'px'
dialog.style.marginTop=(domset.y+move.y)+'px'
//鼠標(biāo)抬起,結(jié)束拖拽
container.onmouseup=(e:any)={
if(start.x===0){//不是拖拽狀態(tài)
return
move.x=e.clientX-start.x
move.y=e.clientY-start.y
//記錄新坐標(biāo),作為下次拖拽的初始位置
domset.x+=move.x
domset.y+=move.y
dialogTitle.style.cursor=oldCursor
dialog.style.marginLeft=domset.x+'px'
dialog.style.marginTop=domset.y+'px'
//結(jié)束拖拽
start.x=0
return{
setDialog//設(shè)置
首先觀察el-dialog渲染后的DOM結(jié)構(gòu),發(fā)現(xiàn)是通過marginLeft、marginTop這兩個css的屬性,那么我們的拖拽也可以通過修改這兩個屬性來實(shí)現(xiàn)。
然后就是古老的拖拽思路:按下鼠標(biāo)的時候,記錄光標(biāo)的初始坐標(biāo),抬起鼠標(biāo)的時候,記錄光標(biāo)的結(jié)束坐標(biāo),然后計算一下得到x、y的偏移量,進(jìn)而修改marginLeft、marginTop這兩個屬性,即可實(shí)現(xiàn)拖拽的效果。
核心思路就是這樣,剩下的就是細(xì)節(jié)完善了。
還有一個小問題,拖拽后關(guān)閉,然后再次打開,希望可以在拖拽結(jié)束的地方打開,而不是默認(rèn)的位置。所以又想了個辦法記錄這個位置。
還是要觀察el-dialog的行為,最后發(fā)現(xiàn)規(guī)律,一開始marginLeft是空的,而拖拽后會保留位置。所以,判斷一下就好。
使用方式
原本想直接給el-dialog設(shè)置自定義指令,但是發(fā)現(xiàn)無效,所以只好在外面套個div。
template
!--拖拽--
el-button@click="dialog.visible=true"打開/el-button
divv-dialog-drag="dialog"
el-dialog
v-model="dialog.visible"
title="自定義拖拽2"
width="25%"
span拖拽測試/span
template#footer
span
el-button@click="dialog.visible=false"Cancel/el-button
el-buttontype="primary"@click="dialog.visible=false"Confirm/el-button
/span
/template
/el-dialog
/div
/template
scriptlang="ts"
import{defineComponent,ref,reactive}from'vue'
import{_dialogDrag}from'../../../lib/main'
exportdefaultdefineComponent({
name:'nf-dialog-move',
directives:{
dialogDrag:_dialogDrag
props:{
setup(props,context){
constdialog=reactive({
visible:false
return{
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 學(xué)校課題活動策劃方案(3篇)
- 2026烏魯木齊市第三十六中學(xué)誠聘初高中教師(18人)參考考試題庫及答案解析
- 2026浙江臺州市緊急救援中心招聘編制外人員1人參考考試題庫及答案解析
- 2026年甘肅省慶陽市西峰環(huán)宇中學(xué)春季招聘教師備考考試題庫及答案解析
- 2026泰安岱岳區(qū)事業(yè)單位初級綜合類崗位招聘工作人員(99人)考試備考試題及答案解析
- 2026廣東中山市東鳳鎮(zhèn)佛奧幼兒園教職工招聘2人筆試模擬試題及答案解析
- 2026中鐵建昆侖高速公路運(yùn)營管理有限公司德遂高速公路路巡隊員招聘1人(重慶)參考考試題庫及答案解析
- 2026上半年玉溪師范學(xué)院招聘6人參考考試題庫及答案解析
- 第四單元7靜夜思
- 三臺公安公開招聘60名警務(wù)輔助人員備考考試試題及答案解析
- 四川省南充市2024-2025學(xué)年高一上學(xué)期期末質(zhì)量檢測英語試題(含答案無聽力原文及音頻)
- 專題08解題技巧專題:圓中輔助線的作法壓軸題三種模型全攻略(原卷版+解析)
- 2024年全國職業(yè)院校技能大賽(節(jié)水系統(tǒng)安裝與維護(hù)賽項)考試題庫(含答案)
- 24秋人教版英語七上單詞表(Vocabulary in Each Unit)總表
- ISO 15609-1 2019 金屬材料焊接工藝規(guī)程和評定-焊接工藝規(guī)程-電弧焊(中文版)
- 肥胖患者麻醉管理
- 小鯉魚跳龍門電子版
- 2019年急性腦梗死出血轉(zhuǎn)化專家共識解讀
- 《混凝土結(jié)構(gòu)工程施工規(guī)范》
- 土地證延期申請書
- 硫乙醇酸鹽流體培養(yǎng)基適用性檢查記錄
評論
0/150
提交評論