Обработчик для определённого css-класса

101
21 ноября 2020, 19:50

У меня по приложению разбросано множество форм с полями ввода денежных величин. Для удобства пользователя, который вставляет данные из разных внешних систем сделана замена запятой на точку, убираются пробелы - удобно, когда не надо вставлять то "1 111,11" то "1111.11".

И было это сделано в приложении на asp.net core с использованием идущего в комплекте jQuery.

Просто к нужным полям добавлялся специальный css-класс clean_money:

<div class="form-group">
    <label asp-for="Vm.Amount"></label>
    <input asp-for="Vm.Amount" class="form-control clean_money" />
    <span asp-validation-for="Vm.Amount" class="text-danger"></span>
</div>

И глобально навешивался обработчик:

// fix money
$(document).ready(function () {
    $(".clean_money").keyup(function () {
        var val = $(this).val();
        if (val === '')
            return;
        val = val.replace(' ', '');
        val = val.replace(',', '.');
        $(this).val(val);
    });
});

Теперь вот думаю, как лучше всего повторить подобную фичу в приложении на vue.js

Есть идеи, как сделать подобное красиво и просто? Хочется один раз объявить функцию чистки и минимальными средствами указывать, к каким полям применять её.

Answer 1

Возможно, вам подойдет вариант с использованием пользовательской директивы.

Vue.directive('clean-money', { 
  inserted(el) { 
    el.addEventListener('keyup', function(e) { 
      let val = el.value; 
      if (val === '') 
        return; 
      el.value = val.replace(' ', '').replace(',', '.'); 
    }); 
  } 
}); 
 
new Vue({ 
  el: '#app' 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> 
<div id="app"> 
  <div class="form-group"> 
    <input v-clean-money class="form-control clean_money" /> 
  </div> 
</div>

Вариант с использованием примесей. Указываем примеси в тех компонентах, где необходимо использовать метод.

const cleanMoneyMixin = { 
  methods: { 
    cleanMoney(e) { 
      const target = e.target; 
      let val = target.value; 
      if (val === '') 
        return; 
      target.value = val.replace(' ', '').replace(',', '.'); 
    } 
  } 
} 
 
new Vue({ 
  el: '#app', 
  mixins: [cleanMoneyMixin] 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> 
<div id="app"> 
  <div class="form-group"> 
    <input class="form-control clean_money" @keyup="cleanMoney" /> 
  </div> 
</div>

И наконец используем отдельный компонент, регистрируя его локально в родительском.

const InputComponent = { 
 
  template: '<input class="form-control clean_money" @keyup="cleanMoney" />', 
 
  methods: { 
    cleanMoney(e) { 
      const target = e.target; 
      let val = target.value; 
      if (val === '') 
        return; 
      target.value = val.replace(' ', '').replace(',', '.'); 
    } 
  } 
} 
 
 
new Vue({ 
  el: '#app', 
  components: { 
    'input-component': InputComponent 
  } 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script> 
<div id="app"> 
  <div class="form-group"> 
    <input-component/> 
  </div> 
</div>