svelte教程(6)數據綁定

雙向數據綁定

雙向綁定意味着當我們更改name的值時會更新input輸入框的值,更改input輸入框值的時候name的值同樣會改變。

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

<input bind:value={name}>

<h1>Hello {name}!</h1>

如果您有多個與同一個值相關的輸入,則可以bind:group與value屬性一起使用。同一組中的單選框是互斥的;同一組中的複選框輸入形成選定值的數組。

<script>
  let scoops=1
  let flavours = ['Mint choc chip'];
  let menu = [
        'Cookies and cream',
        'Mint choc chip',
        'Raspberry ripple'
    ];
</script>

<label>
    <input type=radio bind:group={scoops} value={1}>
    One scoop
</label>

<label>
    <input type=radio bind:group={scoops} value={2}>
    Two scoops
</label>

<label>
    <input type=radio bind:group={scoops} value={3}>
    Three scoops
</label>
<div>
{#each menu as flavour}
    <label>
        <input type=checkbox bind:group={flavours} value={flavour}>
        {flavour}
    </label>
{/each}
</div>

我們還可以使用bind:value與元素綁定:

<script>
  let questions = [
    { id: 1, text: `Where did you go to school?` },
    { id: 2, text: `What is your mother's name?` },
    {
      id: 3,
      text: `What is another personal fact that an attacker could easily find with Google?`
    }
  ];
  let selected;
</script>

<select bind:value={selected}>
  {#each questions as question}
    <option value={question.id} label={question.text}></option>
  {/each}
</select>

<p>The question is "{selected?questions.filter(q => q.id === selected)[0].text:null}"</p>

的value值也可以是對象

<script>
  let questions = [
    { id: 1, text: `Where did you go to school?` },
    { id: 2, text: `What is your mother's name?` },
    {
      id: 3,
      text: `What is another personal fact that an attacker could easily find with Google?`
    }
  ];

    let selected;
</script>

<select bind:value={selected}>
  {#each questions as question}
    <option value={question} label={question.text}></option>
  {/each}
</select>

<p>The question is "{selected?selected.text:''}"</p>

一個可以具有一個multiple屬性,在這種情況下,它將綁定一個數組而不是一個值。

<script>
  let questions = [
    { id: 1, text: `Where did you go to school?` },
    { id: 2, text: `What is your mother's name?` },
    {
      id: 3,
      text: `What is another personal fact that an attacker could easily find with Google?`
    }
  ];

  let selectedList = [];
</script>


<select bind:value={selectedList} multiple>
  {#each questions as question}
    <option value={question} label={question.text} />
  {/each}
</select>

{#each selectedList as selected}
   <p>The question is "{selected.text}"</p>
{/each}

contenteditable

具有contenteditable="true"屬性的元素支持綁定textContent和innerHTML。

<script>
  let html = "<p>Write some text!</p>";
  let text = "Write some text!";
</script>

<style>
  [contenteditable] {
    padding: 0.5em;
    border: 1px solid #eee;
    border-radius: 4px;
  }
</style>

<div contenteditable="true" bind:innerHTML={html} />

<div contenteditable="true" bind:textContent={text} />

<pre>{html}</pre>
<p>{text}</p>

循環中使用數據綁定

<script>
    let todos = [
        { done: false, text: 'finish Svelte tutorial' },
        { done: false, text: 'build an app' },
        { done: false, text: 'world domination' }
    ];

    function add() {
        todos = todos.concat({ done: false, text: '' });
    }

    function clear() {
        todos = todos.filter(t => !t.done);
    }

    $: remaining = todos.filter(t => !t.done).length;
</script>

<style>
    .done {
        opacity: 0.4;
    }
</style>

<h1>Todos</h1>

{#each todos as todo}
    <div class:done={todo.done}>
        <input
            type=checkbox
            bind:checked={todo.done}
        >

        <input
            placeholder="What needs to be done?"
            bind:value={todo.text}
        >
    </div>
{/each}

<p>{remaining} remaining</p>

<button on:click={add}>
    Add new
</button>

<button on:click={clear}>
    Clear completed
</button>

clientWidth、clientHeight、offsetWidth、offsetHeight

這些屬性爲只讀屬性改變w、h的值不會更新元素。inline元素沒有寬高。

<script>
  let w;
  let h;
  let w2;
  let h2;
  let size = 42;
  let text = "edit me";
</script>

<style>
  input {
    display: block;
    margin: 20px auto;
  }
  div {
    display: block;
  }
  .inline {
    display: inline;
  }
</style>

<input type="range" bind:value={size} />
<input bind:value={text} />

<p>size: {w}px x {h}px</p>

<div bind:clientWidth={w} bind:clientHeight={h}>
  <span style="font-size: {size}px">{text}</span>
</div>

<p>line size: {w2}px x {h2}px</p>
<div bind:clientWidth={w2} bind:clientHeight={h2} class="inline">
  <span style="font-size: {size}px">{text}</span>
</div>

bind:this

bind:this可以拿到一個元素的引用。

<script>
  let w;
  let h;
  let w2;
  let h2;
  let size = 42;
  let text = "edit me";
  function getRects(){
    console.log(this.getClientRects())
    console.log(this.getBoundingClientRect())
  }
</script>

<style>
  input {
    display: block;
    margin: 20px auto;
  }
  div {
    display: block;
  }
  .inline {
    display: inline;
  }
</style>

<input type="range" bind:value={size} />
<input bind:value={text} />

<p>size: {w}px x {h}px</p>
<div
  on:click={getRects}
  bind:clientWidth={w}
  bind:clientHeight={h}>
  <span style="font-size: {size}px">{text}</span>
</div>

<p>line size: {w2}px x {h2}px</p>
<div
  on:click={getRects}
  bind:clientWidth={w2}
  bind:clientHeight={h2}
  class="inline">
  <span style="font-size: {size}px">
    {text}
  </span>
</div>

組件數據綁定

正如可以綁定到DOM元素的屬性一樣,也可以綁定到組件prop。

// Keypad.svelte
<script>
  import { createEventDispatcher } from "svelte";

  export let value = "";

  const dispatch = createEventDispatcher();

  const select = num => () => (value += num);
  const clear = () => (value = "");
  const submit = () => dispatch("submit");
</script>

<style>
  .keypad {
    display: grid;
    grid-template-columns: repeat(3, 5em);
    grid-template-rows: repeat(4, 3em);
    grid-gap: 0.5em;
    justify-content: center;
  }

  button {
    margin: 0;
  }
</style>

<div class="keypad">
  <button on:click={select(1)}>1</button>
  <button on:click={select(2)}>2</button>
  <button on:click={select(3)}>3</button>
  <button on:click={select(4)}>4</button>
  <button on:click={select(5)}>5</button>
  <button on:click={select(6)}>6</button>
  <button on:click={select(7)}>7</button>
  <button on:click={select(8)}>8</button>
  <button on:click={select(9)}>9</button>

  <button disabled={!value} on:click={clear}>clear</button>
  <button on:click={select(0)}>0</button>
  <button disabled={!value} on:click={submit}>submit</button>
</div>

// component_bind.svelte
<script>
    import Keypad from '../components/Keypad';

    let pin;
    $: view = pin ? pin.replace(/\d(?!$)/g, '•') : 'enter your pin';

    function handleSubmit() {
        alert(`submitted ${pin}`);
    }
</script>
<h1 style="color: {pin ? '#333' : '#ccc'}">{view}</h1>

<Keypad bind:value={pin} on:submit={handleSubmit}/>

本教程的所有代碼均上傳到github有需要的同學可以參考 https://github.com/sullay/svelte-learn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章