Svelte:如何将格式化输入字段绑定到 属性

Svelte: How to bind a formatted input field to a property

首先:Svelte 对我来说还是个新手。我希望这个问题不是太微不足道。

在一个简单的组件中,我想使用格式化输入字段的内容进行计算。
例如:
在输入字段中,应以格式 (1.000) 显示欧元金额。 在它旁边应该显示带有金额加增值税的文本 (1.190)。

我如何不格式化我很清楚。该示例如下所示:

    export let net;
    export let vat;

    $: gross = net + (net * vat / 100);
    $: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });

使用像这样的简单标记:

    <form>
      <label>Net amount</label>
      <input type="text" step="any" bind:value={net} placeholder="Net amount">
    </form>
    <div>
        Gros = {grossPretty} €
    </div>

vue 中,我使用了计算 属性。它的 getter 传递格式化字符串,它的 setter 获取格式化字符串并保存原始值。 (在 data() 中我定义了 net,在计算属性中我定义了 netInput。输入字段使用 netInput 作为 v-model).
它看起来像这样:

netInput: {
   get(){
      return this.net.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });
   },
   set(s){
      s = s.replace(/[\D\s._-]+/g, "");
      this.net = Number(s);
   }
}

如何在 svelte 中处理它?

你可以做一些类似的事情,你创建另一个计算变量来存储来自输入字段的格式化字符串并用于计算而不是直接输入

  export let net;
  export let vat;
  $: net_plain = Number(net.replace(/[\D\s._-]+/g, ""));
  $: gross = net_plain + (net_plain * vat / 100);
  $: grossPretty = gross.toLocaleString('de-DE',{ minimumFractionDigits: 0, maximumFractionDigits: 0 });

但也许可以为变量找到一个更好的名称:)

感谢 Stephane Vanraes,我找到了解决方案。

它没有vue方法的魅力,但还可以。首先我插入了'net_plain'。为了在输入过程中格式化输入字段,我为 keyup 事件添加了一个事件监听器。

<input type="text" step="any" bind:value={net} on:keyup={handleKeyUp} placeholder="Net amount">

事件由函数 handleKeyUp 处理如下:

function handleKeyUp(event){
        if ( window.getSelection().toString() !== '' ) {
            return;
        }
        // ignore arrow keys
        let arrows = [38,40,37,39];
        if ( arrows.includes( event.keyCode)) {
            return;
        }
        let input = event.target.value.replace(/[\D\s._-]+/g, "");
        input = input ? parseInt( input, 10 ) : 0;
        event.target.value = ( input === 0 ) ? "" : input.toLocaleString( "de-DE" );
    }

但是:如果有人有使用getter和setter的解决方案,我将不胜感激!