错误:如果输入使用双向绑定,则“ type”属性不能为动态

时间:2019-08-07 10:53:58

标签: svelte

我试图为我的项目创建一个Input组件。我想在input元素上动态设置type属性

但是当我在input上动态设置type属性时,出现错误提示 'type' attribute cannot be dynamic if input uses two-way binding

有没有解决方法,这样我可以动态设置type属性而不会丢失双向绑定

Input.svelte

<script>
  export let placeholder = "";
  export let label = "";
  export let description = "";
  export let value = "";
  export let type = "text";
</script>

<div class="container">
    <label>{label}</label>
    <input {type} bind:value {placeholder} />
    <p>{description}</p>
</div>

4 个答案:

答案 0 :(得分:12)

type对于双向绑定必须是静态的,原因是Svelte生成的代码对于不同种类的输入是不同的。例如,numberrange输入必须将其值强制转换为数字,某些输入需要change事件监听器而不是input事件,反之亦然,依此类推。

但是您可以手动执行生成的代码本来应该做的相同的事情-添加一个反映状态的事件侦听器:

<script>
  export let placeholder = "";
  export let label = "";
  export let description = "";
  export let value = "";
  export let type = "text";

  const handleInput = e => {
    // in here, you can switch on type and implement
    // whatever behaviour you need
    value = type.match(/^(number|range)$/)
      ? +e.target.value
      : e.target.value;
  };
</script>

<div class="container">
    <label>{label}</label>
    <input {type} {value} {placeholder} on:input={handleInput} />
    <p>{description}</p>
</div>

答案 1 :(得分:0)

一个简单的解决方法:通过id获取元素并使用element.setAttribute(attributename, attributevalue)设置类型

<script>
  export let id = "";
  export let placeholder = "";
  export let label = "";
  export let description = "";
  export let value = "";
  export let type = "text";
</script>

<div class="container">
    <label>{label}</label>
    <input {type} bind:value {placeholder}
    on:focus="{() => {
       console.log(type)
       let inpt =    document.getElementById(id)
       inpt.setAttribute("type", type)
       console.log(inpt)
    }}"/>
    <p>{description}</p>
</div>

希望它会有所帮助:-)

答案 2 :(得分:0)

<!-- InputField.svelte -->
<script>
  export let placeholder = "";
  export let label = "";
  export let description = "";
  export let value = "";
  export let type = "text";

  const handleInputType = (e) => {
    e.target.type = type;
  };
</script>

<div class="container">
    <label>{label}</label>
    <input {value} {placeholder} on:input={handleInputType} />
    <p>{description}</p>
</div>

为简化起见,我遇到了上面的事情,基本上,我删除了输入中的{type},在输入时我只是修改了目标类型,因为这是一个组件,因此父/路由苗条文件。

<InputField type="email" bind:value={emailValue} />

答案 3 :(得分:0)

这样的事情怎么样?

export let type: 'email' | 'text' | 'password' | 'number' = 'text'

let ref: HTMLInputElement

onMount(() => {
  if (ref) {
    ref.type = type
  }
})

然后

<input bind:this={ref} />

export let type: 'email' | 'text' | 'password' | 'number' = 'text'

const ref = (node: HTMLInputElement) => {
  node.type = type
}

然后

<input use:ref />