2017-12-18 15 views
2

私は、ユーザーが行を隠すことができる表を作成しようとしていて、他の行を削​​除すると非表示にしています。Vuejsはクラスを行にバインドし、後で行を非表示にしますか?

私のHTMLで、私はテーブルをレンダリングするとき、クラスをバインドするvuejsを使用します。

<tr v-for="item in mylist" :class="{'noFruits': (item.fruits.length == 0)}"> 

そのクラスに行を非表示にするには、ユーザーのチェックボックスがあります:私のVueのインスタンスで

<label><input type="checkbox" v-model="showBlankFruits" @change="setBlankDisplay">Show Blank Fruits</label> 

、チェックボックスは、CSS表示プロパティを添付するためにjqueryを介してそのクラスの行を表示/非表示するメソッドを実行します。

methods: { 
    setBlankDisplay: function() { 
    if (this.showBlankFruits) { 
    $('.noFruits').css('display', ''); 
    } else { 
    $('.noFruits').css('display', 'none'); 
    } 
}, 

私のjsfiddleでは、ユーザーが行を削除すると、隠し行が再表示されます。私は、このインスタンスでスタイルをjqueryで付けることは良くありません...誰かがより良いメソッドの提案を持っているのを見ますか?

+0

vuejsでクラス/スタイルのバインディングのためのコンポーネントがあります。 https://vuejs.org/v2/guide/class-and-style.html – divine

答えて

0

VueとjQueryを混在させることはお勧めできません.Vueを使用するだけで、他のライブラリ/フレームワークが何をしているのかわからない矛盾する操作はありません。

果物配列の長さが他の言葉で、0 truthyない、またはshowBlankFruitsが真であればいずれかの場合、次の行が表示されます:

<tr v-for="item in mylist" v-show="item.fruits.length || showBlankFruits"> 

チェックボックスをクリックすると、次のshowBlankFruitsをトグルする:

<label><input type="checkbox" v-model="showBlankFruits">Show Blank Fruits</label> 

完全なコード例:

JSFiddle

1

これは、コンポーネントでDOM操作を使用するのではなく、宣言的レンダリングの優れた例です。あなたが実行している問題は、VueエンジンがsetBlankDisplayメソッドで行ったelemetsの手動操作について知らないリストをレンダリングするときです。これを回避する方法は、最初にnoFruitsクラスを設定したように、ビュー自体の定義にコンポーネントロジックを使用することです。

だから、私はあなたがsetBlankDisplayを取り除くと方法に置き換える提案:

itemDisplay(item) { 
    if (item.fruits.length === 0 && !this.showBlankFruits) { 
    return 'none'; 
    } 
    return ''; 
}, 

次にあなたがそうのように、CSS displayプロパティにリンクされているあなたのtr要素の定義で、それを参照することができます。

<tr v-for="item in mylist" :class="{'noFruits': (item.fruits.length == 0)}" :style="{display: itemDisplay(item)}"> 

私は他の項目が削除されたときに隠された果物の状態が残っていることを示し、この変更でjsfiddleを更新しました。

これは、jqueryを使用してビューの状態を変更する危険性の一般的な例です。コンポーネントロジックに関してビュー全体を定義するためにあらゆる努力が払われるべきです。

2

また、次のように書くこともできます。 私は計算を使用し、jQueryパーツを完全に削除しました。 あなたは、機能の代わりに、データオブジェクト(https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function)あなたはは、初期状態を設定するためのメソッドをマウント呼び出す必要はありません

としてデータを宣言しなければなりません。すでにデータオブジェクトとともに設定されています。 あなたのコードでは、jQueryはDOMがロードされたときにのみ結果を隠すことができるので、あなたはmountを呼び出す必要があります。

new Vue({ 
 
    el: '#app', 
 
    data() { 
 
    return { 
 
     showBlankFruits: true, 
 
     mylist: [ 
 
     {'user': 'Alice', 'fruits': [{'name': 'apple'}]}, 
 
     {'user': 'Bob', 'fruits': [{'name': 'orange'}]}, 
 
     {'user': 'Charlie', 'fruits': []}, 
 
     {'user': 'Denise', 'fruits': [{'name': 'apple'}, {'name': 'orange'}]}, 
 
     ] 
 
    } 
 
    }, 
 
    computed: { 
 
    list() { 
 
     return this.mylist.filter(item => (item.fruits.length > 0 && !this.showBlankFruits) || (item.fruits.length === 0 && this.showBlankFruits)) 
 
    }, 
 
    }, 
 
    methods: { 
 
    delItem(item) { 
 
     let index = this.mylist.indexOf(item); 
 
     if (index > -1) { 
 
     this.mylist.splice(index, 1); 
 
     } 
 
    } 
 
    } 
 
})
<script src="https://unpkg.com/vue"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
 

 
<div id="app"> 
 
    <label><input type="checkbox" v-model="showBlankFruits">Show Blank Fruits</label> 
 
    <br> <br> 
 
    <table> 
 
    <tr> <th class="col">User</th> <th class="col">Fruits</th> <th class="col"></th> </tr> 
 
    <tr v-for="item in list"> 
 
     <td>{{ item.user }}</td> 
 
     <td> <span v-for="f in item.fruits"> {{ f.name }} </span> </td> 
 
     <td> <button @click="delItem(item)">Delete</button> </td> 
 
    </tr> 
 
    </table> 
 
</div>

+0

@cstricklanのようなスタイルバインディングよりもやり方が好きです。データをフィルタリングする計算を使用すると、コンポーネントをよりテスト可能にします。 – kmc059000

+0

データが* components *の関数になるには*必須*です。私が知っている限りでは、ルートVueのインスタンスのどこにでも機能することは「推奨」されていません。実際、ドキュメントでは、[非常に初めの]オブジェクト(https://vuejs.org/v2/guide/index.html#Declarative-Rendering)を使って説明しています。 – Bert

+0

私はこの例では彼が単一のインスタンスを使用しており、アプリケーションを壊さないため、「お勧め」と書いています。しかし、あなたは正しい!私は私の答えを更新します。 – Phil

関連する問題