Я имел удовольствие использовать Vue с начала прошлого года, а также был поклонником Typescript. В предыдущем проекте я использовал React с Typescript, и это был беспроблемный опыт. С Vue я несколько избегал объединения их обоих, но начиная с Vue версии 2.5 были некоторые улучшения с поддержкой. См. Предстоящие изменения TypeScript в Vue 2.5 Эвана Ю.

В этом посте я предполагаю, что у вас уже есть некоторый опыт работы с Vue и Typescript, поэтому вы, скорее всего, поняли, почему вы должны/могли бы использовать фреймворк и инструменты вместе. Если вы хотите знать, почему вы должны использовать Vue или Typescript, напишите мне в комментариях для продолжения. Моя цель в этом посте — шаг за шагом показать вам, как настроить проект с нуля, используя vue-cli для конечного состояния работающего приложения Vue, интегрированного с Typescript. Кроме того, я расскажу о некоторых проблемах, с которыми вы можете столкнуться. Некоторые сообщения в блогах показывают только лучший сценарий, когда все работает правильно, в то время как мой опыт временами был противоположным. Я хотел бы добавить, что существуют различные стартовые проекты typescript и Vue. Надеюсь, это руководство поможет вам, если это изначально не было вашим направлением или если вы вообще заинтересованы в настройке.

Начало работы

Для начала вам понадобится vue-cli, вариант использования — легко создавать проекты Vue. Использование шаблонов Vue — это способ указать тип проекта vue, который вам нужен, и в этом случае мы собираемся использовать стандартный шаблон веб-пакета. Стандартный шаблон веб-пакета создаст очень простое приложение Hello World с веб-пакетом в качестве системы сборки.

Одна из замечательных особенностей открытого исходного кода заключается в том, что вы всегда можете проверить последнюю ветку предполагаемой библиотеки, которую хотите использовать. В будущем выпуске проблемы с vue-cli и этапы настройки, упомянутые в статье, могут просто исчезнуть. Команда Vue в настоящее время работает над следующей версией, и если вы хотите следить за обсуждением, проверьте это здесь vue-cli 3.

Строительные леса проекта «Первый шаг»

Предпосылки

  • Установил узел

Проект

npm install -g vue-cli

vue init <template> <project-name>

vue init webpack vue-typescript-webapp

Во время запуска предыдущей команды в вашем терминале, powershell или оболочке Windows-ubuntu вы должны увидеть что-то вроде следующего ниже, и там вы затем введете свою информацию.

Второй шаг Запуск проекта

После того, как вы закончите отвечать на серию вопросов и сгенерируете проект, следующие команды перенесут вас в ваш проект и запустят приложение. Это докажет, что проект работает как есть.

cd vue-typescript-webapp 
npm run dev

На данный момент у вас есть приложение Vue Hello World с довольно надежной настройкой сборки с использованием webpack/babel. На мой взгляд, добавление зависимостей typescript перед удалением всех зависимостей babel привело к более быстрой настройке для меня. Примечание: скорее всего, вам не нужны и babel, и typescript; машинописный текст, такой как babel, может скомпилироваться до ES5 или целевой ES6. Удаление babel полностью зависит от вас и ваших потребностей в вашем проекте.

Прежде чем перейти к следующему шагу, вы можете остановить выполнение текущего приложения в терминале Clt + C.

Третий шаг: интеграция машинописного текста

Создайте файл tsconfig.json, чтобы начать работу в корневом каталоге с этими конфигурациями. Базовые рекомендации по vue tsconfig. Конфигурации, которые мне понадобились для работы, расположены ниже.

{ 
  "compilerOptions": { 
   "lib": ["dom", "es5", "es2015"], 
   "target": "es5", 
   "module": "es2015", 
   "moduleResolution": "node",     
   "sourceMap": true, 
   "emitDecoratorMetadata": true, 
   "experimentalDecorators": true, 
   "allowSyntheticDefaultImports": true, 
   "allowJs": true 
  } 
}

Установите следующие пакеты npm

yarn add typescript ts-loader --dev 
or 
npm install typescript ts-loader -D

На данный момент у нас есть файл tsconfig, указывающий, что этот проект зависит от машинописного текста. Я рекомендую установить машинописный текст локально, чтобы вы могли убедиться, что ts-loader работает должным образом; в противном случае вам нужно будет установить typescript глобально вне вашего package.json. Пакет ts-loader используется на следующем этапе нашей настройки в нашей конфигурации веб-пакета.

Изменение веб-пакета

