使用Svelte在数据和UI之间创建一个双向的绑定

486 阅读3分钟

使用Svelte,你可以在数据和UI之间创建一个双向的绑定。

许多其他的Web框架都可以提供双向绑定,这是一个非常常见的模式。

它们在表单中特别有用。

bind:value

让我们从你经常使用的最常见的绑定形式开始,你可以使用bind:value 。你从组件状态中获取一个变量,并将其绑定到一个表单字段。

<script>
let name = ''
</script>

<input bind:value={name}>

现在,如果name ,输入字段将更新其值。反之亦然:如果表单被用户更新,name 变量的值也会改变。

请注意,这个变量必须用let/var ,而不是const ,否则它就不能被Svelte更新,因为const 定义了一个不能被重新分配的变量值。

bind:value 这个方法适用于所有类型的输入字段( , 等),但它也适用于其他类型的字段,如 和 (稍后将详细介绍 )。type="number" type="email" textarea select select

复选框和单选按钮

复选框和单选输入 (input 元素与type="checkbox"type="radio") 允许这三种绑定。

  • bind:checked
  • bind:group
  • bind:indeterminate

bind:checked 允许我们将一个值绑定到元素的选中状态。

<script>
let isChecked
</script>

<input type=checkbox bind:checked={isChecked}>

bind:group 对复选框和单选输入来说是很方便的,因为这些元素经常被用在组中。使用 ,你可以将一个JavaScript数组与一个复选框列表联系起来,并根据用户的选择进行填充。bind:group

下面是一个例子。goodDogs 数组根据我勾选的复选框进行填充。

<script>
let goodDogs = []
let dogs = ['Roger', 'Syd']
</script>

<h2>
  Who's a good dog?
</h2>

<ul>
  {#each dogs as dog}
    <li>{dog} <input type=checkbox bind:group={goodDogs} value={dog}></li>
  {/each}
</ul>

<h2>
  Good dogs according to me:
</h2>

<ul>
  {#each goodDogs as dog}
    <li>{dog}</li>
  {/each}
</ul>

svelte.dev/repl/059c1b…上的例子

bind:indeterminate 允许我们绑定到一个元素的 状态(如果你想了解更多,请访问indeterminate css-tricks.com/indetermina…

选择字段

bind:value 也适用于 表单字段,使选择的值自动分配给一个变量的值。select

<script>
let selected
</script>

<select bind:value={selected}>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
</select>

{selected}

最酷的是,如果你从一个对象数组中动态生成选项,那么现在选择的选项是一个对象而不是一个字符串。

<script>
let selected

const goodDogs = [
  { name: 'Roger' },
  { name: 'Syd' }
]
</script>

<h2>List of possible good dogs:</h2>
<select bind:value={selected}>
  {#each goodDogs as goodDog}
    <option value={goodDog}>{goodDog.name}</option>
  {/each}
</select>

{#if selected}
<h2>
  Good dog selected: {selected.name}
</h2>
{/if}

见例子:https://svelte.dev/repl/7e06f9b7becd4c57880db5ed184ea0f3

select 也允许使用 属性。multiple

<script>
let selected = []

const goodDogs = [
  { name: 'Roger' },
  { name: 'Syd' }
]
</script>

<h2>List of possible good dogs:</h2>
<select multiple bind:value={selected}>
  {#each goodDogs as goodDog}
    <option value={goodDog}>{goodDog.name}</option>
  {/each}
</select>

{#if selected.length}
<h2>Good dog selected:</h2>
<ul>
  {#each selected as dog}
    <li>{dog.name}</li>
  {/each}
</ul>
{/if}

参见示例:https://svelte.dev/repl/b003248e87f04919a2f9fed63dbdab8c

其他捆绑方式

根据你正在处理的HTML标签,你可以应用不同种类的绑定。

bind:files 是一个对 输入元素有效的绑定,用于绑定所选文件的列表。type="file"

details HTML元素允许使用bind:open 绑定其打开/关闭值。

audiovideo 媒体HTML标签允许你绑定它们的几个属性。currentTime,duration,paused,buffered,seekable,played,volume,playbackRate

textContent 和 可以绑定在 字段上。innerHTML contenteditable

所有的东西对那些特定的HTML元素非常有用。

只读的绑定

offsetWidth,offsetHeight,clientWidth,clientHeight 可以在任何块级HTML元素上进行只读绑定,不包括无效标签(如br )和被设置为内联的元素(display: inline )。

在JavaScript中获取一个对HTML元素的引用

bind:this 是一种特殊的绑定方式,它允许你获得一个HTML元素的引用并将其绑定到一个JavaScript变量上。

<script>
let myInputField
</script>

<input bind:this={myInputField} />

当你需要在装入元素后对其应用逻辑时,这很方便,例如,使用onMount() 生命周期事件的回调。

绑定组件道具

使用bind: ,你可以将一个值绑定到一个组件所暴露的任何道具上。

假设你有一个Car.svelte 组件。

<script>
export let inMovement = false
</script>

<button on:click={() => inMovement = true }>Start car</button>

你可以导入该组件并绑定inMovement 的道具。

<script>
  import Car from './Car.svelte';

  let carInMovement;
</script>

<Car bind:inMovement={carInMovement} />

{carInMovement}

这可以允许有趣的情况发生。