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与<select>元素绑定:

<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>

<option >的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>

一个<select >可以具有一个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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容