帶你走馬觀花联逻,細(xì)看新版變化。
注意:原文發(fā)表于2018-04-18检痰,隨著框架不斷演進(jìn)包归,部分內(nèi)容可能已不適用。
大約是一年之前铅歼,我們首次在 Svelte 的 issue 跟蹤器上討論過 v2 版本公壤,現(xiàn)在是時(shí)候進(jìn)行一些重大變更了换可。
我們的座右銘是“循序漸進(jìn),破舊立新”境钟。
……好吧锦担,我錯(cuò)了,看來我要改過自新了慨削。
這篇博文闡述了新版本的變化,都變了哪些地方套媚、為什么要變以及應(yīng)對的策略缚态。
長話短說,先看梗概
我們會不厭其詳?shù)孛枋雒恳粋€(gè)變更細(xì)項(xiàng)堤瘤,如果你還是遇到了困難玫芦,請?jiān)谖覀儦夥沼押玫?Discord 聊天室 中尋求幫助。
從 npm 安裝 Svelte v2
用 svelte-upgrade 升級你的模板
刪除對
component.observe
方法的調(diào)用本辐,或者從 svelte-extras 中添加observe
方法將對
component.get('foo')
的調(diào)用重寫為component.get().foo
從你的自定義事件處理程序中返回
destroy
桥帆,而不是teardown
確保沒有將值是數(shù)字類型的字符串作為 props 傳遞給組件
最新的模板語法
最明顯的變化是:我們對模板語法做了一些改進(jìn)。
我們經(jīng)常聽到的反饋是慎皱,“哎呀老虫,又是Mustache”或者“哎呀,這不Handlebars嘛”茫多。
在 Web 開發(fā)的較早時(shí)期祈匙,許多開發(fā)者使用基于字符串的模板系統(tǒng),但他們似乎對模板深痛惡絕天揖。
由于 Svelte 也采用了這種 {{表達(dá)式}}
的語法夺欲,因此許多人以為我們也在某種程度上有那些相同的局限性,比如奇怪的作用域規(guī)則今膊,或者無法隨意使用 JavaScript 表達(dá)式些阅。
提示:如果你需要顯示一個(gè) '{' 字符,那么它可以簡單地用 '{' 來表示斑唬。
除此以外市埋,JSX 證明了使用雙大括號其實(shí)大可不必。
所以我們使得模板更加的 …… 怎么說呢赖钞,
Svelte 采用單個(gè)大括號括起表達(dá)式腰素。
應(yīng)該說結(jié)果似乎看起來更輕松了,打字時(shí)也更愉快了:
<h1>Hello {name}!</h1>
當(dāng)然也還有一些其他的更新的雪营。
好消息是你不需要手動去一個(gè)一個(gè)地改弓千,只需要在代碼庫上運(yùn)行 svelte-upgrade 就行:
npx svelte-upgrade v2 src
這假定 src
目錄下的任何 .html
文件都是一個(gè)小組件。
源目錄和目標(biāo)目錄均可以任君自由指定献起,例如洋访,你可以使用 npx svelte-upgrade v2 routes
更新 Sapper 應(yīng)用镣陕。
要查看完整的變更列表,請移尊步到 svelte-upgrade 的 README 文檔姻政。
計(jì)算屬性
人們經(jīng)常對 Svelte 感到困惑的一件事情是計(jì)算屬性的工作方式呆抑。
回顧一下,如果你有這么一個(gè)組件……
export default {
computed: {
d: (a, b, c) => a = b + c
}
};
……Svelte 首先檢查函數(shù)的參數(shù)汁展,以便計(jì)算出 d
所依賴的參數(shù)是什么鹊碍,然后它會自動編寫好代碼,在這些值發(fā)生改變時(shí)食绿,通過將新值注入到函數(shù)中侈咕,從而更新 d
。
很酷吧器紧!
因?yàn)樗试S你從組件的輸入中獲取復(fù)雜的值耀销,而不必?fù)?dān)心何時(shí)需要重新計(jì)算它們,但這用法也怪里怪氣的铲汪。
JavaScript 語法不支持這么寫熊尉。
在 v2,我們用解構(gòu)來代替:
export default {
computed: {
d: ({ a, b, c }) => a = b + c
}
};
Svelte 編譯器仍然可以知道 d
依賴哪個(gè)值掌腰,但不再注入值狰住,而是將整個(gè)組件狀態(tài)對象丟給每個(gè)計(jì)算的屬性中。
友情提示:你同樣不需要手動進(jìn)行此更改辅斟,只需要對組件運(yùn)行 svelte-upgrade转晰,如上所示。
IE11士飒,不好意思查邢,好自為之
Svelte v1 生成的是 ES5 的代碼,這樣你就不會被迫使用轉(zhuǎn)譯器酵幕。
但現(xiàn)在都 2018 年了扰藕,幾乎所有瀏覽器都支持現(xiàn)代 JavaScript。如果能拋棄 ES5 的束縛芳撒,我們就可以生成更精簡的代碼邓深。
不過你如果還需要友好地支持 IE11,你還是可以用 Babel 或者 Bublé 之類的轉(zhuǎn)譯器的笔刹。
新的生命周期 Hook
除了 oncreate
和 ondestroy
外芥备,Svelte v2 還添加了兩個(gè)生命周期函數(shù)來響應(yīng)狀態(tài)更改:
export default {
onstate({ changed, current, previous }) {
// 在 oncreate 之前以及狀態(tài)變更時(shí)觸發(fā)
},
onupdate({ changed, current, previous }) {
// 在 oncreate 之后觸發(fā), 并且狀態(tài)變更后更新了 DOM 時(shí)觸發(fā)
}
};
你還可以通過編寫代碼的方式監(jiān)聽這些事件:
component.on('state', ({ changed, current, previous }) => {
// ...
});
component.observe
使用新的生命周期函數(shù),我們不再需要 component.observe(...)
方法:
// 之前
export default {
oncreate() {
this.observe('foo', foo => {
console.log(`foo is now ${foo}`);
});
}
};
// 之后
export default {
onstate({ changed, current }) {
if (changed.foo) {
console.log(`foo is now ${current.foo}`);
}
}
};
這可以減少 Svelte 生成的代碼量舌菜,并為你提供了更大的靈活性萌壳。
例如,現(xiàn)在可以十分容易在幾個(gè)屬性中的任何一個(gè)發(fā)生變更時(shí)響應(yīng)這些動作,比方說在不釋放觀察者的情況下進(jìn)行重繪 canvas袱瓮。
不過如果你實(shí)在喜歡使用 component.observe(...)
缤骨,你可以通過 svelte-extras 來支持這玩意。
import { observe } from 'svelte-extras';
export default {
methods: { observe }
};
component.get
這個(gè)方法不再接收可選的 key
參數(shù) —— 相反尺借,它總數(shù)返回整個(gè) state 對象:
// 之前
const foo = this.get('foo');
const bar = this.get('bar');
// 之后
const { foo, bar } = this.get();
初時(shí)绊起,這種改變可能看起來很煩人,但這是正確的方向:
除了其他特殊情況外燎斩,將來我們會更充分地探索這個(gè)方面虱歪,它可能會在類型系統(tǒng)中發(fā)揮更好的作用。
event_handler.destroy
如果你的應(yīng)用程序具有自定義的事件處理器瘫里,那么它必須返回一個(gè)帶有 destroy
方法实蔽,而不是 teardown
方法。這樣事件處理器就和組件的 API 對齊了谨读。
不再嚴(yán)格要求類型
以前,傳遞給組件的數(shù)字類型的值會被視為純數(shù)字:
<Counter start='1' />
這可能會導(dǎo)致一些意外行為√秤酰現(xiàn)在已經(jīng)被更改了劳殖。
如果你需要傳遞數(shù)字的字面量,可以直接用表達(dá)式:
<Counter start={1} />
編譯器方面的變更
在大多數(shù)情況下拨脉,你是永遠(yuǎn)不需要直接和編譯器打交道的哆姻,因此編譯器方面你其實(shí)不需要什么對策的。
不管怎么說玫膀,值得注意的是:編譯器的 API 也是有變更的矛缨。
現(xiàn)在編譯器將返回 js
,css
帖旨,ast
和 stats
箕昭,而不是有一大堆屬性的對象:
const { js, css, ast, stats } = svelte.compile(source, options);
js
和 css
都是 {code, map}
對象,其中 code
是代碼字符串解阅,map
代表 sourcemap落竹。
ast
是組件的抽象語法樹,并且 stats
對象包含有關(guān)組件的元數(shù)據(jù)以及編譯信息货抄。
以前是有一個(gè) svelte.validate
方法來檢查你的組件是否有效的述召。
不過它已經(jīng)被刪掉了,如果你只需檢查組件蟹地,而不實(shí)際對其進(jìn)行編譯的話积暖,那么僅僅傳遞一個(gè) generate: false
選項(xiàng)即可。
我的應(yīng)用還有問題要尋求幫助
希望以上的內(nèi)容已經(jīng)覆蓋了所有可能的問題怪与,并且更新對你來說夺刑,應(yīng)該比較輕松從容的。
如果你發(fā)現(xiàn)錯(cuò)誤或者本文未盡事項(xiàng),請進(jìn)入 Discord 聊天室 里頭轉(zhuǎn)轉(zhuǎn)看性誉,或者在 issue 跟蹤器 反饋給我們窿吩。
< The End >
- 窗明幾凈,靜候時(shí)日變遷 -