Svelte

# 視頻教程

http://noover.leanapp.cn/courses

# 安裝(Install)

npm install -g svelte-cli

# 創(chuàng)建一個會說你好世界的組件(HelloWorld Component)

  • 新建一個項目文件夾,新建一個 HelloWrold.html 內(nèi)容如下。
<!-- HelloWrold 組件 -->
<h1>你好 {{name}}</h1>
  • 使用命令編譯 html 文件
svelte compile --format iife HelloWorld.html > HelloWorld.js
  • 創(chuàng)建 index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Svelte Application</title>
</head>
<body>
    
    <application></application>
    
    <script src="./HelloWorld.js"></script>
    <script>
      var app = new HelloWorld({
        target: document.querySelector( 'application' ),
        data: {
          name: '世界'
        }
      });
    </script>
</body>
</html>

# 組件實例方法(Component API)

創(chuàng)建一個組件的實例的方法就是通過 new 調(diào)用并傳入配置項

  • 要加載到的 DOM 節(jié)點上面
target: document.querySelector( 'main' )
  • 組件的初始數(shù)據(jù)
data: {
    author: {
      name: '近藤麻理惠'
      gender: 'female'
      nationality: 'Japan'
    },
    title: '怦然心動人生整理魔法'
    recommendedReason: '勤儉持家,人人有責(zé)劈榨。無論男女脏嚷,統(tǒng)統(tǒng)要干褒颈。'
}

# 在我們的 HelloWorld 例子中安皱,在你的Chrome 控制臺輸入以下內(nèi)容

以下內(nèi)容都是實例的方法,每次開始測試之前可以刷新一下氛雪,清空之前的變量想虎。

# get

app.get('name')
// "世界"

# set

app.set({ name: '天地' })

# observe

observe 字面上的意思就是觀察卦尊,在代碼中的意思就是觀察 name,當(dāng)值改變的時候就執(zhí)行回調(diào)函數(shù)磷醋。

可以看到加上觀察就立馬觸發(fā)了回調(diào)猫牡,打印了當(dāng)前 name 的值

const observer = app.observe( 'name', name => {
  console.log( `當(dāng)前 name 的值是 ${name}` );
});

app.set({name:'虛空大帝'})

observer.cancel() // 取消觀察

app.set({name:'皓月大帝'})

傳入{ init: false } 那么第一次就不會觸發(fā)

app.observe( 'name', ( newValue, oldValue ) => {
  console.log( `長度對比 ${newValue.length > oldValue.length ? 'new > old' : 'new < old'}` );
}, { init: false });

app.set({name:'宵元大帝~'})

默認(rèn)所有回調(diào)會在更新前完成,傳入{ defer: true } 會導(dǎo)致回調(diào)在組件更新完成之后調(diào)用邓线。
這樣的操作組要是跟 Dom 有關(guān)聯(lián)淌友,所以我們需要添加一點代碼來驗證它們。

  • HelloWorld.html
<h1>你好 {{name}}</h1>

<canvas id="canvas-container" width="{{ canvas_width }}" height="{{ canvas_height }}"></canvas>

<style type="text/css">
    #canvas-container{
        background: #7F7BFF;
    }
</style>
  • 重新編譯一下
svelte compile --format iife HelloWorld.html > HelloWorld.js
  • index.html
  var app = new HelloWorld({
    target: document.querySelector( 'application' ),
    data: {
      name: '世界',
      canvas_width: '350',
      canvas_height: '150'
    }
  });

  function redraw(newValue, oldValue) {
    const canvas = document.querySelector('#canvas-container')
    console.log("Dom height " + canvas.height);
    console.log("Dom width " + canvas.width);
    console.log(newValue + "  -> " + oldValue);
  }

  app.observe('canvas_width', redraw, { init: false})
  app.observe('canvas_height', redraw, { defer : true, init: false })
  • 在控制臺里面輸入
app.set({ canvas_height: 20 })
app.set({ canvas_width: 20 })

# on

