vue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。

怪我咯
リリース: 2018-05-28 11:42:07
オリジナル
4391 人が閲覧しました


はじめに
私は過去数か月間 VUE を検討し、ネイティブ js+vue のみを使用していくつかのコンポーネントを実装しようとしました。
PC 時間選択コンポーネント これは、PC 上での時間選択の最初の実装です。モバイル側でも実行されるので、モバイル側での 時間セレクター の実装を共有したいと思います。特殊効果の時間セレクターのアイデアとプロセス。コンポーネント全体は vue-cli
関数に基づいて構築されています
1. 時間選択 [

A.年月日选择
ログイン後にコピー

C. 時間と分の選択]

2. スクロールホイール効果 [

B.年月日小时分钟选择
ログイン後にコピー

]エンドツーエンド接続]
3. 時間選択範囲設定 (選択した時間が範囲を超える場合、ポップアップウィンドウが表示されます)、分間隔設定
4. 多言語設定5. yyyy/MM/dd HH:mm の要件を満たします ルールを設定します
6. UE はネイティブ iOS エフェクトに近いです
7. 拡張機能は時間を選択するだけでなく、カスタム リンケージ選択データを渡すこともできます
ここでは主に無限スクロール ホイールの実装について話します

データの準備 1ここから入手してください

A.构成一个圆环首尾相连
ログイン後にコピー

説明のため

1 か月の日数を取得する賢い方法。

ログイン後にコピー

ここではvueのcomputedメソッドを使って実装し、

dayList () {
       /* get currentMonthLenght */
        let currentMonthLength = new Date(this.tmpYear, this.tmpMonth + 1, 0).getDate();
       /* get currentMonth day */
        let daylist = Array.from({length: currentMonthLength}, (value, index) => {
          return index + 1
        });
        return daylist
      },
ログイン後にコピー
yearList
ログイン後にコピー

dayList

monthList
ログイン後にコピー
hourList
ログイン後にコピー

を配置して基本的なデータの準備はここで終わりです。


静的効果の実装スクロールホイールの静的効果を実現するには多くの方法があります
1. 視覚的な3D効果[影を追加]
2. 実際の3D効果[CSS3D]

minuteList
ログイン後にコピー

私が使用した2番目の方法自分でCSS3Dを実装してみます


説明まず第一に、スクロールホイールが選択範囲に入った場合と選択範囲外に入った場合では、ネイティブiOSの選択効果が異なることがわかります


vue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。
それでは、この効果を実現するには違いは、2 つの DOM 構造を使用することにしました。1 つの DOM はスクロール ホイールを実装し、もう 1 つの DOM は黒の選択効果を実装します。そのため、リンクすると、元の

我把实现效果大致分为上面2种,具体的大家可以自己搜索相关资料,这里展开涉及太多就带过好了
ログイン後にコピー

と同様の効果に違いが生じます。 DOM のオプションがインストールされています。ここでは 1 つだけ指定されています。

picker-panel
ログイン後にコピー

その日のデータがインストールされています。 一番外側のボックス、

box-day
ログイン後にコピー

は、選択された 2 行、

check-line
ログイン後にコピー

一番外側の黒いエフェクト データ、

day-list
ログイン後にコピー

グレーのローラー部分

を実装します。

day-wheel
ログイン後にコピー
rreee

主にCSS

属性

<p class="picker-panel">
<!--other box-->
<p class="box-day">
  <p class="check-line"></p>
  <p class="day-checked">
    <p class="day-list">
      <p class="list-p" v-for="day in renderListDay">
       {{day.value}}
      </p>
    </p>
  </p>
  <p class="day-wheel">
    <p class="wheel-p" v-for="day in renderListDay" transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);>
    {{day.value}}
    </p>
  </p>
</p>
<!--other box-->
</p>
ログイン後にコピー

を使用して3D効果を表示し、


.day-wheel{
    position: absolute;
    overflow: visible;
    height: px2rem(68px);
    font-size: px2rem(36px);
    top:px2rem(180px);
    left: 0;
    right: 0;
    color:$unchecked-date;
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    .wheel-p{
     height: px2rem(68px);
     line-height: px2rem(68px);
     position: absolute;
     top:0;
     width: 100%;
     text-align: center;
     -webkit-backface-visibility: hidden;
     backface-visibility: hidden;
     white-space: nowrap;
     overflow: hidden;
     text-overflow: ellipsis;
    }
   }
ログイン後にコピー

ホイールの後ろの部分は自動的に非表示になります


transform-style: preserve-3d;
ログイン後にコピー

ホイールの位置決めに使用します


-webkit-backface-visibility: hidden;
ログイン後にコピー

各データの回転角度とホイール側

ビュー円の半径
各データ回転の角度と構築原理
vue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。上の写真
は、ローラーの効果の三次元ビューです。rは、私たちのローラーの2.5レムです。 translation3d(0px,0px,2.5rem) css
そのような css がない場合、すべてのデータは円の中心に集められます

