2017-12-28 53 views
0

client-rowというコンポーネントのリストがあり、1つを選択するとスタイルを変更したいです。新しい行を選択するときに、前に選択した行からスタイリングを削除しようとするときに問題が発生します。Vue:スタイルリスト行が選択されている場合

Vue.component('client-row', { 
    template: '#client-row', 
    props: { 
     client: Object, 
    }, 
    data: function() { 
     return { 
      selected: false 
     } 
    }, 
    methods: { 
     select: function() { 

      // Does not work properly 
      el = document.querySelector('.chosen_row') 
      console.log(el) 

      if (el) { 
       el.className = el.className - "chosen_row" 
      } 
      this.selected = true 
      this.$emit('selected', this.client) 
     } 
    } 
}) 

<script type="text/x-template" id="client-row"> 
    <tr v-bind:class="{ 'chosen_row': selected }"> 
     <td>{{ client.name }}</td> 
     <td>{{ client.location_name || 'no location found' }}</td> 
     <td>{{ client.email || 'no email found' }}</td> 
     <td><button class="btn btn-sm btn-awaken" @click="select()">Select</button></td> 
    </tr> 
</script> 

は私がきちんとselectedプロパティ、を設定することができますが、確実にそれを削除するように見えることはできません。

答えて

1

一般的に、コンポーネントのDOM要素を手動で変更することは悪い習慣です。代わりに、親コンポーネントを変更して、どの行が選択されたかを追跡し、その値を行に渡すためのデータフィールドを持つようにすることをお勧めします。行は、その値が親の選択された行に一致するかどうかをチェックし、trueの場合はスタイルを適用します。

コンポーネントでのDOM操作は、vueで非常に間違っていることを示す記号です。

あなたの場合、vueと手動でのDOM操作はお互いに争っています。 Vueは、子のデータフィールドselectedが真であるかどうかに基づいて、クラスをtrに追加するかどうかを追跡しています。あなたのコードでは、これを真に設定するだけです。 Vueは、クリックした行のクラスを常にインクルードしようとします。その後、クリックしたすべての行からクラスを手動で削除しますが、クリックされた子コンポーネントではまだselectedがtrueであるため、Vueはクラスを追加しようとします。

DOM操作ベースのアプローチではなく、データ指向のアプローチを行う必要があります。

子供:

Vue.component('client-row', { 
    template: '#client-row', 
    props: { 
     client: Object, 
     selectedClient: Object 
    }, 
    methods: { 
     select: function() { 
      this.$emit('selected', this.client); 
     } 
    } 
}) 

<script type="text/x-template" id="client-row"> 
    <tr v-bind:class="{ 'chosen_row': client === selectedClient }"> 
     <!-- td's removed for brevity --> 
     <td><button class="btn btn-sm btn-awaken" @click="select">Select</button></td> 
    </tr> 
</script> 

親:また

Vue.component('parent', { 
    template: '#parent', 
    data() { 
     return { 
      clients: [], 
      selectedClient: null 
     }; 
    }, 
    methods: { 
     clientSelected(client) { 
      this.selectedClient = client; 
     } 
    } 
}) 

<script type="text/x-template" id="parent"> 
    <!-- i dont know what your parent looks like, so this is as simple as i can make it --> 
    <div v-for="client in clients"> 
     <client-row :client="client" :selected-client="selectedClient" @selected="clientSelected"></client-row> 
    </div> 
</script> 

:ボタン上の

あなたのクリックイベントハンドラがある@click="select"に短縮することができます推奨バインディング方法メソッド。

+0

よく考えられた答えをありがとう。いったん私がDOM操作を書いたら、私はそれが間違った方法であることを知っていたので、私はこれを最初に尋ねました! 'クライアント== selectedClient'ははるかに良いです:) –

+0

一つのこと。私の小道具が選択を更新していないようです。それがどうして起こるのか? –

+0

わかりません、コードを共有できますか? – kmc059000

関連する問題