Используемый шаблон vue сгенерирует структуру каталогов проекта. См. изображение ниже.

Как видите, есть несколько конфигурационных файлов webpack, и babel все еще на месте. Следующее, что мы хотим сделать, это добавить правило в webpack.base.config.

{ 
   test: /\.ts$/, 
   exclude: /node_modules|vue\/src/, 
   loader: 'ts-loader', 
   options: { appendTsSuffixTo: [/\.vue$/] 
  } 
}

Точка входа в приложение теперь может быть изменена на расширение .ts. Найдите main.js в каталоге src, и после завершения изменения вы также можете изменить точку входа в webpack.base.config

entry: { app: './src/main.js' -> './src/main.ts' }

Для разрешения дополнительного расширения файла вам также потребуется обновить конфигурацию разрешения в webpack.base. С добавлением .vue.

resolve: { 
 extensions: ['.js', '.vue', '.json']
       -> ['.js', '.vue', '.json', '.ts'] 
}

Дополнения для инструментов машинописного текста

  • Создайте и добавьте sfc.d.ts or vue-shim.d.ts в каталог src/. В первую очередь это помогает инструментам сборки, в противном случае могут возникнуть проблемы с поиском правильных компонентов с расширением .vue.
declare module "*.vue" { 
  import Vue from 'vue' export default Vue 
}

Связанная ошибка без файла декларации

error in ./src/main.ts [tsl] ERROR in /Users/me/Documents/programming/vue-typescript-webapp/src/main.ts(4,17) TS2307: Cannot find module './App.vue'.

Запуск приложения

Подводя итог к этому моменту, мы создали проект hello world (свежий) с помощью babel, webpack, vue, vue-router и всего такого хорошего. В какой-то момент машинописный текст был введен в ваш проект благодаря удаче, грубой силе и т. д. Мы установили необходимые пакеты машинописного текста, изменили конфигурации и изменили точку входа в наше приложение с помощью main.ts. На этом этапе основная цель состоит в том, чтобы увидеть, будет ли проект успешно работать только с текущими изменениями.

npm run dev

Еще одно преимущество использования VS Code вместе с машинописным текстом заключается в том, что он действительно полезен для выявления простых ошибок и получения хорошего представления о API выбранного вами фреймворка или библиотеки, не выходя из редактора. Все, что вам нужно более подробно или разъяснить, вы всегда можете проверить в документации.

На изображении ниже вы можете видеть, как компилятор машинописного текста кричит о присвоении строки логическому значению. Очень простые предупреждения и уведомления обеспечивают лучший опыт разработчика.

Если приложение запускается нормально для вас, пропустите — # Возможные распространенные ошибки

Возможные распространенные ошибки

[tsl] ERROR TS18002: The 'files' list in config file 'tsconfig.json' is empty. @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.ts Module build failed: error while parsing tsconfig.json...

Fix - Your missing a tsconfig.json file at the root directory, add a tsconfig.json file there

error in ./src/main.ts [tsl] ERROR in /Users/me/Documents/programming/vue-typescript-webapp/src/main.ts(4,17) TS2307: Cannot find module './App'.

Fix - Go to the main.ts file change импортировать приложение из './App' -> импортировать приложение из './App.vue appending the extension should do the trick for that one.

Ориентация на машинописный текст в одном файловом компоненте (SFC)

Мне очень нравится использовать метод SFC для создания компонентов. Vue оказывается действительно гибким в том, как вы можете их создавать, все зависит от предпочтений. Здесь мы будем ориентироваться на typescript в наших файлах .vue, глядя на пример ниже. Я специально использую HelloWorld.vue. Добавление цели lang со значением ts к тегу script позволяет нам начать использовать машинописный текст, как если бы это был собственный файл .ts. Поэкспериментировать с возможностями машинописного текста теперь можно прямо в этом файле Typescript Docs.

<script lang="ts">
import Vue from 'vue'
interface IHelloWorldLogger {
   msg: string;
}
export default Vue.extend({
 name: 'HelloWorld',
 data () {
   return {
     msg: 'Welcome to Your Vue.js App'
   }
 },
 created () {
   this.logger({ msg: `The Best Hello World Today` })
 },
 methods: {
   logger (logger: IHelloWorldLogger) {
     console.log(logger.msg)
   }
 }
})

Через некоторое время вы, вероятно, заметите, что если вы попытаетесь пометить аннотации машинописного текста к экспортированному объекту по умолчанию, контекст this не будет работать, как вы могли ожидать. Использование синтаксиса на основе классов действительно является решением. Цитата ниже взята из статьи, упоминаемой о поддержке Typescript в версии 2.5. Использование Vue.extend обеспечивает некоторый вывод типа, но последний выглядит несколько лучше.

