この記事では、Vue のドラッグ コンポーネントの開発例を中心に紹介します。ドラッグの原理は、指の動きに合わせて要素の位置、つまり上部と左の値がリアルタイムに変更され、要素が移動することです。指の動きとともに。サンプルコードに興味のある友達、一緒に学びましょう
Vue を選ぶ理由
主な理由: フロントエンド開発では、互換性は考慮しなければならない問題の 1 つです。私たちのプロジェクトは、下位バージョンのブラウザと互換性がある必要はありません。プロジェクト自体もデータドリブンです。さらに、Vue 自体には次の主な機能があります:
• 仮想 DOM を使用する;
• 効率的なデータ バインディング;
• 完全な開発エコロジカル チェーン。
Vue フレームワークを選択する理由をいくつか示します。
なぜ Vue コンポーネントにカプセル化する必要があるのでしょうか? 主な目的は、コードの再利用性と保守性を向上させることです。
•再利用性: コンポーネント化後、パラメータを設定することで一部のスタイルとロジックが差別化および反映されるため、パラメータの設定可能性によりコンポーネントの再利用率と柔軟性が向上します。
•保守性: コンポーネント化後、コンポーネントの内部ロジックはコンポーネントのみを担当し、外部ロジックは構成パラメータを通じてのみ適応されるため、コードのロジックの明瞭さが向上し、コードの問題を迅速に解決できます。位置した。
コンポーネントベースの構築ページの図:
上の図からわかるように、Vue では、いわゆるコンポーネントベースの構築ページは、簡単に言うと、実際には独立した機能を持つコンポーネントから構築されます。 。これらのコンポーネントを組み合わせたりネストしてページを形成することができます。
コンポーネント構成以下は完成したコンポーネント構成です:
// 组件内模板 // 组件内逻辑代码 <script type="text/javascript"></script> // 组件内封装的样式 <style lang="scss" scoped></style>
例としてのVueモバイルドラッグコンポーネントの開発
ドラッグ原理指が動いている間この処理では、要素の位置、つまり上と左の値がリアルタイムで変更され、指の動きに合わせて要素が移動します。
ドラッグ実装•ドラッグ開始時:ビューエリア全体に対する接触点の座標clientX, clientYを取得、要素とビューの上辺と左辺との距離を取得initTop, initLeft; 接触点と要素の上辺および左辺の間の距離を計算します elTop = clientY - initTop, elLeft = clientX - initLeft; ドラッグプロセス中: 要素と上辺および左辺の間の距離を取得します。 currTop = clientY - elTop、currLeft = clientX - elLeft を介してリアルタイムでビューを移動します。要素が指の動きに合わせて移動するように、側面の距離値が要素に割り当てられます。
• ドラッグした後、要素を配置します。Vueを使用する場合の最大の違いは、DOMをほとんど操作せず、ドラッグアンドドロップ機能を実装するためにVueのデータドライバーを駆使する必要があることです。この場合、要素を垂直方向にドラッグするだけでよいため、垂直方向の移動のみが考慮されます。
上の図では、データ内のドラッグリストを介してドラッグ領域リストがレンダリングされます。コードは次のとおりです:
template: <p class="drag-title">拖拽可调整顺序</p> <ul class="drag-list"> <li class="drag-item">{{item.txt}}</li> </ul> script: export default { data() { return { dragList:null } }, created() { this.dragList = [ { isDrag: false, txt: '列表1', isShow: false } ... ] }, }
– ビュー: ビュー部分;
– ビューモデル: ビューとデータを接続するミドルウェア。
この考えに従って、次のことが分かります:
– oldIndex: 配列内の要素の初期インデックス;
– elHeight: 単一要素ブロックの高さ;
– currTop - initTop > : 要素が上にドラッグされていることを確認します。
下にドラッグしてみましょう:
– 首先,我们要在拖拽结束事件touchend中判断元素从拖动开始到拖动结束时拖动的距离。若小于某个设定的值,则什么也不做;
– 然后,在touchmove事件中判断,若(currTop - initTop) % elHeight>= elHeight/2成立,即当元素拖至另一个元素块等于或超过1/2的位置时,即可将元素插入到最新的位置为newIndex = (currTop - initTop) / elHeight + oldIndex。
– 最后,若手指离开元素,那么我们在touchend事件中,通过this.dragList.splice(oldIndex, 1),this.dragList.splice(newIndex, 0, item)重新调整数组顺序。页面会根据最新的dragList渲染列表。
写到这里,我们俨然已经用Vue实现了移动端的拖拽功能。但是拖拽体验并不好,接下来,我们对它进行优化。
优化点:我们希望,在元素即将可能落到的位置,提前留出一个可以放得下元素的区域,让用户更好的感知拖拽的灵活性。
方案:(方案已被验证是可行的)将li的结构做一下修改,代码如下:
<ul> <li class="drag-item"> <p class="leave-block"></p> // 向上拖拽时留空 <p class="">{{item.txt}}</p> <p class="leave-block"></p> // 向下拖拽时留空</li> </ul>
•拖拽开始:将元素的定位方式由static设置为absolute,z-index设置为一个较大的值,防止元素二次拖拽无效;
•拖拽过程中:将元素即将落入新位置的那个li下p的item.isShow设置为true,其他li下p的item.isShow均设置为false;
•拖拽结束:将所有li下p的item.isShow 均设置为false,将元素定位方式由absolute设置为static。
贴一段伪代码:
touchStart(e){ // 获取元素距离视口顶部的初始距离 initTop = e.currentTarget.offsetTop; // 开始拖动时,获取鼠标距离视口顶部的距离 initClientY = e.touches[0].clientY; // 计算出接触点距离元素顶部的距离 elTop = e.touches[0].clientY - initTop; }, touchMove(index, item, e){ // 将拖拽结束时,给元素设置的static定位方式移除,防止元素二次拖拽无效 e.target.classList.remove('static'); // 给拖拽的元素设置绝对定位方式 e.target.classList.add('ab'); // 获取元素在拖拽过程中距离视口顶部距离 currTop = e.touches[0].clientY - elTop; // 元素在拖拽过程中距离视口顶部距离赋给元素 e.target.style.top = currTop ; // 获取元素初始位置 oldIndex = index; // 获取拖拽元素 currItem = item; // 若元素已经拖至区域外 if(e.touches[0].clientY > (this.dragList.length) * elHeight){ // 将元素距离上侧的距离设置为拖动区视图的高 currTop = (this.dragList.length) * elHeight; return; } // 向下拖拽 if(currTop > initTop ){ // 若拖拽到大于等于元素的一半时,即可将元素插入到最新的位置 if((currTop - initTop) % elHeight>= elHeight / 2){ // 计算出元素拖到的最新位置 newIndex = Math.round((currTop - initTop) / elHeight) + index; // 确保新元素的索引不能大于等于列表的长度 if(newIndex < this.dragList.length){ // 将所有列表留空处隐藏 for(var i = 0;i< this.dragList.length;i++){ this.dragList[i].isShow = false; } // 将元素即将拖到的新位置的留空展示 this.dragList[newIndex].isShow = true; } else { return; } } } // 向上拖拽,原理同上 if(currTop < initTop){ ... } }, touchEnd(e){ // 若拖动距离大于某个设定的值,则按照上述,执行相关代码 if(Math.abs(e.changedTouches[0].clientY - initClientY ) > customVal){ this.dragList.splice(oldIndex, 1); this.dragList.splice(newIndex, 0, currItem); for(var i = 0;i< this.dragList.length;i++){ this.dragList[i].isShow = false; this.dragList[i].isShowUp = false; } } e.target.classList.remove('ab'); e.target.classList.add('static'); }
优化后,如下图所示:
以上便是用Vue实现移动端拖拽组件的过程。我们知道,有些项目是需要在PC端用Vue实现此功能。这里简单提一下PC与移动端的区别如下:
•PC端可以使用的事件组有两种:第一种:H5新特性draggable,dragstart,drag,dragend;第二种:mousedown,mousemove,mouseup;
•PC端获取鼠标坐标是通过e.clientX,clientY,区别于移动端的e.touches[0].clientX,e.touches[0].clientY。
小结
本文从Vue拖拽组件开发为例,剖析Vue组件的结构、开发思路、Vue的数据驱动等,对Vue组件化的原理,进行了更深入的理解。 并将Vue实现拖拽的方案提供给大家学习研究。
P.S. 牢记一点,切勿在Vue中过多得操作DOM,要能深入理解Vue数据驱动的核心思想。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
以上がVue ドラッグ アンド ドロップ コンポーネントの開発の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。