Vue開發(fā)實(shí)現(xiàn)滑動(dòng)驗(yàn)證組件
簡述
在開始開發(fā)工作之前,我們有必要先了解一下相關(guān)Javascript函數(shù),方便我們后續(xù)的開發(fā)工作
在PC端
我們經(jīng)常使用鼠標(biāo)相關(guān)的事件來進(jìn)行交互。下面是一些常見的鼠標(biāo)事件:
click:當(dāng)用戶點(diǎn)擊鼠標(biāo)左鍵時(shí)觸發(fā)。dblclick:當(dāng)用戶雙擊鼠標(biāo)左鍵時(shí)觸發(fā)。mousedown:當(dāng)用戶按下鼠標(biāo)按鈕時(shí)觸發(fā)。mouseup:當(dāng)用戶釋放鼠標(biāo)按鈕時(shí)觸發(fā)。mousemove:當(dāng)用戶移動(dòng)鼠標(biāo)時(shí)觸發(fā)。mouseover:當(dāng)用戶將鼠標(biāo)移動(dòng)到元素上方時(shí)觸發(fā)。mouseout:當(dāng)用戶將鼠標(biāo)移出元素時(shí)觸發(fā)。
這些事件可以通過JavaScript來進(jìn)行處理。我們可以使用事件監(jiān)聽器將特定的事件與特定的元素關(guān)聯(lián)起來,從而在事件觸發(fā)時(shí)執(zhí)行相應(yīng)的操作。
此外,在一些庫和框架中,可能還會(huì)有更多的鼠標(biāo)相關(guān)事件和功能可供使用。例如,一些圖形庫可能提供鼠標(biāo)繪圖功能,而一些游戲引擎可能提供鼠標(biāo)控制功能,當(dāng)然這些不是我寫這篇文章所要說的,就簡單的從鼠標(biāo)滑動(dòng)驗(yàn)證開始,凡事必先利其器,方能有效地使用鼠標(biāo)事件來進(jìn)行交互。
但是有時(shí)候,我們有些用戶會(huì)通過移動(dòng)端(如手機(jī)、ipad等)用手觸控的方式去訪問PC網(wǎng)站的時(shí)候,鼠標(biāo)事件就不起作用。所以要考慮到一些兼容的情況,那么就有了下面關(guān)于移動(dòng)端的內(nèi)容
在移動(dòng)端
如觸摸(touch)、滑動(dòng)(swipe)、捏合(pinch) 等,是用來與移動(dòng)設(shè)備進(jìn)行互動(dòng)的重要手段 而我主要總結(jié)下觸摸相關(guān),并且待會(huì)用于開發(fā)滑動(dòng)驗(yàn)證組件的方法,如下:
常見的觸摸相關(guān)事件包括以下幾種:
touchstart:當(dāng)手指觸摸屏幕時(shí)觸發(fā),即手指接觸到觸摸表面。touchmove:當(dāng)手指在屏幕上移動(dòng)時(shí)觸發(fā),即手指在觸摸表面上滑動(dòng)。touchend:當(dāng)手指從屏幕上離開時(shí)觸發(fā),即手指離開觸摸表面。touchcancel:在手指移動(dòng)過程中,如果有其他事件(如電話呼入)發(fā)生,會(huì)觸發(fā)該事件,取消當(dāng)前觸摸過程。touchenter:當(dāng)手指觸摸到某個(gè)元素時(shí)觸發(fā),即手指進(jìn)入元素所在區(qū)域。touchleave:當(dāng)手指從某個(gè)元素上離開時(shí)觸發(fā),即手指離開元素所在區(qū)域。
通過監(jiān)聽這些觸摸事件,我們可以實(shí)現(xiàn)不同的交互效果和功能,比如通過滑動(dòng)事件來實(shí)現(xiàn)輪播圖、通過長按事件來實(shí)現(xiàn)彈出菜單,當(dāng)然也可以來實(shí)現(xiàn)驗(yàn)證組件。同時(shí),還可以通過事件對(duì)象獲取觸摸點(diǎn)的坐標(biāo)信息,從而精確地處理觸摸操作。好了,廢話不多說,我們開始著眼于開發(fā)工作
滑動(dòng)驗(yàn)證組件
先上成型的滑動(dòng)組件效果圖
第一張命名為:png1

第二張命名為:png2

