7. 聲明(計算屬性)
在官方文檔中把定義一個根據依賴值的變化而變化的動態參數**
- 一個簡單的兩倍值的例子
<script>
let count = 0;
$: doubleCount = count * 2
function addCount() {
count++
}
</script>
<div>{count} * 2 = {doubleCount}</div>
<button on:click={addCount}>+1</button>
- 實驗效果
這裏的$ 在我的理解中完全可以作爲count改變時的一個回調函數,可以類比於react中的useEffect + useMemo,爲了驗證猜想,我們來測試一下
- 一個回調函數的例子
<script>
let count = 0;
$: doubleCount = count * 2
function addCount() {
count++
}
let callbackForCount;
// 爲count添加回調
$: {
console.log(`${count} is changed`)
}
// 爲count添加callback
$: {
callbackForCount = () => {
return `現在的count是${count}`
}
}
</script>
<div>{count} * 2 = {doubleCount}</div>
<button on:click={addCount}>+1</button>
<div>{ callbackForCount() }</div>
- 實驗效果
- 文檔是這麼說的
We’re not limited to declaring reactive values — we can also run arbitrary statements reactively.
聲明任何響應值的行爲都是被允許的,我們可以運行任意響應的狀態表達式
比如我們可以聲明一個if
$: if (count >= 10) {
alert(`count is dangerously high!`);
count = 9;
}
這些都是被允許的
8. 複雜類型的更新問題
Because Svelte’s reactivity is triggered by assignments, using array methods like
push
andsplice
won’t automatically cause updates. For example, clicking the button doesn’t do anything.Svelte 是通過賦值來發起數據響應的,因此對於array中的push和splice等方法來改變數組並不會被監聽到,因此不會引起頁面的重新渲染。
因此,如果當我們通過對引用類型採取非 = 號的方式進行改值,其並不會使頁面重新渲染,例如下面一個例子
<script>
let friends = ["tom", "jack"];
let score = {
math: 100,
chinese: 80
};
let people = {
name: "jemmery",
friends,
score
};
let newFriend = "";
$: numOfFriends = people.friends.length;
function addFriends() {
// 解決方法
// people.friends = [...people.friends, newFriend]
// 通過下面的兩種方法並不會生效
people.friends.push(newFriend);
// friends.push(newFriend)
console.log(people.friends)
newFriend = "";
}
function handleInput(e) {
newFriend = e.target.value;
}
const changeScore = () => {
// 這種方法並不會導致輸出的score變化,但是people.score確實發生了變化
score.math = 30
console.log(people.score)
// 通過下面的方法可以使頁面進行強制渲染
// 解決方法
// people.score = people.score
}
</script>
<style>
</style>
<div>
{people.name} has {numOfFriends} friend{numOfFriends > 1 ? 's' : ''}: {people.friends.join(',')}
<div>數學:{people.score.math}</div>
<div>語文:{people.score.chinese}</div>
<br />
<input type="text" value={newFriend} on:input={handleInput} />
<button on:click={addFriends}>增加朋友</button>
<button on:click={changeScore}>改變分數</button>
</div>
- 效果
我們通過這種方式進行修改參數發現並不會發生變化,其原因是隻有等號賦值 纔會導致頁面的刷新
現在我們通過代碼中標記爲解決方法的代碼來解決這個問題
- 問題解決
- 總結
- 在svelte中,利用非=號的方式對引用類型進行修改會導致頁面更新監聽的失效,例如數組的splice和push方法
- 解決辦法通過強行等號賦值,實現頁面的強制刷新
- 第二種方法是通過…表達式對值進行賦值,也能解決這個問題