Mint-ui 프레임워크 Popup 및 Datetime Picker 구성 요소 스크롤 관통 문제 해결

이동단 개발에서 Mint-ui 구성 요소 라이브러리에 사용됐는데 두 개의 구성 요소 Popup 구성 요소와 Datetime Picker가 스크롤성 관통 문제가 존재했고 공식 문서의 최신 버전은 이 문제를 해결하지 못했다.
현상 환원
공식 주소
핸드폰 스캔으로 데모를 보고 두 개의 구성 요소인 Popup 구성 요소와 Datetime의 예를 보여 줍니다.
문제의 원인
HTML5 터치 이벤트 touchmove 이벤트: 손가락이 화면에서 미끄러질 때 연속적으로 터치
따라서 구성 요소 Popup 구성 요소와 Datetime Picker의 팝업 레이어를 활성화할 때, 우리가 탄층에서 내용을 선택할 때 위아래로 연속적으로 미끄러지면 이 이벤트를 촉발합니다
사고방식을 해결하다
팝업층이 나타나면 바디를 막는 터치무브 이벤트, 팝업층이 사라지면 저지 이벤트를 제거합니다.
mint-ui 구성 요소 라이브러리 사용 해결 방법
Popup 구성 요소
//공식 사례

<mt-popup
 v-model="popupVisible"
 position="bottom">
 ...
</mt-popup>
//해결 방식, popupVisible 변수를 감청함으로써 탄창이 나타난 후 bode 노드 touchMove 이벤트를 금지하고, 탄창이 사라진 후 body 노드를 복구하는 touchMove 이벤트

const handler = function(e) {
  e.preventDefault();
}

// vue 
watch: {
  popupVisible: function (val) {
   if(val) {
     document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
   } else {
     document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
   }
  }
}
Datetime Picker
//공식 사례

<mt-datetime-picker
  ref="picker"
  type="time"
  v-model="pickerValue">
</mt-datetime-picker>
//해결 방법: 이 구성 요소는 비교적 구덩이입니다. Datetime Picker가 탄창 표시와 숨겨진 귀속 변수를 제공하지 않았기 때문에 우리는 popup을 해결하는 방식으로 문제를 해결하지 않았습니다. 이벤트를 열고 이벤트를 확인하며 이벤트를 취소하고 몽환된 탄창을 클릭하여 사라지는 몇 가지 시간만 해결할 수 있습니다.정부에서 제시한 속성 방법은 이벤트 확인, 이벤트 열기만 지원합니다.사건을 취소하는 리셋 함수를 명문으로 제시하지 않았고, 몽타주 창을 클릭하여 사건을 사라지는 것도 지원하지 않아 구덩이였다.

<mt-datetime-picker
  ref="picker"
  type="time"
  v-model="pickerValue"
  @confirm="confirm">
</mt-datetime-picker>

const handler = function(e) {
  e.preventDefault();
}
//vue 인스턴스 내

methods: {
  openPicker() { //  
    document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
    this.$refs.picker.open();
  },
  confirm() { //  
    document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
  }
}
이 때 리셋 취소와 몽타주 클릭 이벤트가 하나 부족합니다. 그리고 원본 코드를 보면 사실 mint-ui 원본 코드는 리셋 취소 이벤트를 지원합니다. 또한 놀랍게도 2.0 버전 이후의mint-ui가 Datetime picker 구성 요소에visible-change 이벤트와close OnClick Modal 속성(전송문)을 추가했지만 공식 문서는 여전히 이러한 속성을 업데이트하지 않았습니다.지금 상술한 문제를 잘 해결하였다.
그리고visible-change 사건이 생기면 상술한 사고방식대로 해결하지 않아도 된다.어셈블리 섹션 소스는 다음과 같습니다.

props: {
  ...,
  closeOnClickModal: {
    type: Boolean,
    default: true
  }
},
watch: {
  ...,
 visible(val) {
  this.$emit('visible-change', val);
 }
},
...
<span class="mint-datetime-action mint-datetime-cancel" @click="visible = false;$emit('cancel')">{{ cancelText }}</span>
직접visible-change 방법으로 해결합니다.