JYM看了這兩張圖后,可能覺得少了那么一些花里胡哨,看起來好像也蠻簡單的。但是嘛,涉及到的知識(shí)點(diǎn)也不少。 我們先來梳理一下開發(fā)思路:
思路梳理
- 定義組件結(jié)構(gòu):確定滑動(dòng)驗(yàn)證組件的整體結(jié)構(gòu),可以使用HTML和CSS來布局和樣式化組件。一般包括一個(gè)容器用于顯示滑塊和背景,一個(gè)滑塊用于拖動(dòng),以及一個(gè)按鈕用于觸發(fā)驗(yàn)證。
- 實(shí)現(xiàn)滑塊拖動(dòng)功能:通過監(jiān)聽觸摸事件或鼠標(biāo)事件,實(shí)現(xiàn)滑塊的拖動(dòng)功能。可以使用JavaScript來獲取觸摸或鼠標(biāo)事件的坐標(biāo)信息,并根據(jù)拖動(dòng)距離來改變滑塊的位置。
- 添加驗(yàn)證邏輯:當(dāng)滑塊被拖動(dòng)到預(yù)定位置時(shí),需要觸發(fā)驗(yàn)證邏輯。可以定義一個(gè)閾值,當(dāng)滑塊的位置超過閾值時(shí),認(rèn)為驗(yàn)證成功??梢允褂肑avaScript來判斷滑塊位置是否超過閾值,并觸發(fā)驗(yàn)證結(jié)果。
- 添加反饋效果:根據(jù)驗(yàn)證結(jié)果,可以添加相應(yīng)的反饋效果,比如驗(yàn)證成功時(shí)顯示成功提示,驗(yàn)證失敗時(shí)顯示失敗提示??梢允褂肅SS動(dòng)畫或Class切換來實(shí)現(xiàn)反饋效果的顯示與隱藏。
- 提供可配置選項(xiàng):為了滿足不同場(chǎng)景的需求,可以為組件提供一些可配置的選項(xiàng),例如滑塊的占比、滑塊背景的顏色、驗(yàn)證成功提示的內(nèi)容等。
- 添加事件回調(diào):為了讓開發(fā)者能夠在驗(yàn)證成功或失敗后執(zhí)行相應(yīng)的處理邏輯,可以為組件提供事件回調(diào)函數(shù),例如驗(yàn)證成功回調(diào)和驗(yàn)證失敗回調(diào)。
代碼實(shí)現(xiàn)
第一步:定義組件結(jié)構(gòu)
<div class="drag">
<div class="bg" />
<div class="text" @selectstart="sotp">
<img v-if="success" src="@/assets/icon/login_icon_successful.png" width="16px" />
{{ tips }}
</div>
<div class="btn" />
</div>并用CSS來布局和樣式化
const oDarg = getDom('.drag');
const oBg = getDom('.bg');
const oText = getDom('.text');
const oBtn = getDom('.btn');
oBtn.style.left = 0;
oBg.style.width = 0;
oBg.style.transition = 'width 1s ease';
oBtn.style.transition = 'left 1s ease';
tips.value = '滑動(dòng)驗(yàn)證';
success.value = false;
oText.style.color = '#666666';
oText.style.background = '#E5E5E5';第二步:實(shí)現(xiàn)滑塊拖動(dòng)功能
通過監(jiān)聽觸摸事件或鼠標(biāo)事件,實(shí)現(xiàn)滑塊的拖動(dòng)功能,如下:
// PC端事件
// 鼠標(biāo)按下事件
oBtn.onmousedown = function (eve) {
console.log('叮咚');
// const phone = _this.form.getFieldValue('phone')
// const password = _this.form.getFieldValue('password')
// if (!phone || !password) {
// _this.$message.info(_this.$t('msg.telPsw'))
// return false
// }
// this.isMouseUp = false
oText.style.background = 'none';
oBg.style.transition = '';
oBtn.style.transition = '';
const e = eve || window.event;
const downX = e.clientX;
// eslint-disable-next-line no-unused-vars
let successPan = false; // 判斷驗(yàn)證是否成功
const distance = oDarg.offsetWidth - oBtn.offsetWidth; // 驗(yàn)證成功的距離
// 鼠標(biāo)移動(dòng)
document.onmousemove = function (eve) {
console.log('onmousemove');
const e = eve || window.event;
const moveX = e.clientX;
let offsetX = moveX - downX;
if (offsetX > distance) {
offsetX = distance;
} else if (offsetX < 0) {
offsetX = 0;
}
oBtn.style.left = `${offsetX}px`;
oBg.style.width = `${offsetX}px`;
if (offsetX === distance) {
// 判斷驗(yàn)證通過
// _this.tips = _this.$t('login.verificationRes')
tips.value = '驗(yàn)證成功';
success.value = true;
// oBtn.innerHTML = '√'
oText.style.color = '#FFF';
oBtn.style.color = '#4CAF50';
successPan = true; // 驗(yàn)證通過時(shí)的條件
siliding.value = successPan;
console.log(siliding, 'this.siliding');
document.onmousemove = null; // 驗(yàn)證通過后 鼠標(biāo)按下事件和鼠標(biāo)移動(dòng)都沒用了 因此需要清除
oBtn.onmousedown = null;
}
};
// 鼠標(biāo)抬起事件
document.onmouseup = function () {
if (!successPan) {
oBtn.style.left = 0;
oBg.style.width = 0;
oBg.style.transition = 'width 1s ease';
oBtn.style.transition = 'left 1s ease';
}
document.onmousemove = null;
oBtn.onmouseup = null;
};
};其中,onmousemove和onmouseup這兩個(gè)方法,已經(jīng)在簡述中,提過了它的觸發(fā)條件,當(dāng)然也得考慮到移動(dòng)端訪問的情況,
// 移動(dòng)端事件
oBtn.ontouchstart = function (eve) {
console.log('ontouchstart');
// const phone = _this.form.getFieldValue('phone')
// const password = _this.form.getFieldValue('password')
// if (!phone || !password) {
// _this.$message.info(_this.$t('msg.telPsw'))
// return false
// }
this.isMouseUp = false;
oText.style.background = 'none';
oBg.style.transition = '';
oBtn.style.transition = '';
let e = eve || window.event;
// 移動(dòng)端特殊處理
e = 'ontouchstart' in document ? e.touches[0] : e;
const downX = e.clientX;
// eslint-disable-next-line no-unused-vars
let successPan = false; // 判斷驗(yàn)證是否成功
const distance = oDarg.offsetWidth - oBtn.offsetWidth; // 驗(yàn)證成功的距離
// 鼠標(biāo)移動(dòng)
// document => oBtn
oBtn.ontouchmove = function (eve) {
console.log('ontouchmove');
console.log(eve);
let e = eve || window.event;
// 移動(dòng)端特殊處理
e = 'ontouchstart' in document ? e.touches[0] : e;
console.log(e.clientX);
const moveX = e.clientX;
let offsetX = moveX - downX;
if (offsetX > distance) {
offsetX = distance;
} else if (offsetX < 0) {
offsetX = 0;
}
oBtn.style.left = `${offsetX}px`;
oBg.style.width = `${offsetX}px`;
if (offsetX === distance) {
// 判斷驗(yàn)證通過
// _this.tips = _this.$t('login.verificationRes')
// _this.success = true
tips.value = '驗(yàn)證成功';
success.value = true;
// oBtn.innerHTML = '√'
oText.style.color = '#FFF';
oBtn.style.color = '#4CAF50';
successPan = true; // 驗(yàn)證通過時(shí)的條件
siliding.value = successPan;
console.log(siliding.value, 'this.siliding');
// document => oBtn
oBtn.ontouchmove = null; // 驗(yàn)證通過后 鼠標(biāo)按下事件和鼠標(biāo)移動(dòng)都沒用了 因此需要清除
oBtn.ontouchstart = null;
}
};依此類推,在這里就不過的闡述
第三步:添加驗(yàn)證邏輯
當(dāng)滑塊被拖動(dòng)到預(yù)定位置時(shí),需要觸發(fā)驗(yàn)證邏輯,并設(shè)定一個(gè)成功的閾值
const distance = oDarg.offsetWidth - oBtn.offsetWidth; // 驗(yàn)證成功的距離
我這里設(shè)置的閾值是,軌道總長度 - 按鈕總長度。
當(dāng)用戶滑動(dòng)按鈕到達(dá)distance范圍時(shí),只要是小于或等于,都算滑動(dòng)驗(yàn)證成功,并自動(dòng)完成剩余的滑動(dòng)軌跡

第四步:添加反饋效果
給與相應(yīng)的提示和顏色加持


以上就是Vue開發(fā)實(shí)現(xiàn)滑動(dòng)驗(yàn)證組件的詳細(xì)內(nèi)容,更多關(guān)于Vue滑動(dòng)驗(yàn)證組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue @click與@click.native,及vue事件機(jī)制的使用分析
這篇文章主要介紹了vue @click與@click.native,及vue事件機(jī)制的使用分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
vue常用事件v-on:click詳解事件對(duì)象,事件冒泡,事件默認(rèn)行為
這篇文章主要介紹了vue常用事件之v-on:click?以及事件對(duì)象,事件冒泡,事件默認(rèn)行為,其實(shí)v-on后面跟的不止是click事件也可以是其他的事件,用法均相似,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
詳解Vue CLI3配置之filenameHashing使用和源碼設(shè)計(jì)使用和源碼設(shè)計(jì)
這篇文章主要介紹了詳解Vue CLI3配置之filenameHashing使用和源碼設(shè)計(jì)使用和源碼設(shè)計(jì),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
Vue實(shí)現(xiàn)push數(shù)組并刪除的例子
今天小編就為大家分享一篇Vue實(shí)現(xiàn)push數(shù)組并刪除的例子,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11
Vue+Element UI+vue-quill-editor富文本編輯器及插入圖片自定義
這篇文章主要為大家詳細(xì)介紹了Vue+Element UI+vue-quill-editor富文本編輯器及插入圖片自定義,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
vue--點(diǎn)擊當(dāng)前增加class,其他刪除class的方法
今天小編就為大家分享一篇vue--點(diǎn)擊當(dāng)前增加class,其他刪除class的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09

