我试图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生成的代码对于不同类型的输入是不同的。例如,number与range输入必须有自己的价值观强制转换为数字,一些投入需要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)