on 在 js 語言中通常監(jiān)聽某一事件骇陈,這很符合慣例

const listener = app.on( 'eat', event => {
  console.log( `${event.name} 超齡兒童震庭,你老婆叫你回家吃晚飯了` );
});

# fire

觸發(fā)某一事件

app.fire( 'eat', {
  name: 'Alex'
});
  • teardown

刪除 DOM 會觸發(fā)這個事件

app.on( 'teardown', () => {
  alert( '滾蛋吧 組件君!' ); 
});

app.teardown()

# HelloWorld 組件源碼分析

  • NeedTodo

# 組件模板語法(Template syntax)

# 變量

使用小胡子Mustaches語法輸出變量

<p>{{a}} + {} = {{a + b}}</p>
<h1 style='color: {{color}};'>{{color}}</h1>

# 條件

{{#if user }}
    <div>{{ user.name }} is beautful girl!</div>
{{/if}}
{{#if x > 10}}
  <p>{{x}} 大于 10</p>
{{elseif 5 > x}}
  <p>{{x}} 小于 5</p>
{{else}}
  <p>{{x}} 在 5 與 10 之間</p>
{{/if}}

# 循環(huán)

<h1>水果大家庭</h1>

<ul>
  {{#each fruits as fruit}}
    <li>{{fruit}}</li>
  {{/each}}
</ul>
fruits: ['蘋果','梨','香蕉','葡萄','橘子','菩提','火龍果','荔枝']

# 指令

<p>Count: {{count}}</p>
<button on:click='set({ count: count + 1 })'>+1</button>

# 組件樣式(Style)

<canvas id="canvas-container" width="{{ canvas_width }}" height="{{ canvas_height }}"></canvas>


<style type="text/css">
    #canvas-container{
        background: #7F7BFF;
    }
</style>

# 組件行為(Script)

# 組件屬性

<p>Count: {{count}}</p>
<button on:click='set({ count: count + 1 })'>+1</button>

<script>
  export default {
    data () {
      return {
        count: 0
      };
    }
  };
</script>

# 計算屬性

<p>
  The time is
  <strong>{{hours}}:{{minutes}}:{{seconds}}</strong>
</p>

<script>
  export default {
    data () {
      return {
        time: new Date()
      };
    },

    computed: {
      hours: time => time.getHours(),
      minutes: time => time.getMinutes(),
      seconds: time => time.getSeconds()
    }
  };
</script>

# 生命周期

<script>
  export default {
    onrender () {
      this.interval = setInterval( () => {
        this.set({ time: new Date() });
      }, 1000 );
    },

    onteardown () {
      clearInterval( this.interval );
    },

    data () {
      return {
        time: new Date()
      };
    },

    computed: {
      hours: time => time.getHours(),
      minutes: time => time.getMinutes(),
      seconds: time => time.getSeconds()
    }
  };
</script>

# 幫助函數(shù)

把你需要的函數(shù)放到 helpers 里面那就可以在模板中使用了你雌,但是必須是純函數(shù)器联。

<p>
  The time is
  <strong>{{hours}}:{{leftPad(minutes, 2, '0')}}:{{leftPad(seconds, 2, '0')}}</strong>
</p>

<script>

  function leftPad(str, len, ch) {
      str = str + '';

      len = len - str.length;
      if (len <= 0) return str;

      if (!ch && ch !== 0) ch = ' ';
      ch = ch + '';

      return ch.repeat(len) + str;
  };
    
  export default {
    helpers: {
      leftPad
    },

    onrender () {
      this.interval = setInterval( () => {
        this.set({ time: new Date() });
      }, 1000 );
    },

    onteardown () {
      clearInterval( this.interval );
    },

    data () {
      return {
        time: new Date()
      };
    },

    computed: {
      hours: time => time.getHours(),
      minutes: time => time.getMinutes(),
      seconds: time => time.getSeconds()
    }
  };
</script>

# 組件方法

<button on:click='say("hello")'>say hello!</button>

<script>
  export default {
    methods: {
      say ( message ) {
        alert( message ); 
      }
    }
  };
</script>

# 組件事件

記得在你的 data 上添加 done 變量
node 就是當(dāng)前的 dom 節(jié)點,callback 就是我要執(zhí)行的代碼婿崭,自行打印一下就很清楚了拨拓。

<button on:longpress='set({ done: true })'>click and hold</button>

{{#if done}}
  <p>clicked and held</p>
{{/if}}

<script>
  export default {
    events: {
      longpress ( node, callback ) {
        function onmousedown ( event ) {
          const timeout = setTimeout( () => callback( event ), 1000 );

          function cancel () {
            clearTimeout( timeout );
            node.removeEventListener( 'mouseup', cancel, false );
          }

          node.addEventListener( 'mouseup', cancel, false );
        }

        node.addEventListener( 'mousedown', onmousedown, false );

        return {
          teardown () {
            node.removeEventListener( 'mousedown', onmousedown, false );
          }
        };
      }
    }
  };
</script>

# 子組件

此小節(jié)注意大小寫,組件用大寫氓栈,別弄錯了渣磷。

  • 創(chuàng)建一個新的文件 Widget.html
<div class="widget-container">
    <h1>hei! Widget</h1>
</div>
  • 編譯一下
svelte compile -f iife -i Widget.html -o Widget.js
  • 給 HelloWrold 添加一下代碼
import Widget from './Widget.html';

export default {
    components: {
        Widget
    },
    ......
}
  • 編譯一下 HelloWorld.html
svelte compile -f iife HelloWorld.html > HelloWorld.js
  • 在給 index.html 修改一下代碼
    Widget 由于被 HelloWorld 依賴所以需要先加載
    <script src="./Widget.js"></script>
    <script src="./HelloWorld.js"></script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市授瘦,隨后出現(xiàn)的幾起案子醋界,更是在濱河造成了極大的恐慌,老刑警劉巖提完,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件形纺,死亡現(xiàn)場離奇詭異,居然都是意外死亡徒欣,警方通過查閱死者的電腦和手機逐样,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人官研,你說我怎么就攤上這事秽澳。” “怎么了戏羽?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長楼吃。 經(jīng)常有香客問我始花,道長,這世上最難降的妖魔是什么孩锡? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任酷宵,我火速辦了婚禮,結(jié)果婚禮上躬窜,老公的妹妹穿的比我還像新娘浇垦。我一直安慰自己,他們只是感情好荣挨,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布男韧。 她就那樣靜靜地躺著,像睡著了一般默垄。 火紅的嫁衣襯著肌膚如雪此虑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天口锭,我揣著相機與錄音朦前,去河邊找鬼。 笑死鹃操,一個胖子當(dāng)著我的面吹牛韭寸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荆隘,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼恩伺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了臭胜?” 一聲冷哼從身側(cè)響起莫其,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎耸三,沒想到半個月后乱陡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡仪壮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年憨颠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡爽彤,死狀恐怖养盗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情适篙,我是刑警寧澤往核,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嚷节,受9級特大地震影響聂儒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜硫痰,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一衩婚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧效斑,春花似錦非春、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至藏研,卻和暖如春敬矩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蠢挡。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工弧岳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人业踏。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓禽炬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親勤家。 傳聞我的和親對象是個殘疾皇子腹尖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,185評論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法伐脖,內(nèi)部類的語法热幔,繼承相關(guān)的語法,異常的語法讼庇,線程的語...
    子非魚_t_閱讀 31,644評論 18 399
  • 我想工作!
    羅一一的日記本閱讀 118評論 0 1
  • 荷包里的娓娓閱讀 234評論 0 0
  • 有時候我們都會想绎巨,生活給了我們什么,是生活給了我們蠕啄,還是我們?nèi)?chuàng)造了生活场勤。每每深夜睡不著覺戈锻,自己就會想很多事,有...
    基里閱讀 298評論 0 1