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

GAG*_*NGH 3 svelte

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

但是当我动态设置type属性时,input出现错误提示 '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>
Run Code Online (Sandbox Code Playgroud)

kjd*_*n84 21

use组件中用于设置节点类型的函数:

输入.svelte:

<script>
    export let type = 'text'
    export let label
    export let value

    function typeAction(node) {
        node.type = type;
    }
</script>

<div class="space-y-1">
    <label>{label}</label>

    <input use:typeAction bind:value class="rounded-md w-full">

    <p class="text-sm text-red-600">errors</p>
</div>
Run Code Online (Sandbox Code Playgroud)

表单.svelte:

    <form on:submit|preventDefault={login}>
        <Input type="email" label="Email" bind:value={values.email}/>
        <Input type="password" label="Password" bind:value={values.password}/>

        <Button type="submit" label="Login"/>
    </form>
Run Code Online (Sandbox Code Playgroud)


KTi*_*bow 15

如果你想仍然使用bind:value和SSR,你可以这样做:

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

<input bind:value {...{ type }} />
Run Code Online (Sandbox Code Playgroud)


Ric*_*ris 10

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>
Run Code Online (Sandbox Code Playgroud)


Esc*_*ton 10

另一种可能的解决方案不是非常优雅或干燥,但不需要自己模拟核心 Svelte 功能,即简单地分支type并相应地渲染不同的输入:

<script>
  export let name;
  export let value;
  export let type = 'text';
</script>


{#if type === 'password'}
  <input
    type="password"
    id={name}
    {name}
    on:change
    on:blur
    bind:value
  />
{:else if type === 'email'}
  <input
    type="email"
    id={name}
    {name}
    on:change
    on:blur
    bind:value
  />
{:else if type === 'number'}
  <input
    type="number"
    id={name}
    {name}
    on:change
    on:blur
    bind:value
  />
{:else if type === 'date'}
  <input
    type="date"
    id={name}
    {name}
    on:change
    on:blur
    bind:value
  />
{:else}
  <input
    type="text"
    id={name}
    {name}
    on:change
    on:blur
    bind:value
  />
{/if}
Run Code Online (Sandbox Code Playgroud)