web-dev-qa-db-ja.com

VueJSのチェックボックス変更イベントを傍受する

チェックボックスの長いセットがあります。 3つのうちの2つのグループがラジオボタンとして動作するようにしたいと考えています。さて、私のUXの選択は別として、これをどのように機能させることができますか?

チェックボックスは、単一のオブジェクトlayerのプロパティとして実装されます。

_    data: {
            layer: {},
        },
        watch: {
            layer: {
                handler: function(val, oldval) {
                    mapping.updateLayers(val);
                },
                deep: true
            }
        }
_

それはうまくいきます。ただし、valをインターセプトし、handler()内の_this.layer_を更新しても、次のことは行われません。

_        handler: function(val, oldval) {
            if (val.FutureYear) { this.layer.NextYear = false; this.layer.ExistingYear = false; }
            if (val.ExistingYear) { this.layer.NextYear = false; this.layer.FutureYear = false; }
            if (val.NextYear) { this.layer.ExistingYear = false; this.layer.FutureYear = false; }
            mapping.updateFoiLayers(val);
        },
_

どうすればこの結果を達成できますか? (実際のラジオボタンを実装する必要はありません。すべてのレイヤーとUIの管理が複雑になるためです。)

4
Steve Bennett

例: https://codepen.io/jacobgoh101/pen/NyRJLW?editors=001

主な問題は、watchのロジックです。

FutureYearがすでに選択されている場合、他のフィールドは変更できなくなります。 if (val.FutureYear)は常に最初にトリガーされるフィールドであり、他の2つのフィールドは常にすぐにfalseに設定されるためです。

watchについてのもう1つのことは、

  • ユーザーが値を変更しました
  • プログラムが値を変更しました(これは不要であり、処理が困難になります)

したがって、@changeイベントは、このシナリオでより適切です。

JS

methods: {
    handleChange: function(e) {
      const name = e.target.name;
      if (this.layer[name]) {
        Object.keys(this.layer).map((key)=>{
          if(key != name) {
            this.layer[key] = false;
          }
        })
      }
    }
  }

html

<div id="app">
  <input type="checkbox"/ v-model="layer.FutureYear" name="FutureYear"  @change="handleChange($event)">FutureYear<br/>
  <input type="checkbox"/ v-model="layer.NextYear" name="NextYear"  @change="handleChange($event)">NextYear<br/>
  <input type="checkbox"/ v-model="layer.ExistingYear" name="ExistingYear"  @change="handleChange($event)">ExistingYear<br/>
 </div>
7
Jacob Goh