Getting started with Svelte - Bi

2023-11-27  本文已影响0人  游文影月志

Text inputs

<input bind:value={name}>

Two-way binding.

Numeric inputs

In the DOM, everything is a string. That's unhelpful when you're dealing with numeric inputs — type="number" and type="range" — as it means you have to remember to coerce input.value before using it.

With bind:value, Svelte takes care of it for you:

<input type="number" bind:value={a} min="0" max="10" />
<input type="range" bind:value={a} min="0" max="10" />

Checkbox inputs

Checkboxes are used for toggling between states. Instead of binding to input.value, we bind to input.checked:

<input type="checkbox" bind:checked={yes} />

Select bindings

We can also use bind:value with <select> elements:

<select
    bind:value={selected}
    on:change={() => (console.log(selected))}
>
    {#each questions as question}
        <option value={question}>
            {question.text}
        </option>
    {/each}
</select>

Note that the <option> values are objects rather than strings.

Group inputs

If you have multiple type="radio" or type="checkbox" inputs relating to the same value, you can use bind:group along with the `value attribute. Radio inputs in the same group are mutually exclusive; checkbox inputs in the same group form an array of selected values.

<script>
    let scoops = 1;
    let flavours = [];

    const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
</script>

<h2>Size</h2>

{#each [1, 2, 3] as number}
    <label>
        <input
            type="radio"
            name="scoops"
            value={number}
            bind:group={scoops}
        />

        {number} {number === 1 ? 'scoop' : 'scoops'}
    </label>
{/each}

<h2>Flavours</h2>

{#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
    <label>
        <input
            type="checkbox"
            name="flavours"
            value={flavour}
            bind:group={flavours}
        />

        {flavour}
    </label>
{/each}

{#if flavours.length === 0}
    <p>Please select at least one flavour</p>
{:else if flavours.length > scoops}
    <p>Can't order more flavours than scoops!</p>
{:else}
    <p>
        You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
        of {formatter.format(flavours)}
    </p>
{/if}

Select multiple

A <select> element can have a multiple attribute, in which case it will populate an array rather than selecting a single value.

Note that we're able to omit the value attribute on the <option>, since the value is identical to the element's contents.

<script>
    let scoops = 1;
    let flavours = [];

    const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
</script>

<h2>Size</h2>

{#each [1, 2, 3] as number}
    <label>
        <input
            type="radio"
            name="scoops"
            value={number}
            bind:group={scoops}
        />

        {number} {number === 1 ? 'scoop' : 'scoops'}
    </label>
{/each}

<h2>Flavours</h2>

<select multiple bind:value={flavours}>
    {#each ['cookies and cream', 'mint choc chip', 'raspberry ripple'] as flavour}
        <option>{flavour}</option>
    {/each}
</select>

{#if flavours.length === 0}
    <p>Please select at least one flavour</p>
{:else if flavours.length > scoops}
    <p>Can't order more flavours than scoops!</p>
{:else}
    <p>
        You ordered {scoops} {scoops === 1 ? 'scoop' : 'scoops'}
        of {formatter.format(flavours)}
    </p>
{/if}

Press and hold the control key (or the command key on MacOS) to select multiple options.

Textarea inputs

The <textarea> element behaves similarly to a text input in Svelte — use bind:value:

<script>
    import { marked } from 'marked';
    let value = `Some words are *italic*, some are **bold**\n\n- lists\n- are\n- cool`;
</script>

<div class="grid">
    input
    <textarea bind:value></textarea>

    output
    <div>{@html marked(value)}</div>
</div>

<style>
    .grid {
        display: grid;
        grid-template-columns: 5em 1fr;
        grid-template-rows: 1fr 1fr;
        grid-gap: 1em;
        height: 100%;
    }

    textarea {
        width: 500px;
        resize: none;
    }
</style>
上一篇下一篇

猜你喜欢

热点阅读