我怎样才能拥有一个 <input type=... 属性,该属性在 Svelte 组件的实例化时有所不同,同时在反应性系统中具有其价值?

How can I have an <input type=… attribute that varies on instantiations of a Svelte component while having its value in the reactivity system?

我有一个 FormRow 组件,大致如下所示(为简洁起见,此处删除了样式和布局信息,这就是我想要一个组件的原因):

<script>
  export let label;
  export let type;
  export let value;
</script>
<input type={type} bind:value={value}>

它的用法是这样的:

<FormRow title="Email: " type="email" value={email}/>
<FormRow title="Username:"  type="text" value={username}/>
<FormRow title="Password: " type="password" value={password}/>
<FormRow title="Confirm Password: " type="password" value={confirmPassword}/>

目的是在提交表单时访问 JS 中的电子邮件、用户名、密码和 confirmPassword 变量,并可能使用反应性来添加输入验证(当然除了服务器端验证之外) .但是,当我尝试编译它时,出现了这个错误:

ERROR in ./src/pages/_components/FormRow.svelte
Module build failed (from ./node_modules/svelte-loader/index.js):
Error: ValidationError: 'type' attribute cannot be dynamic if input uses two-way binding (31:22)
29:         {title}
30:     </label>
31:     <input id="input" type={type} bind:value={value}>

我想我明白问题是什么(类型和值不能同时通过反应系统设置),但我不知道如何完成我想要的(可重用和通用的 FormRow 组件) .我认为可能有其他方法可以为每个 FormRow 实例设置 type 属性,因为我不需要它在任何特定实例的运行时更改,但我找不到任何技术让它根据每个 - Svelte 文档中这样的组件基础。

根据输入类型,Svelte 将在绑定到元素时使用不同的事件侦听器。例如,<input type="text"> 上的 bind:value 监听更新的输入事件,而 <input type="checkbox"> 上的 bind:checked 监听更改事件。 Svelte 需要在编译时知道输入是什么类型才能生成这些侦听器,这就是为什么当您使用双向绑定时它不会让类型属性是动态的。

如果你想要一个动态输入类型,你需要自己生成监听器来更新值。假设您只使用在 value 更新时分派 input 事件的类型,您可以执行以下操作:

<!-- FormRow.svelte -->
<script>
    export let label;
    export let type;
    export let value = '';
    
    function handleInput(e) {
        value = e.target.value;
    }
</script>
<label><input type={type} value={value} on:input={handleInput}> {label}</label>

<!-- App.svelte -->
<script>
    import FormRow from './FormRow.svelte';
    let value = 'hello';    
</script>

<p>
    Current value: {value}
</p>
<FormRow label="test" type="text" bind:value={value} />