<mt-datetime-picker
  ref="picker"
  type="time"
  v-model="pickerValue"
  @confirm="confirm"
  @visible-change=""handleValueChange>
</mt-datetime-picker>

const handler = function(e) {
  e.preventDefault();
}

// vue 
methods: {
  handleValueChange: function (val) {
   if(val) {
     document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
   } else {
     document.getElementsByTagName('body')[0].addEventListener('touchmove', this.handler, { passive: false });
   }
  }
}
위의 방법은 프로젝트가 부딪힌 구덩이를 해결할 수 있지만, 모든 페이지에 구성 요소인 Popup 구성 요소와 Datetime Picker를 사용하려면 이 코드를 추가해야 합니다. 페이지에 여러 개의 Popup 구성 요소가 존재하면 여러 개의 변수를 감청해야 합니다.
더 좋은 해결 방식(상술한 방식은 인터넷에서도 유사한 해결 방식이 있고visible-change 방안을 스스로 보충했다)
프로젝트에서 위와 같이 해결하는 것은 너무 번거롭기 때문에 비교적 좋은 해결 방안을 생각했다. 탄층의 출현과 사라짐은 구성 요소의 업데이트를 촉발하기 때문에 전체 국면에 지령 v-roll을 등록하고 지령의componentUpdated 갈고리를 활용하여 이 기능을 실현할 수 있다고 생각했다.코드는 다음과 같습니다.

//  
const handler = (e) => {
 e.preventDefault();
};
Vue.directive('roll', {
 componentUpdated(el, binding) {
  if (binding.value) {
   document.getElementsByTagName('body')[0].addEventListener('touchmove', handler, { passive: false });
  } else {
   document.getElementsByTagName('body')[0].removeEventListener('touchmove', handler, { passive: false });
  }
 }
});
이렇게 되면 많은 코드를 간소화하고 다른 개발자들은 사용할 때 대응하는 구성 요소에 v-roll 명령을 추가하면 된다.

// popup 
<mt-popup
 v-model="popupVisible"
 v-roll:visible=popupVisible>
 ...
</mt-popup>

// mt-datetime-picker 
<mt-datetime-picker 
 ref="datePicker" 
 v-model="date"
 @visible-change="handleVisibleChange"
 v-roll:visible=pVisible
 ...>
</mt-datetime-picker>
...
data: {
  pVisible: false 
},
methods: {
  handleVisibleChange (isVisible) {
    this.pVisible = isVisible;
  }
}
이어 같은 보기 페이지에 여러 개의 구성 요소 Popup 구성 요소와 Datetime Picker가 명령을 사용할 때 집단적으로 명령을 터치하는 구덩이가 있습니다.그래서 서로 덮어씁니다. 예를 들어 A탄층을 열어 페이지touchMove 이벤트를 막지만 다른 popuu 구성 요소도 갈고리 함수를 터치하고 TouchMove 이벤트를 막아서 효과가 없습니다.
componentUpdated: 명령어가 있는 구성 요소의 VNode와 하위 VNode를 모두 업데이트한 후 호출합니다.//현재 자신의 이해는 탄층이 나타나고 사라지면서 보이는 인터페이스 노드가 업데이트되었기 때문에 다른 노드가 v-roll 명령을 연결한 갈고리도 촉발되었다
해결 방안: 한 보기에 여러 개의 구성 요소 Popup 구성 요소와 Datetime Picker를 사용하는 명령어 입력 그룹 형식

//  
const handler = (e) => {
 e.preventDefault();
};
Vue.directive('roll', {
 componentUpdated(el, binding) {
  if (binding.value instanceof Array) {
   const visible = binding.value.some(e => e); //  true, touchmove 
   if (visible) {
    document.getElementsByTagName('body')[0].addEventListener('touchmove', handler, { passive: false });
   } else {
    document.getElementsByTagName('body')[0].removeEventListener('touchmove', handler, { passive: false });
   }
  } else if (typeof binding.value === 'boolean') {
   if (binding.value) {
    document.getElementsByTagName('body')[0].addEventListener('touchmove', handler, { passive: false });
   } else {
    document.getElementsByTagName('body')[0].removeEventListener('touchmove', handler, { passive: false });
   }
  }
 }
});

