В Svelte JS как работает реактивная переменная, если какая-то переменная только что напечатана, но не участвует в выдаче значения? - PullRequest
0 голосов
/ 03 февраля 2020

Код в https://svelte.dev/repl/f8db4771ba794c658d7c25a6e72d1b46?version=3.18.1

имеет две «реактивные переменные»:

$: nameUpperCase = name.toUpperCase();

$: if (name === "city") { 
    console.log("RUNNING HERE 01", age);
} else {
    console.log("RUNNING HERE 02", age);
}

, если значение name изменяется, то nameUpperCase также переодеться. Это легко.

Но для второй части, кажется, когда значение name или age изменяется, тогда оценивается строка if. Если age удален из console.log(), как в https://svelte.dev/repl/68c2cdea2bfd462caa5ac5519fb8b99d?version=3.18.1, тогда не имеет значения, если age изменится. Строка if не оценивается.

Но age никогда не участвует в генерации какого-либо окончательного значения для оператора if. Он просто распечатывается, и console.log всегда возвращает undefined. Так какое правило? Каким-то образом Svelte «волшебным образом» собирает все переменные после $:, а затем, если какая-либо из них изменяется, затем выполняет строку после $:? Таким образом, даже если переменная не участвует в формировании некоторого окончательного значения, она все еще считается?

Ответы [ 2 ]

3 голосов
/ 03 февраля 2020

То, как ваш вопрос сформулирован, я думаю, что "да" будет правильным ответом.

Это работает точно так, как вы описали: Когда любая переменная в реактивном блоке изменяется, тогда блок исполняется.

Это правило. Просто. Предсказуемость. Посмотрите, как вы интуитивно все это интуитивно понимаете?

Это больше (или даже меньше) волхвов c, чем когда значение ваших переменных автоматически отражается в вашем представлении. Svelte уже знает обо всех переменных (верхнего уровня) в вашем коде для этого.

Независимо от того, «генерирует» ли реативный блок значение или нет (реактивное объявление против оператор ) не имеет значения. Это просто «все переменные».

Если вы хотите исключить переменную из наблюдаемого, то извлеките обработку, которая ее использует, из реактивного блока:

// runs when `name` or `age` change
$: if (name === "city") { 
    console.log("RUNNING HERE 01", age);
} else {
    console.log("RUNNING HERE 02", age);
}

const logAge = msg => console.log(msg, age)

// only runs when `name` changes
$: if (name === "city") { 
    logAge("RUNNING HERE 01");
} else {
    logAge("RUNNING HERE 02");
}
2 голосов
/ 03 февраля 2020

Ты прав. Реактивность Svelte основана на присваивании.

API говорит следующее:

Любой оператор верхнего уровня (т.е. не внутри блока или функции) можно сделать реактивным, добавив перед ним префикс $: Реактивные операторы запускаются непосредственно перед обновлением компонента всякий раз, когда изменяются значения, от которых они зависят.

...