оригинал:Vue's Darkest Dayавтор:Daniel Elkington
Примечание переводчика: Первоначальный текст был написан 21 июня 2019 г.
Сегодня я с удивлением обнаружил, что обычно позитивное и дружелюбное сообщество VueJS ведет ожесточенную войну. Две недели назад Юйси Ю, создатель Vue, выпустилаЗапрос комментариев (RFC), для написания компонентов Vue с использованием функционального подхода в грядущем выпуске Vue 3.0. сегодня,Критический пост на Redditа такжеНекоторые подобные критические комментарии на Hacker News, в результате чего поток разработчиков стекался к исходному RFC, чтобы выразить свое возмущение, некоторые из которых были немного оскорбительными. Это было заявлено во многих местах:
- Весь код Vue приходится переписывать совершенно по-новому, потому что существующий синтаксис удаляется и заменяется чем-то другим;
- Все время, которое люди тратят на изучение Vue, тратится впустую, потому что все меняется;
- Новый синтаксис хуже старого, потому что он не имеет обязательной структуры и приводит к спагетти-коду;
- Основная команда Vue внезапно внедрила огромное критическое изменение без каких-либо консультаций;
- Vue станет React!
- Нет, Vue станет AngularJS/Angular!
- Весь HTML должен быть написан в виде очень длинной строки!
Прочитав кучу негативных комментариев на Reddit, вы можетеRFC-страницаЯ был удивлен, обнаружив, что RFC Юси Ю получил гораздо более высокий процент положительных ответов на смайлики, чем отрицательных, и многие из первых комментариев были весьма положительными. На самом деле, первый комментарий был полон комплиментов.
Я был первым, кто написал обзор. Я оказался уведомление о новых RFC, и сразу прочитал его и нашел только то, что я хотел от Vue 3.0, и это даст мне большую помощь, поэтому я публикую первые 15 минут, оставшихся в комментариях RFC, чтобы выразить свою благодарность. Здесь я хотел бы также объяснить, почему я думаю, что новое предложение - это такая хорошая идея, но прежде всего, ответить на некоторую критику.
Я подозреваю, что многие люди немного взволнованы, прочитав сообщение на Hacker News или Reddit с большим количеством вводящих в заблуждение комментариев, они его не читают.оригинальное предложениевыразил свое возмущение. You Yuxi обновила это предложение и ответила на множество вопросов людей через вопросы и ответы. В целом:
- Если вы не хотите переписывать какой-либо код, то вам и не нужно — новый синтаксис является аддитивным, и он будет работать в Vue 3.0, пока широко используется старый синтаксис. Даже если в конечном итоге он будет удален из основного кода,Также легко использовать плагины, чтобы сделать старый синтаксис на 100% действительным..
- Время, потраченное на изучение Vue, не потрачено впустую — новый синтаксис компонентов использует те же концепции, которые вы тратили на изучение раньше, а другие концепции, такие как однофайловые компоненты, шаблоны, стили с областью действия, работают точно так же.
- Ничего не изменится без консультации —RFCтолько что вконсультироваться. Новый синтаксис еще далек от выпуска.
- Нет, HTML-код не нужно записывать в очень длинную строку.
Более субъективная точка зрения состоит в том, что новый синтаксис уступает старому синтаксису и приводит к менее структурированному коду. Мне нужен простой пример того, почему я так взволнован, когда вижу RFC, и почему я думаю, что он лучше и приведет к структурированномулучшекод.
Рассмотрим следующий интересный компонент, в котором пользователь может вводить данные о питомце. осторожность:
- Сообщение отображается, когда они закончили вводить имя своего питомца;
- Другое сообщение появится после того, как они выберут размер своего питомца.
ты сможешьздесьПопробуйте демо-версию компонента, вы также можетездесьПосмотреть код, написанный с помощью Vue 2.x (в component/Vue2.vue)
Рассмотрим JavaScript для этого компонента:
export default {
data() {
return {
petName: "",
petNameTouched: false,
petSize: "",
petSizeTouched: false
};
},
computed: {
petNameComment: function() {
if (this.petNameTouched) {
return "Hello " + this.petName;
}
return null;
},
petSizeComment: function() {
if (this.petSizeTouched) {
switch (this.petSize) {
case "Small":
return "I can barely see your pet!";
case "Medium":
return "Your pet is pretty average.";
case "Large":
return "Wow, your pet is huge!";
default:
return null;
}
}
return null;
}
},
methods: {
onPetNameBlur: function() {
this.petNameTouched = true;
},
onPetSizeChange: function() {
this.petSizeTouched = true;
}
}
};
По сути, у нас есть некоторые данные, свойства, вычисленные из этих данных, и методы для управления этими данными.
Обратите внимание, что в Vue 2.x мыНет возможности совместить связанные вещи.
мы не можем поставитьpetName
декларация данных вpetNameComment
вычисленное свойство илиonPetNameBlur
метод, потому что в Vue 2.x эти параметры организованы по типу.
Конечно, для таких небольших примеров это менее важно. Но представьте себе более крупный пример с большим количеством функций, требующихdata
,computed
,methods
, даже один или дваwatcher
.
ещеплохой способДавайте объединим связанные вещи! Кто-то может использовать что-то вроде миксинов или компонентов более высокого порядка, ноу них у всех проблемы- Трудно сказать, откуда берется тот или иной атрибут, и возникают конфликты пространств имен.
(Да, в этом случае возможна разбивка на несколько компонентов, но этоаналогичный примернет)
Вместо того, чтобы организовывать компоненты по типам опций, новое предложение позволяет нам организовывать компоненты по фактической функциональности. Это похоже на то, как вы упорядочиваете свои личные файлы на своем компьютере — обычно у вас нет папки «Листы» и папки «Документы Word», вместо этого у вас может быть папка «Работа» и папка «План отпуска». Представьте, что вы пишете компонент, используя синтаксис из предложения (постарайтесь, дайте мне знать, если обнаружите какие-либо ошибки):
import { state, computed } from "vue";
export default {
setup() {
// Pet name
const petNameState = state({ name: "", touched: false });
const petNameComment = computed(() => {
if (petNameState.touched) {
return "Hello " + petNameState.name;
}
return null;
});
const onPetNameBlur = () => {
petNameState.touched = true;
};
// Pet size
const petSizeState = state({ size: "", touched: false });
const petSizeComment = computed(() => {
if (petSizeState.touched) {
switch (this.petSize) {
case "Small":
return "I can barely see your pet!";
case "Medium":
return "Your pet is pretty average.";
case "Large":
return "Wow, your pet is huge!";
default:
return null;
}
}
return null;
});
const onPetSizeChange = () => {
petSizeState.touched = true;
};
// All properties we can bind to in our template
return {
petName: petNameState.name,
petNameComment,
onPetNameBlur,
petSize: petSizeState.size,
petSizeComment,
onPetSizeChange
};
}
};
Уведомление:
- Легко складывать связанные вещи вместе;
- Просмотрев возвращаемое значение функции настройки, мы можем легко узнать, какие переменные можно получить в шаблоне;
- Мы даже можем избежать раскрытия внутреннего состояния (touched), к которому шаблону не нужно обращаться.
Кроме того, новый синтаксис может иметь полную поддержку Typescript, чего было трудно добиться в объектно-ориентированном синтаксисе Vue 2.x. И мы можем легко извлечь повторно используемую логику в повторно используемые функции. Например:
import { state, computed } from "vue";
function usePetName() {
const petNameState = state({ name: "", touched: false });
const petNameComment = computed(() => {
if (petNameState.touched) {
return "Hello " + petNameState.name;
}
return null;
});
const onPetNameBlur = () => {
petNameState.touched = true;
};
return {
petName: petNameState.name,
petNameComment,
onPetNameBlur
};
}
function usePetSize() {
const petSizeState = state({ size: "", touched: false });
const petSizeComment = computed(() => {
if (petSizeState.touched) {
switch (this.petSize) {
case "Small":
return "I can barely see your pet!";
case "Medium":
return "Your pet is pretty average.";
case "Large":
return "Wow, your pet is huge!";
default:
return null;
}
}
return null;
});
const onPetSizeChange = () => {
petSizeState.touched = true;
};
return {
petSize: petSizeState.size,
petSizeComment,
onPetSizeChange
};
}
export default {
setup() {
const { petName, petNameComment, onPetNameBlur } = usePetName();
const { petSize, petSizeComment, onPetSizeChange } = usePetSize();
return {
petName,
petNameComment,
onPetNameBlur,
petSize,
petSizeComment,
onPetSizeChange
};
}
};
В Vue 2.x мне часто приходилось писать «компонент-монстр», который было трудно разбить на более мелкие части — его нельзя было разбить на другие компоненты, потому что многие транзакции основывались на небольшом количестве состояния. Однако, используя синтаксис в предложении, легко увидеть, что логика большого компонента может быть разбита на более мелкие повторно используемые части, перемещенные в отдельные файлы, когда это необходимо, оставив вам небольшие, простые для понимания функции и компоненты.
Это самый мрачный день для Vue? Похоже, это так. Сообщество, которое было объединено в следовании направлению этого проекта, разделилось. Но я надеюсь, что люди вернутся к этому предложению, оно ничего не ломает,Они по-прежнему могут упорядочивать варианты по типу, если захотят., но может сделать больше — более чистый код, более чистый код, более интересные библиотеки и полную поддержку Typescript.
Наконец, при работе с программным обеспечением с открытым исходным кодом лучше всего помнить, что все зависит от самоотверженности сопровождающих, что вы можете использовать его бесплатно. Некоторая неоправданная критика сегодня — это то, что им не следует воспринимать. Хорошо, что таких оскорбительных критических замечаний лишь меньшинство (хотя их довольно много), и большинство людей могут выражаться более вежливо.
Обновление от 23 июня 2019 г.:
Я написал оригинал очень быстро и не ожидал этогополучить такое внимание. Затем я понял, что этот пример кода слишком сложен для того, что я пытался донести, поэтому я сильно его упростил. Исходный пример кода находится вздесь.