2017-10-16 2 views
1

iOSネイティブの日付/時刻ピッカーのようなカルーセルのようなリストを作成しようとしていますが、これは上下に移動できます。動的CSSプロパティを使用したVueリストのレンダリング

各項目の位置は、モデルからの属性であるtopに基づいており、最終的に絶対配置で各リスト項目要素に割り当てられます。

私はそれが一方向に機能するように管理していたので、「上に行く」を押すと、それは私が望んでいたとおりに機能します(下のスニペットで調べることができます)。一方、同じコードを別の方向に使用する場合(.pop()機能を.shift().unshift().push()に切り替える場合を除く)、別の方法で動作します。特に、項目値は再割り当てされますが、何も動きません。

私が気づいたのは、2番目のケースでは、アイテムキーが何らかの理由でリストアイテムがゼロからレンダリングされるということです。したがって、座標遷移は起こらない。

このメカニズムを両方向で動作させるにはどうすればよいですか?私は持っているように見える参照としてこのgithubの問題(github.com/vuejs/vue/issues/4834)を使用して

Vue.component('list-component', { 
 
    template: '#list-component', 
 
    name: 'list-componet', 
 
    data() { 
 
    \t return { 
 
    \t model: [], 
 
     activeIndex: null, 
 
     itemHeight: 56, 
 
    } 
 
    }, 
 
    methods: { 
 
    shiftWheel(direction) { 
 
     if (direction === 'up') { 
 
     const value = this.model[0].value - 1; 
 

 
     this.model.map((v) => { 
 
      v.top += this.itemHeight; 
 
     }); 
 

 
     this.model.pop(); 
 
     this.model.unshift({ 
 
      value, 
 
      top: -this.itemHeight 
 
     }); 
 

 
     } else { 
 
     const value = this.model[this.model.length - 1].value + 1; 
 

 
     this.model.shift(); 
 

 
     this.model.forEach((v) => { 
 
      v.top -= this.itemHeight; 
 
     }); 
 
     this.model.push({ 
 
      value, 
 
      top: this.itemHeight * 5 
 
     }); 
 
     } 
 
    \t } 
 
    }, 
 
    mounted() { 
 
    const quantity = 5 + 2; 
 
    
 
    this.top = -56; 
 

 
    const currentYear = moment().year; 
 
    const toTheSides = Math.floor(quantity/2); 
 

 
    this.activeIndex = quantity - toTheSides - 1; 
 

 
    const start = moment().clone().subtract(toTheSides, 'Y'); 
 

 
    this.model = Array(quantity).fill().map((v, i) => { 
 
     const value = start.clone(); 
 
     start.add(1, 'Y'); 
 
     return { 
 
     value: value.year(), 
 
     top: i * this.itemHeight - this.itemHeight 
 
     }; 
 
    }); 
 
    } 
 
}); 
 

 
new Vue({ 
 
    el: '#app' 
 
});
.container { 
 
    position: relative; 
 
    overflow: hidden; 
 
    height: 280px; 
 
    width: 50px; 
 
} 
 

 
.wrapper { 
 
    display: flex; 
 
    align-items: center; 
 
} 
 

 
.buttons { 
 
    position: relative; 
 
    z-index: 999; 
 
} 
 

 
.md-wheel-item { 
 
    padding: 16px 0; 
 
    display: flex; 
 
    position: absolute; 
 
    flex: 1; 
 
    align-items: center; 
 
    justify-content: center; 
 
    transition: top .2s ease-in-out; 
 
    will-change: top; 
 
    &.is-active { 
 
    color: red; 
 
    } 
 
}
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script> 
 
<script src="https://cdn.jsdelivr.net/npm/[email protected]/moment.min.js"></script> 
 

 
<script type="text/x-template" id="list-component"> 
 
\t <div class="wrapper"> 
 
    \t <div class="container"> 
 
    \t <div v-for="(item, iIndex) in model" 
 
\t \t \t \t :key="item.value" 
 
     \t class="md-wheel-item" 
 
     \t :class="{'is-active': iIndex === activeIndex}" 
 
     \t :style="{height: itemHeight + 'px', top: item.top + 'px'}"> 
 
     \t {{ item.value || item }} 
 
    \t </div> 
 
    </div> 
 
    <div class="buttons"> 
 
    \t <button @click.prevent="shiftWheel('up')">Go up</button> 
 
    \t \t <button @click.prevent="shiftWheel('down')">Go down</button> 
 
    </div> 
 
\t </div> 
 
</script> 
 

 
<div id="app"> 
 
    <div id="content"> 
 
     <list-component></list-component> 
 
    </div> 
 
</div>

+1

これは確かに難しいものです。この特定のユースケースについては、あなたがやりたいことに適しているため、vueの「移行グループ」を調べることをおすすめします:https://vuejs.org/v2/guide/transitions.html#List-Transitions –

+0

@ b-fleming、それは確かにそれを解決する方法ですが、私はまだ私が上記のようにすることに興味があります。 btwは、あなたが提案したように、私が "transition-group"を使って作ったものです:https://jsfiddle.net/o_voloshin/mf5svm82/1/ –

+0

@ b-flemingあなたは完全に正しいです。 githubの問題(https://github.com/vuejs/vue/issues/4834)を読むと、 'transition-group'が私の唯一の方法だと思われます。 –

答えて

0

:私は準備スニペットを見てみることをお気軽に使用するtransition-group

これらは再作成されません(アイテム)が、insertBeforeによって移動されます。そして、トランジション中の要素がトランジション中に移動されると、トランジションは中断されます。このキーは、すべての操作が完了したときに要素がDOM内の正しい位置にくることを保証しますが、プロセス内で決して移動されないことを保証するものではありません。これは、一貫性のある結果を持つ簡潔なアルゴリズムを保証するために必要なことです。これは将来改善されるかもしれませんが、それは非常に重要なものではありません。

関連する問題