// popup 
<mt-popup
 v-model="popupVisible"
 v-roll:visible=[popupVisible, pVisible]>
 ...
</mt-popup>

// mt-datetime-picker 
<mt-datetime-picker 
 ref="datePicker" 
 v-model="date"
 @visible-change="handleVisibleChange"
 v-roll:visible=[popupVisible, pVisible]
 ...>
</mt-datetime-picker>
...
data: {
  pVisible: false 
},
methods: {
  handleVisibleChange (isVisible) {
    this.pVisible = isVisible;
  }
}
현재mint-ui는 아직 이 문제를 복구하지 않았기 때문에 당분간 상술한 방안을 사용하여 해결합니다.처음에는 원본 코드를 바꾸려고 했지만, 비현실적이었다. 왜냐하면 나중에mint-ui 버전을 업데이트해야 할 수도 있기 때문이다.여러분도 위와 같은 해결 방식에 구덩이가 있는지 확인해 주실 수 있습니다.
추가 정보: vue에서 mint-ui의 날짜 플러그인을 사용할 때 ios에서 스크롤 관통 문제가 발생합니다
문제:ios에서 날짜를 선택하면 위아래로 미끄러질 때 전체 페이지가 스크롤됩니다. 안드로이드는 정상입니다.
해결 방법은 날짜 팝업 층이 나타날 때 페이지의 기본 스크롤 메커니즘을 금지하고, 날짜 팝업 층이 사라질 때 금지 페이지의 기본 스크롤 메커니즘을 해제하는 것이다
1. 날짜 구성 요소 호출

 <div class="datePicker" style="z-index: 9999">
   <mt-datetime-picker
    type="date"
    ref="picker"
    v-model="nowTime"
    year-format="{value}  "
    month-format="{value}  "
    date-format="{value}  "
    @confirm="handleConfirm"
    :startDate="startDate"
    :endDate="endDate"
   >
   </mt-datetime-picker>
  </div>
2. 감청 함수 설정

data () {
    return {
     birthday:"", // 
     startDate: new Date('1952'),
     endDate:new Date(),
     nowTime:'1992-09-15',
    
     /*--------- --------------*/
     handler:function(e){e.preventDefault();}
    }
   },
   methods:{
    /* iphone */
    closeTouch:function(){
     document.getElementsByTagName("body")[0].addEventListener('touchmove',
      this.handler,{passive:false});// 
     console.log("closeTouch haved happened.");
    },
    openTouch:function(){
     document.getElementsByTagName("body")[0].removeEventListener('touchmove',
      this.handler,{passive:false});// 
     console.log("openTouch haved happened.");
    },
 }
그리고 감청, 탄창이 사라질 때 상응하는 방법을 사용한다

// 
watch:{
  signReasonVisible:function(newvs,oldvs){//picker , 
    if(newvs){
      this.closeTouch();
    }else{
      this.openTouch();
    }
  }
},
다음은datetime-picker의 처리입니다. (openPicker1은 선택기를 여는 이벤트를 터치하기 위해handleConfirm(data)는 선택한 날짜의 리셋 함수입니다)

 openPicker () {
      this.$refs.picker.open();
      this.closeTouch();// 
 
     },
     handleConfirm (data) {
      let date = moment(data).format('YYYY-MM-DD')
      this.birthday = date;
      this.openTouch();// 
 
     },
그리고 이 문제를 해결했어!
이상에서 Mint-ui 프레임워크 팝업과 Datetime Picker 구성 요소가 스크롤되어 관통하는 문제를 해결한 것은 바로 편집자가 여러분에게 공유한 모든 내용입니다. 참고 부탁드리고 저희도 많이 사랑해 주세요.

좋은 웹페이지 즐겨찾기