Svelte响应式计算变量绑定input无法输入的解决方法
问题根源
你用$:声明的name和lastName属于单向派生响应式值,取值完全由依赖项loggedInUserInfo决定:
- 只要
loggedInUserInfo发生变动,Svelte就会重新执行派生语句,把两个变量强制重置为store中存储的对应值 - 输入框输入时,
bind:value虽然会临时修改变量值,但组件更新时派生逻辑会立刻覆盖你输入的内容,最终表现为输入框完全无法输入内容
如果把$:换成let声明普通变量,变量不会随store更新自动同步,虽然能正常输入,但也无法拿到接口返回的初始化值。
解决方案
根据你的业务场景二选一即可:
方案1:本地暂存表单值(适合常规编辑表单场景)
用普通let声明表单绑定的本地变量,在store更新时主动给本地变量赋值,输入内容默认存在本地,需要提交时再同步回store,避免输入过程被打断:
修改App.svelte代码如下:
<script> import {loggedInUserProfile} from './store.js' import { onMount } from 'svelte' import {update} from './util.js' let loggedInUserInfo // 声明绑定到输入框的本地变量 let name = '' let lastName = '' // 订阅store,仅当store的用户信息更新时,同步赋值给本地表单变量 loggedInUserProfile.subscribe((value) => { loggedInUserInfo = value if (value) { name = value.name lastName = value.lastName } }) onMount(() => { console.log('App onMount called') update() }) const capitalizeFirstLetter = (string) => { return string?.charAt(0).toUpperCase() + string?.slice(1); } // 👉 如果需要输入实时同步回store,取消下方注释即可;如果是表单编辑场景,建议在提交按钮的逻辑里统一更新store // $: if (loggedInUserInfo) loggedInUserProfile.set({ ...loggedInUserInfo, name, lastName }) </script> <div style="display:flex; flex-direction: column;"> <div> <span>Name: </span><input label="name" bind:value={name}> </div> <div> <span>Last Name: </span><input bind:value={lastName}> </div> </div>
方案2:直接双向绑定store值(适合需要实时同步store的场景)
用Svelte内置的store自动订阅语法($前缀直接访问store值),不需要额外声明中间变量,直接绑定store的对应属性即可:
注意:需要先给store设置初始空对象,避免初始值为
undefined时绑定属性报错,比如store初始化时写为export const loggedInUserProfile = writable({})
<script> import {loggedInUserProfile} from './store.js' import { onMount } from 'svelte' import {update} from './util.js' onMount(() => { console.log('App onMount called') update() }) const capitalizeFirstLetter = (string) => { return string?.charAt(0).toUpperCase() + string?.slice(1); } </script> <div style="display:flex; flex-direction: column;"> <div> <span>Name: </span><input label="name" bind:value={$loggedInUserProfile.name}> </div> <div> <span>Last Name: </span><input bind:value={$loggedInUserProfile.lastName}> </div> </div>
内容的提问来源于stack exchange,提问作者Andi Keikha
相关产品推荐
相关产品推荐

