您好,登錄后才能下訂單哦!
小編這次要給大家分享的是如何實現vue模塊移動組件,文章內容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
一直都想實現類似于五百丁中簡歷填寫中模塊跟隨鼠標移動的組件,最近閑來無事,自己琢磨實現了一個差不多的組件。
其中每個模塊都是組件調入(項目經驗、教育經驗、工作經驗等),所以這里也用到了動態加載組件方式。
思路:鼠標移入模塊,顯示相應模塊的點擊移動按鈕,點擊A模塊移動按鈕,此時原先A模塊所在的位置上變為拖動到這里綠框模塊,同時鼠標下懸浮著A模塊,鼠標移動,懸浮的A模塊跟隨移動,綠框也跟隨上下移動。
父組件
1、父組件template中的代碼
<div class="component-box" ref="compBox"> <component v-for="(item, index) in comRoute" :is="item" :key="index" @getData="getData"> </component> <div :class="['translate-box', {'move-icon':transType}]" ref="translateBox" v-if="transType"> <component :is="transCom"></component> </div> </div>
2、data中定義的屬性
comList: ['educationExp', 'workExp', 'projectExp'], // 模塊列表 comLen: 0, // 模塊的長度 comType: '', // 當前移動的模塊 transType: '', // 當前移動的模塊 coordinate: { // 鼠標坐標 mouseX: 0, mouseY: 0, }, downFlag: false, // 當前是否點擊模塊移動 mouseYBefore: 0, // 記錄鼠標點擊時Y坐標以及鼠標每移動30后重新記錄鼠標Y坐標 mouseYLast: 0, // 實時記錄鼠標移動時的Y坐標 nowCom: '', // 移動模塊時,上一個模塊或者下一個模塊的名稱 forFlage: false, // forEach遍歷結束的標識 comRoute: [], // 動態加載組件列表 transCom: null, // 點擊后懸浮的組件 compBox: null, // 獲取當前組件在頁面中的位置信息
3、scrollTop為頁面滾動的距頂部的距離,從父組件傳過來
props: { scrollTop: Number,}
4、watch一些屬性
watch: { comList: { handler(val) { this.getCom(val); // 模塊列表改變時,實時加載組件 }, deep: true, immediate: true, // 聲明了之后會立馬執行handler里面的函數 }, transType(val) { // 懸浮模塊加載組件 if (val) { this.transCom = () => import(`./default/${val}`); } }, scrollTop: { // 監聽頁面滾動 handler() {}, immediate: true, }, comType(newVal) { if (newVal) { this.comList.forEach((item, index) => { if (item === newVal) { this.comList[index] = 'moveBox'; // 將組建列表中為comType的元素改為moveBox組件 } }); this.getCom(this.comList); } }, downFlag(newVal) { // 鼠標已經點擊 const nowThis = this; document.onmousemove = function (e) { if (newVal) { // 鼠標移動賦值 nowThis.coordinate.mouseX = e.clientX; nowThis.coordinate.mouseY = e.clientY; } }; document.onmouseup = function () { // 鼠標松開 document.onmousemove = null; if (newVal) { nowThis.transType = ''; // 懸浮組件置空 nowThis.comList.forEach((item, index) => { if (item === 'moveBox') { // 尋找moveBox所在位置 nowThis.comList[index] = nowThis.comType; // 還原成點擊組件 } }); nowThis.downFlag = false; nowThis.comType = ''; nowThis.getCom(nowThis.comList); } }; }, coordinate: { handler(newVal) { // 懸浮組件位置 this.$refs.translateBox.style.top = `${newVal.mouseY + this.scrollTop - 40 - this.compBox.y}px`; this.$refs.translateBox.style.left = `${newVal.mouseX - this.compBox.x - 200}px`; this.mouseYLast = newVal.mouseY; }, deep: true, }, mouseYLast(newVal) { // 鼠標移動Y坐標 this.forFlage = false; if (newVal - this.mouseYBefore > 30) { // 移動30鼠標向下移,每移動30,moveBox移動一次 this.comList.forEach((item, index) => { if (item === 'moveBox' && index < this.comLen - 1 && !this.forFlage) { this.nowCom = this.comList[index + 1]; this.$set(this.comList, index + 1, 'moveBox'); this.$set(this.comList, index, this.nowCom); this.mouseYBefore = newVal; this.forFlage = true; } }); } else if (newVal - this.mouseYBefore < -30) { // 鼠標向上移 this.comList.forEach((item, index) => { if (item === 'moveBox' && index > 0 && !this.forFlage) { this.nowCom = this.comList[index - 1]; // this.comList[index - 1] = 'moveBox'; // this.comList[index] = this.nowCom; // this.comList[index]數組中采用這種方式賦值,vue是不能檢測到數組的變動的 this.$set(this.comList, index - 1, 'moveBox'); this.$set(this.comList, index, this.nowCom); this.mouseYBefore = newVal; this.forFlage = true; } }); } }, },
其中 forFlage的作用是,在forEach中不能使用break這樣來結束循環,所以用forFlage來表示,當遍歷到moveBox后, 就結束遍歷
5、methods
methods: { getCom(val) { this.comRoute = []; val.forEach((item) => { this.comRoute.push(() => import(`./default/${item}`)); }); }, getData(data, dataY, dataX) { // 模塊組件點擊后,父組件中調用此方法,并傳值過來 this.comType = data; this.transType = data; // 目前考慮點擊后立即移動,點擊不移動的情況后期再考慮 this.downFlag = true; this.mouseYBefore = dataY; this.$nextTick(() => { this.$refs.translateBox.style.top = `${dataY + this.scrollTop - 40 - this.compBox.y}px`; this.$refs.translateBox.style.left = `${dataX - this.compBox.x - 200}px`; }); }, },
6、mounted
mounted() { this.comLen = this.comList.length; this.compBox = this.$refs.compBox.getBoundingClientRect(); const that = this; window.onresize = () => (() => { that.compBox = this.$refs.compBox.getBoundingClientRect(); })(); },
子組件
1、子組件template代碼
<div class="pad-box hover-box name-box"> <p class="absolute-box"> <i class="el-icon-rank operation-icon move-icon" @mousedown="mouseDown"></i> <i class="el-icon-circle-plus operation-icon"></i> <i class="el-icon-s-tools operation-icon"></i> </p> 教育經驗 </div>
2、script
export default { name: 'educationExp', data() { return { comType: 'educationExp', mouseYBefore: 0, mouseXBefore: 0, }; }, methods: { mouseDown(e) { this.mouseYBefore = e.clientY; this.mouseXBefore = e.clientX; this.$emit('getData', this.comType, this.mouseYBefore, this.mouseXBefore); }, }, };
看完這篇關于如何實現vue模塊移動組件的文章,如果覺得文章內容寫得不錯的話,可以把它分享出去給更多人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。