vue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。 上の画像は回転していません (赤色は表示されるデータ効果を表します)

vue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。
上の図は回転しています (赤とオレンジは、私たちが見ているデータ効果を表しています)

青い円弧で表されている角度は同じです (これには (角度の知識) が含まれます。これは視覚的な回転角度でもあります。 rotate3d CSS の 80deg では、各間隔が 20 度になるようにしています。このようにして、実際には X 軸を回転す​​るだけで、円の中心角も回転するので、リング全体が広がります。完全な円には 360/20 のデータを保持でき、正面のデータは肉眼で見ることができるため、特定の角度を過ぎると、その背後にあるデータは見えなくなります。 -webkit-backface-visibility: hidden;うまくいったという意味です。

postition:absolute;
ログイン後にコピー

効果は下の写真と似ています


vue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。そこで、2番目のデータ準備があります

データ準備2ここでも、初期データとしてdayListを使用します[1,2,3,4,.. ,30,31]
ここでは、毎回 19 個のデータをレンダリング データとして取得し、renderListDay の初期レンダリングを [23,24,25,26,27,28,29,30,31,1,2] にする必要があります。 ,3 ,4,5,6,7,8,9,10]
真ん中の数字がちょうど最初の数字なので(初期化時のみ)

transform: rotate3d(1, 0, 0, 80deg) translate3d(0px, 0px, 2.5rem);
ログイン後にコピー

データの取得方法は、0未満の場合は、 0 より大きいです。フェッチ時に、

index が元のデータ長より大きい場合、% 計算を使用して通常の範囲に対応するインデックスを取得します。そのため、上記のスピンはデータをフェッチするためのフォークです (最初は -9 から9)

这里我们发现轮子装不完所有数据,而且我们要实现数据循环
ログイン後にコピー

各データの回転角度(上半円が正、下半円が負)


<p class="wheel-p" v-for="day in renderListDay" v-bind:data-index="day.index" v-bind:style="{transform: &#39;rotate3d(1, 0, 0, &#39;+ (-day.index)*20%360+&#39;deg) translate3d(0px, 0px, 2.5rem)&#39;}">{{day.value}}{{day.value}}</p>
ログイン後にコピー

接着需要旋转到我们需要的角度,跟我们的初始化时间对上,this.orDay-this.DayList[0] 是获取偏移量来矫正角度

this.$el.getElementsByClassName(&#39;day-wheel&#39;)[0].style.transform = &#39;rotate3d(1, 0, 0, &#39; + (this.orDay - this.dayList[0]) * 20 + &#39;deg)&#39;;
ログイン後にコピー

增加touch事件
剩下的事就很好处理了,给对应的dom绑定事件根据touchmove的距离来转换成旋转的角度 和check-list的位移这里translateY是用来记录实际移动的距离的,最后输出需要算入偏移量

<p class="box-day" v-on:touchstart="myTouch($event,&#39;day&#39;)" v-on:touchmove="myMove($event,&#39;day&#39;)" v-on:touchend="myEnd($event,&#39;day&#39;)">
  <p class="check-line"></p>
  <p class="day-checked">
    <p class="day-list" data-translateY="0" style="transform: translateY(0rem)">
      <p class="list-p" v-for="day in renderListDay" v-bind:data-index="day.index">
        {{day.value}}
      </p>
    </p>
  </p>
  <p class="day-wheel" style=" transform: rotate3d(1, 0, 0,0deg)">
    <p class="wheel-p" v-for="day in renderListDay" v-bind:data-index="day.index" v-bind:style="{transform: &#39;rotate3d(1, 0, 0, &#39;+ (-day.index)*20%360+&#39;deg) translate3d(0px, 0px, 2.5rem)&#39;}">
     {{day.value}}
    </p>
  </p>
</p>
ログイン後にコピー

惯性滚动
这个实现我是用了一个 cubic-bezier(0.19, 1, 0.22, 1)
判断手势是不是flicker 如果是flicker通过一个瞬时速度来算出位移,和时间,然后一次性设置,然后用transition做惯性滚动,
普通拖动 设置1秒
这个实际效果还是有点不好,以后来改进。
其他功能的实现
这里不做详细说明了
总结
自适应方面用了手淘的解决方案
这次实现这个组件最困难的就是实现无限滚动,和无限滚动的渲染数据的构造,接着就是惯性滚动的实现。
已知问题
1.惯性滚动不完美
2.无限滚动实现了。非无限滚动没实现,就是渲染数据就是[1,2,3,4,5,6,7,8,9,10]
3.现在选择必须 年月日 或者年月日小时分钟 不能单独选小时或者分钟

以上がvue.js は、ネイティブの iOS 時間選択コンポーネントを模倣する開発エクスペリエンスを実装します。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート