Запретить null но разрешить undefined во входных параметрах Vue 3
Странно как-то обстоят дела с понятием "опциональности" входных параметров (props) во Vue 3 (может и в 2, но это не актуально). Если если входной параметр помечен как required: false, то и undefined и null будут расценеы так пустое значение и никаких предупреждений в консоль не будет выдано:
export default {
props: {
label: {
type: String,
required: false
}
}
};
В этом случае валидатор validator (если он есть) выполнен не будет:
export default {
props: {
label: {
// Не будет вызван, когда значение `null`
validator: value => typeof value == "string" && value.length > 0,
required: false
}
}
};
При этом, если указано значение по умолчанию default, то оно будет подставлено только когда значение входного параметра undefined, не не когда null.
export default {
props: {
label: {
validator: value => typeof value == "string" && value.length > 0,
default: "DEFAULT" // Не будет поставлен, когда значение - `null`
}
}
};
Как же при таком раскладе исключить null? Нужно каждый опциональный параметр теперь как на null, так и на undefined проверять, или каждый из них обкладывать computed-ами? Слишком много рутин для середины 2020-х. Нужно что-то, что берёт эти рутины на себя.
Ответы (1 шт):
Я тоже один раз столкнулся с такой проблемой, мне нужно было четко различать null и undefined в props, потому что null означал
"пользователь намеренно сбросил значение"
а undefined
"значение не передано, используй дефолт"
Но Vue ведёт себя одинаково и с null, и с undefined — ни валидация не вызывается, ни default не подставляется, если required: false.
Я прям напрягся, потому что я ожидал, что validator будет вызван в любом случае, а default — если значение отсутствует или null. Но Vue так не работает.
После некоторых экспериментов я пришёл к такому решению:
props: {
label: {
type: String,
required: false,
validator(value) {
// validator не вызывается, если передан null, но если вдруг вызовется — отсеиваем
if (value === null) return false;
return typeof value === 'string' && value.length > 0;
},
default: () => 'Default Label'
}
},
computed: {
safeLabel() {
// если передали null — используем default
return this.label === null ? this.$options.props.label.default() : this.label;
}
}
Возможно это не идеально, но в свое время мне помогло.