Однако при использовании стандартного Vue API текущей интеграции не хватает. Например, TypeScript не может легко вывести тип this внутри объектно-ориентированного API по умолчанию, который использует Vue. Чтобы наш код Vue хорошо работал с TypeScript, мы должны использовать декоратор vue-class-component, который позволяет нам создавать компоненты Vue, используя синтаксис на основе классов.

При этом вы определенно можете использовать API на основе объектов, если вы понимаете ограничения машинописного текста. Двигаясь дальше, давайте проверим синтаксис на основе классов.

Компонент класса Vue — необязательно

  • Установите пакет npm npm install vue-class-component or yarn add vue-class-component
  • Создайте новый компонент BaseWorldDecorated.ts в каталоге компонентов
  • Вы можете создавать компоненты вне файлов SFC .vue и создавать компоненты с логическими/вспомогательными функциями для расширения вашего компонента пользовательского интерфейса.
  • Создайте EssentialLinks.vue

Исходный код того, что необходимо в каждом из новых файлов, приведен ниже. Файл HelloWord.vue будет изменен, чтобы использовать синтаксис на основе классов и расширение от BaseWorldDecorated.ts. Он также будет использовать только что созданный файл EssentialLinks.vue. Если вам нужно точно увидеть, как выглядит HelloWorld с этими изменениями, посмотрите код здесь HelloWorld.vue.

import Vue from 'vue'
import Component from 'vue-class-component'
interface IHelloWorldLogger {
  log: string;
}
@Component({})
export default class BaseWorldDecorated extends Vue {
  msg: string = 'The Best Hello World Today'
  // computed
  get computedMsg() {
    return 'computed ' + this.msg
  }
  // method
  logger({ log }: IHelloWorldLogger) {
    console.log(log)
  }
}

Декораторы свойств Vue также могут быть полезны, если вы решите использовать компоненты класса. Выводы типов, похоже, лучше работают с объявлениями свойств, использующими этот метод.

<template>
 <div class="essential-links">
   <h2>Essential Links</h2>
   <ul>
     <li v-for="item in links" :key="item.id">
       <a :href="item.link" target="_blank">{{item.text}}</a>
     </li>
   </ul>
 </div>
</template>
<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
@Component({})
export default class EssentialLinks extends Vue {
 @Prop({ default: [] })
 links: Array<string>
 // lifecycle method
 mounted() {
   console.log(this.links)
 }
}
</script>

С последними изменениями мы показали машинописные работы по всему проекту в отдельных файлах как lang target и vue class components. Если у вас возникнут какие-либо проблемы, вы всегда можете обратиться к конечному решению. Проблема, с которой я столкнулся, заключалась в том, что хотя можно расширить базовый компонент Vue, такой как BaseWorldDecorated.ts, до HellowWorld.vue, метод регистратора, унаследованный от BaseWorldDecorated, работает в шаблоне HelloWorld, но дает сбой, если используется в реальном компоненте класса vue.

@Component({
 components: {
   EssentialLinks
 }
})
export default class HelloWorld extends BaseWorldDecorated {
 mounted () {
   // Error incountred: Property 'logger' does not exist on type 'HelloWorld'.
   this.logger({ log: 'I just want to log' })
 }

Необязательный шаг — удаление ненужных ресурсов

Сначала остановите приложение, а затем решите, хотите ли вы удалить зависимости шаг за шагом или все сразу.

Шаг за шагом

  • Удалите обе зависимости babel и eslint одну за другой через yarn remove or npm uninstall
  • после завершения запустите приложение

Все вместе

  • Удалите все зависимости babel и eslint в package.json.
  • удалить файл блокировки
  • пряжа или установка npm`
  • запустить приложение

Приложение должно запуститься и нормально работать с вашей пользовательской настройкой машинописного текста.

В заключение

Вот несколько рекомендаций по использованию инструментов в рабочем процессе разработки Vue, если у вас их еще нет ;)

  • Код ВС
  • Ветур
  • Красивее / Код VS
  • Цлинт

Исходный код для этого проекта находится Vue-Typescript-WebApp. Я надеюсь, что предоставленная информация поможет вам начать работу, а также поможет тем, кто уже начал проекты Vue и хочет интегрировать typescript. Спасибо, что нашли время прочитать!

Первоначально опубликовано на tirellmckinnon.com.