vue自定義tap指令及tap事件的實(shí)現(xiàn)
1.Vue指令
Vue提供自定義實(shí)現(xiàn)指令的功能, 和組件類似,可以是全局指令和局部指令,詳細(xì)可以參見vue官網(wǎng)自定義指令一節(jié)(https://cn.vuejs.org/v2/guide/custom-directive.html).
2.v-tap指令實(shí)現(xiàn)
我個人的理解,編寫指令即是在vue指令對象提供的鉤子函數(shù)中做相應(yīng)的邏輯處理,tap指令是在bind鉤子函數(shù)中做相應(yīng)的處理, 首先,要明白的是tap是為了處理click事件在iphone上的存在300ms的延時,這樣使得連續(xù)點(diǎn)擊很不流暢,tap通過移動端的touchstart事件和touchend事件判斷移動距離為零的話,則觸發(fā)綁定的函數(shù),話不多說,上代碼:
Vue.directive('tap',{
bind(el, binding, vNode){
let expression = binding.value;
let handler = expression.name;
let args = expression.args
on(el, 'touchstart', (e)=>{
let startX = e.changedTouches[0].clientX;
let startY = e.changedTouches[0].clientY;
once(el, 'touchend',(ev)=>{
let disX = Math.abs(ev.changedTouches[0].clientX-startX);
let disY = Math.abs(ev.changedTouches[0].clientY-startY);
if(disX == 0 && disY ==0){
handler(args);
}
})
})
}
})
使用示例: <div v-tap="{ name : mymethod, args:{arg1:11, args2:22} }"></div>
3.總結(jié)
當(dāng)我們需要復(fù)用一些dom底層操作的時候,可以考慮使用vue directive的方式復(fù)用代碼.
下面看下vue tap事件的實(shí)現(xiàn)代碼
前兩天做了個tap.js插件,實(shí)現(xiàn)了移動端touch事件模擬click事件,解決點(diǎn)擊延遲的問題,但是在vue中并不能用v-tap來調(diào)用,所以今天做了vue版的vue-tap.js。此前也曾用過其他的插件來實(shí)現(xiàn)v-tap,但方式仍有些累贅,于是便用了更簡潔的方式來實(shí)現(xiàn),下面附上代碼(只支持vue2.0+)。
vue-tap.js
/*!
* vue-tap.js
* by weijianhua https://github.com/weijhfly/vue-tap
*/
;(function (factory) {
if (typeof define === 'function' && define.amd) {
define(function(){return factory;});
}else if (typeof exports == "object") {
module.exports = factory;
}else{
Vue.use(factory);
}
}({
master:{
bind: function (el, binding) {
var isTouch = "ontouchend" in document;
el.exec = function (e) {
var data = binding.value;
data[0].apply(this, data.slice(1));
};
if (isTouch) {
//touchstart
el.addEventListener('touchstart', function (e) {
binding.modifiers.stop && (e.stopPropagation());
var t = e.touches[0];
el.startX = t.clientX;
el.startY = t.clientY;
el.sTime = + new Date;
});
//touchend
el.addEventListener('touchend', function (e) {
binding.modifiers.stop && (e.stopPropagation());
var t = e.changedTouches[0];
el.endX = t.clientX;
el.endY = t.clientY;
if((+ new Date)-el.sTime<300){
if(Math.abs(el.endX-el.startX)+Math.abs(el.endY-el.startY)<20){
e.preventDefault();
el.exec();
}
}
});
}else {
//click
el.addEventListener('click', function (e) {
binding.modifiers.stop && (e.stopPropagation());
el.exec();
});
}
},
componentUpdated : function(el,binding) {
el.exec = function () {
var data = binding.value;
data[0].apply(this, data.slice(1));
};
},
unbind: function (el) {
el.exec = null;
}
},
install:function(){
Vue.directive('tap', this.master);
}
}))
demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1.0, user-scalable=0" />
<title>vue plugin test</title>
<style type="text/css">
strong{
font-size: 15px;
}
pre{
padding: 16px 0;
overflow: auto;
line-height: 1.45;
background-color: #f6f8fa;
border-radius: 3px;
}
</style>
</head>
<body style="padding:30px;">
<div id="app">
<pre>
<strong>vue-tap.js</strong>
<b>簡潔的調(diào)用方式:</b>
v-tap="[方法,參數(shù)一,參數(shù)二...]"
<b>獲取參數(shù):</b>
methods:{
tap:function(參數(shù)一,參數(shù)二...){
console.log(參數(shù)一,參數(shù)二...);
}
}
<b>阻止冒泡:</b>
v-tap.stop
</pre>
<hr>
<div v-for="(l,i) in list">
<div v-tap="[tap,l,i]">li-{{l}}-{{i}}</div>
</div>
<br>
<hr>
<div v-tap="[test,'parent']">
parent<br><br>
<button v-tap.stop="[test,'son']">stop propagation</button>
</div>
</div>
<script src="https://cdn.bootcss.com/vue/2.5.13/vue.js"></script>
<script src="vue-tap.js"></script>
<script>
new Vue({
el:'#app',
data:{
list:['a','b','c','e','f']
},
methods:{
tap:function(i,k){
console.log(i,k);
},
test:function(i){
console.log(i);
}
}
})
if(window.innerWidth < 768){
document.getElementsByTagName('body')[0].style.padding = 0;
}
</script>
</body>
</html>
github:https://github.com/weijhfly/vue-tap
參考了其他vue-tap插件,但仍有需要完善的地方,后續(xù)更新。此外,在移動端解決點(diǎn)擊延遲問題,還是比較推薦fastclick,兼容性較好且方便使用,不過相對而言模擬tap事件體積較小,也可以拿來練手了。
總結(jié)
以上所述是小編給大家介紹的vue自定義tap指令及tap事件的實(shí)現(xiàn),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Vue通過getAction的finally來最大程度避免影響主數(shù)據(jù)呈現(xiàn)問題
這篇文章主要介紹了Vue通過getAction的finally來最大程度避免影響主數(shù)據(jù)呈現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
el-select與el-tree結(jié)合使用實(shí)現(xiàn)樹形結(jié)構(gòu)多選框
我們在實(shí)際開發(fā)中需要用到下拉樹,elementUI是沒有這個組件的,我們就要自己去寫了,下面這篇文章主要給大家介紹了關(guān)于el-select與el-tree結(jié)合使用實(shí)現(xiàn)樹形結(jié)構(gòu)多選框的相關(guān)資料,需要的朋友可以參考下2022-10-10
vue?this.$router和this.$route區(qū)別解析及路由傳參的2種方式?&&?this.$route
this.$router?相當(dāng)于一個全局的路由器對象,包含了很多屬性和對象(比如?history?對象),任何頁面都可以調(diào)用其?push(),?replace(),?go()?等方法,本文給大家介紹Vue中this.$router與this.$route的區(qū)別?及push()方法,感興趣的朋友跟隨小編一起看看吧2023-10-10
vue+element項(xiàng)目中過濾輸入框特殊字符小結(jié)
這篇文章主要介紹了vue+element項(xiàng)目中過濾輸入框特殊字符小結(jié),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08
vue backtop組件的實(shí)現(xiàn)完整代碼
這篇文章主要介紹了vue backtop組件的實(shí)現(xiàn)完整代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
前端虛擬滾動列表實(shí)現(xiàn)代碼(vue虛擬列表)
前端的性能瓶頸那就是頁面的卡頓,當(dāng)然這種頁面的卡頓包含了多種原因,下面這篇文章主要給大家介紹了關(guān)于前端虛擬滾動列表實(shí)現(xiàn)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06

