Спасибо за пример. Хорошая заготовка.
Приложение даже запустилось без проблем.
Только версии NPM-пакетов очень старые.
Подтягивание dot.net core до версии 2.1 прошло нормально.
Но перейти на свежий webpack не получилось — не хватает образования.
Попытка подтянуть версию Vue.js тоже сходу не проходит (ошибки компиляции TypeScript).
Официальный стайл-гайд требует, чтобы для фреймворка явно описывались типы свойств компонента. У вас — массив. Исправляем, делаем явно — и получаем дубликат описаний, то есть еще хуже.
Массив использовать опасно ещё по одной причине — у компилятора TypeScript частично отключается контроль типов.
Теоретически оба варианта определения props, которые приведены ниже, должны работать одинаково. И это действительно так. Даже получаемый на выходе JavaScript код одинаковый.
Но обнаруживается неприятный баг-фича в тайпинге Vue.js.
Если props определены как массив, то для компилятора TypeScript перечисленные свойства становятся легальными.
Например, компилятор спокойно скушает использование this.filterKey.
Перечисленные в props свойства даже в IntelliSense появляются при использовании VS2017.
А если определить props явно с указанием типов, то компилятор будет материться на тот же this.filterKey.
К этому ещё можно добавить Razor-рендеринг в приложениях Asp.Net Core MVC.
Razor-синтаксис позволяет жестко связать модель и представление.
Но здесь одно лечат, другое — калечат.
Полностью с вами согласен. Имя автора ничего не гарантирует. Но зато, при сильных наездах, легче отмазаться :).
Насчет "явно не TypeScript":
Образец на vuejs.org, куда вы ссылаетесь — лохматого года, и явно не Typescript. Вы его портируете, и остальные лохматости оставляете как есть.
И я про тоже самое говорю:
На широких просторах Интернета можно найти массу качественных примеров и готовых приложений, использующих Vue.js. Но подавляющее большинство этих примеров написано на JavaScript.
Зачастую, при попытке причесать "лохматости" что-нибудь отваливалось. Поэтому я и стараюсь оставлять "как есть".
Кстати, первый пример, который я использую в этой статье, тоже практически официальный.
Переход с официального сайта typescriptlang.org, выбрать Vue.js.
Автор примера: DanielRosenwasser — Program Manager of TypeScript.
При написании tutotial я не ставил себе задачу написать идеальный пример.
Я выбрал официальный пример известного автора: Evan You.
Затем постарался минимизировать изменения в исходном коде.
Чтобы не потерять узнаваемость.
Так что: "так вообще писать нельзя" — это к автору :).
Что касается кривости кода — посмотрите на цитаты от создателя Vue.js в начале статьи. В них содержится ответ.
Vue.js изначально был плохо заточен под TypeScript.
Например, дублирование определений props неизбежно даже при использовании vue-class-component.
Поэтому и приходится использовать "костыли".
Есть варианты "костылей", которые выглядят получше, чем использованный мной.
Описанный мной вариант с интерфейсами, мне лично, экономит массу времени и нервов при изучении потрохов самого Vue.js, а также "чужих" компонент, которые я подбираю для использования в своих приложениях.
Обычно сам пример мне не нужен, поэтому тратиться на него нет смысла.
Главное — быстро заставить работать подходящий пример использования "нужной" компоненты.
А потом ставишь точки остановки и шаришься по коду "нужной" компоненты и Vue.js.
В подобных применениях будет удобнее, как мне кажется, подход с явным определением интерфейсов для входных и выходных данных Vue-компоненты.
Не требуется "включать мозги" и разбираться во внутренней логике работы "чужого" примера.
Надежная связь между ts-кодом компоненты и его представленим (шаблоном) — это частный случай общей проблемы поддержания взаимосвязей между моделью и представлением.
Например, те же проблемы есть в приложениях WPF или XamarinForms. XAML-файлы представления тоже можно ненароком сломать. И здесь тоже определенные ошибки проявятся только в рантайм.
На 100% эту проблему никто ещё не решил нормально. Поэтому рефакторинг объектов, которые участвуют в биндинге — везде вызывает затруднения.
На уровне привязки ts-кода Vue-компоненты к его шаблону особых проблем нет.
Обычно это решается соглашением по именам (для AppGrid templateId=«app-grid-template», для DemoGrid templateId=«demo-grid-template»).
На уровне привязки (биндинга) атрибутов компоненты к определенным элементам представления, естественно можно нарваться на ошибки в рантайм.
Тут только грамотное тестирование сможет помочь. По-моему, Vue.js ругается вполне осмысленно в случае отсутствия нужных тэгов или сломанного биндинга.
Но ведь строгая типизация, в любом случае, помогает улучшать код. Поэтому её надо применять в той части, в которой она работает.
Всё зависит от области применения. Ваши варианты в определенных условиях будут предпочтительнее.
Вариант с интерфейсами удобен, когда не сам проектируешь компоненты, а сдираешь чужой js-код.
Кроме того, бывает полезно видеть результат компиляции из TypeScript в JavaScript без посредников. Декоратор несколько искажает картину.
На всякий случай уточняю, что «esModuleInterop» появился в версии TypeScript 2.7. На ноуте не обновился и некоторое время не мог понять, почему работавшее приложение вдруг перестало собираться.
Спасибо автору за сий труд. Для меня лично, многое стало понятнее, после ответа на этот вопрос:
В: Тони Хор (Tony Hoare) назвал null ошибкой на миллиард долларов. Какое было самое неудачное техническое решение в твоей карьере?
O: Было бы неплохо использовать TypeScript изначально, еще когда я начал переписывать код для Vue 2.x.
Может Vue.js 3.0 уже будет на TypeScript при примеру Angular?
Если поддерживаете свой репозиторий на github в актуальном состоянии, то надо немного подправить hello.ts.
Компилятор TypeScript, вероятно, стал более привередливым и ругается на неинициализированную переменную message. Всё работает после модификации private message!: string;.
Сработало! Спасибо!
Проект с amd-модулями работает без заплатки и через SystemJS, и через RequireJS. В файлах TypeScript ничего менять не надо, достаточно поменять tsconfig.json:
Попробовал import * as Vue from «vue»;
Компилятор TS выдает ошибки.
Может подскажете, что ещё подкрутить?
TryVue D:\Git\starter-vue\TryVue\ClientApp\index.ts 5
Ошибка TS2351 Build: Невозможно использовать new с выражением, у типа которого нет сигнатуры вызова или конструктора.
TryVue D:\Git\starter-vue\TryVue\ClientApp\components\Hello.ts 4
Ошибка TS2339 Build: Свойство «extend» не существует в типе «typeof „D:/Git/starter-vue/TryVue/node_modules/vue/types/index“».
Толстый node_modules для деплоя не нужен, в приведенном примере используется только для сборки. Всё необходимое в рантайм тащится по ссылкам CDN: vue.js, jquery.js, system.js. Деплой можно делать визардом vs2017.
Приложение даже запустилось без проблем.
Только версии NPM-пакетов очень старые.
Подтягивание dot.net core до версии 2.1 прошло нормально.
Но перейти на свежий webpack не получилось — не хватает образования.
Попытка подтянуть версию Vue.js тоже сходу не проходит (ошибки компиляции TypeScript).
Массив использовать опасно ещё по одной причине — у компилятора TypeScript частично отключается контроль типов.
Теоретически оба варианта определения
props
, которые приведены ниже, должны работать одинаково. И это действительно так. Даже получаемый на выходе JavaScript код одинаковый.Но обнаруживается неприятный баг-фича в тайпинге Vue.js.
Если
props
определены как массив, то для компилятора TypeScript перечисленные свойства становятся легальными.Например, компилятор спокойно скушает использование
this.filterKey
.Перечисленные в
props
свойства даже в IntelliSense появляются при использовании VS2017.А если определить
props
явно с указанием типов, то компилятор будет материться на тот жеthis.filterKey
.Вот такой баг-фича.
В продакшн используем декоратор vue-class-component.
К этому ещё можно добавить Razor-рендеринг в приложениях Asp.Net Core MVC.
Razor-синтаксис позволяет жестко связать модель и представление.
Но здесь одно лечат, другое — калечат.
Полностью с вами согласен. Имя автора ничего не гарантирует. Но зато, при сильных наездах, легче отмазаться :).
Насчет "явно не TypeScript":
И я про тоже самое говорю:
Зачастую, при попытке причесать "лохматости" что-нибудь отваливалось. Поэтому я и стараюсь оставлять "как есть".
Кстати, первый пример, который я использую в этой статье, тоже практически официальный.
Переход с официального сайта typescriptlang.org, выбрать Vue.js.
Автор примера: DanielRosenwasser — Program Manager of TypeScript.
Развве может он писать на TypeScript криво?
При написании tutotial я не ставил себе задачу написать идеальный пример.
Я выбрал официальный пример известного автора: Evan You.
Затем постарался минимизировать изменения в исходном коде.
Чтобы не потерять узнаваемость.
Так что: "так вообще писать нельзя" — это к автору :).
Что касается кривости кода — посмотрите на цитаты от создателя Vue.js в начале статьи. В них содержится ответ.
Vue.js изначально был плохо заточен под TypeScript.
Например, дублирование определений props неизбежно даже при использовании vue-class-component.
Поэтому и приходится использовать "костыли".
Есть варианты "костылей", которые выглядят получше, чем использованный мной.
Описанный мной вариант с интерфейсами, мне лично, экономит массу времени и нервов при изучении потрохов самого Vue.js, а также "чужих" компонент, которые я подбираю для использования в своих приложениях.
Обычно сам пример мне не нужен, поэтому тратиться на него нет смысла.
Главное — быстро заставить работать подходящий пример использования "нужной" компоненты.
А потом ставишь точки остановки и шаришься по коду "нужной" компоненты и Vue.js.
В подобных применениях будет удобнее, как мне кажется, подход с явным определением интерфейсов для входных и выходных данных Vue-компоненты.
Не требуется "включать мозги" и разбираться во внутренней логике работы "чужого" примера.
Всё зависит от поставленных целей.
Например, те же проблемы есть в приложениях WPF или XamarinForms. XAML-файлы представления тоже можно ненароком сломать. И здесь тоже определенные ошибки проявятся только в рантайм.
На 100% эту проблему никто ещё не решил нормально. Поэтому рефакторинг объектов, которые участвуют в биндинге — везде вызывает затруднения.
На уровне привязки ts-кода Vue-компоненты к его шаблону особых проблем нет.
Обычно это решается соглашением по именам (для AppGrid templateId=«app-grid-template», для DemoGrid templateId=«demo-grid-template»).
На уровне привязки (биндинга) атрибутов компоненты к определенным элементам представления, естественно можно нарваться на ошибки в рантайм.
Тут только грамотное тестирование сможет помочь. По-моему, Vue.js ругается вполне осмысленно в случае отсутствия нужных тэгов или сломанного биндинга.
Но ведь строгая типизация, в любом случае, помогает улучшать код. Поэтому её надо применять в той части, в которой она работает.
Вариант с интерфейсами удобен, когда не сам проектируешь компоненты, а сдираешь чужой js-код.
Кроме того, бывает полезно видеть результат компиляции из TypeScript в JavaScript без посредников. Декоратор несколько искажает картину.
Спасибо автору за сий труд. Для меня лично, многое стало понятнее, после ответа на этот вопрос:
Может Vue.js 3.0 уже будет на TypeScript при примеру Angular?
Спасибо за полезный пример.
Если поддерживаете свой репозиторий на github в актуальном состоянии, то надо немного подправить hello.ts.
Компилятор TypeScript, вероятно, стал более привередливым и ругается на неинициализированную переменную
message
. Всё работает после модификацииprivate message!: string;
.В статью внесено дополнение под заголовком UPD 01.03.2018 с учетом предложенного решения @mayorovp.
Также все необходимые изменения внесены в решение VS2017 на github.
Сработало! Спасибо!
Проект с amd-модулями работает без заплатки и через SystemJS, и через RequireJS. В файлах TypeScript ничего менять не надо, достаточно поменять tsconfig.json:
Заплатку можно убирать. Получается зря гланды вырывал не через то место.
Может есть ссылка на работающий пример с TypeScript для случая: import * as Vue from «vue»?
vue.esm.js:10809 Uncaught SyntaxError: Unexpected token export
Хотя «в лоб» не проходит, при выполнении ошибка:
Uncaught (in promise) Error: Unable to dynamically transpile ES module
A loader plugin needs to be configured via `SystemJS.config({ transpiler: 'transpiler-module' })`.
Instantiating cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.esm.js
Компилятор TS выдает ошибки.
Может подскажете, что ещё подкрутить?
TryVue D:\Git\starter-vue\TryVue\ClientApp\index.ts 5
Ошибка TS2351 Build: Невозможно использовать new с выражением, у типа которого нет сигнатуры вызова или конструктора.
TryVue D:\Git\starter-vue\TryVue\ClientApp\components\Hello.ts 4
Ошибка TS2339 Build: Свойство «extend» не существует в типе «typeof „D:/Git/starter-vue/TryVue/node_modules/vue/types/index“».