Проведя два года с Polymer и еще один с Angular 2, я недавно начал заново открывать для себя свою любовь к Vue.js.
Quasar - очень хороший Ionic-подобный мобильный фреймворк для Vue, и, поскольку Angular 2 заставил меня использовать TypeScript, я решил пройти процесс его интеграции в приложение Quasar. Вот 11 простых шагов, чтобы добавить поддержку TypeScript.
Шаг 1. Создайте приложение
Предполагая, что вы установили его, мы просто следуем инструкциям с помощью Quasar CLI.
Шаг 2. Установите зависимости TypeScript
Нам нужно несколько зависимостей для сборки нашего проекта TypeScript.
npm install --save-dev ts-loader typescript @types/node
Нам также понадобятся декораторы классов Vue.js для TypeScript / ES2015.
npm install --save vue-class-component
Шаг 3. Добавьте файл tsconfig.json
{ "compilerOptions": { "target": "es5", "lib": [ "dom", "es2015" ], "types": [ "node" ], "module": "commonjs", "moduleResolution": "node", "isolatedModules": false, "experimentalDecorators": true, "noImplicitThis": true, "strictNullChecks": true, "removeComments": true, "suppressImplicitAnyIndexErrors": true }, "include": [ "./src/**/*.ts" ], "compileOnSave": false }
Шаг 4. Обновите webpack.base.conf.js
var path = require('path'), webpack = require('webpack'), config = require('../config'), cssUtils = require('./css-utils'), env = require('./env-utils'), merge = require('webpack-merge'), projectRoot = path.resolve(__dirname, '../'), ProgressBarPlugin = require('progress-bar-webpack-plugin'), useCssSourceMap = (env.dev && config.dev.cssSourceMap) || (env.prod && config.build.productionSourceMap) module.exports = { entry: { app: './src/main.ts' }, output: { path: path.resolve(__dirname, '../dist'), publicPath: config[env.prod ? 'build' : 'dev'].publicPath, filename: 'js/[name].js', chunkFilename: 'js/[id].[chunkhash].js' }, resolve: { extensions: ['.ts', '.js'], modules: [ path.join(__dirname, '../src'), 'node_modules' ], alias: config.aliases }, module: { rules: [ { test: /\.ts$/, exclude: /node_modules|vue\/src/, loader: 'ts-loader', options: { appendTsSuffixTo: [/\.vue$/] } }, { test: /\.vue$/, loader: 'vue-loader', options: { esModule: true, postcss: cssUtils.postcss, loaders: merge(cssUtils.styleLoaders({ sourceMap: useCssSourceMap, extract: env.prod })) } }, { test: /\.json$/, loader: 'json-loader' }, { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'img/[name].[hash:7].[ext]' } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: 'fonts/[name].[hash:7].[ext]' } } ] }, plugins: [ /* Uncomment if you wish to load only one Moment locale: */ // new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en/), new webpack.DefinePlugin({ 'process.env': config[env.prod ? 'build' : 'dev'].env, 'DEV': env.dev, 'PROD': env.prod, '__THEME': '"' + env.platform.theme + '"' }), new webpack.LoaderOptionsPlugin({ minimize: env.prod, options: { context: path.resolve(__dirname, '../src'), eslint: { formatter: require('eslint-friendly-formatter') }, postcss: cssUtils.postcss } }), new ProgressBarPlugin({ format: config.progressFormat }) ], performance: { hints: false }, devtool: 'source-map' }
Главное, что мы здесь сделали, - это заменили загрузчик babel на загрузчик машинописного текста и добавили ts к расширениям. Все остальное может остаться прежним.
Шаг 5: Добавьте файл sfc.d.ts в папку src
declare module "*.vue" { import * as Vue from 'vue'; export default typeof Vue } declare module "quasar" declare const __THEME
Это должно показаться знакомым любому, кто видел пример TypeScript Vue, но у нас есть пара дополнений. Первое объявление состоит в том, чтобы компилятор TypeScript не прерывал работу, когда мы загружаем модули * .vue в наши модули * .ts. Второе объявление призвано восполнить отсутствие объявлений типа Quasar. Последний оператор объявления - это глобальная константа, которую Quasar использует для назначения вашей темы. Он вводится во время сборки в конфигурацию webpack.
Шаг 6. Переименуйте модули * .js в * .ts
Достаточно просто, мы просто переименовываем все файлы JavaScript в нашем каталоге src как файлы TypeScript.
Шаг 7. Исправьте импорт и модули Vue
import Vue from 'vue' import VueRouter from 'vue-router'
Становится
import * as Vue from 'vue' import * as VueRouter from 'vue-router'
Также важно отметить, что мы сделаем то же самое для всех наших операторов импорта Quasar.
Шаг 8. Обновите компоненты Vue, чтобы использовать декоратор классов
Замените скрипт в Index.vue следующим
var moveForce = 30 var rotateForce = 40 import * as Quasar from 'quasar' import * as Vue from 'vue' import Component from 'vue-class-component' @Component({ props: { propMessage: String } }) export default class Index extends Vue { quasarVersion = Quasar.version moveX = 0 moveY = 0 rotateY = 0 rotateX = 0 get position() { let transform = `rotateX(${this.rotateX}deg) rotateY(${this.rotateY}deg)` return { top: this.moveY + 'px', left: this.moveX + 'px', '-webkit-transform': transform, '-ms-transform': transform, transform } } move(event) { const {width, height} = Quasar.Utils.dom.viewport() const {top, left} = Quasar.Utils.event.position(event) const halfH = height / 2 const halfW = width / 2 this.moveX = (left - halfW) / halfW * -moveForce this.moveY = (top - halfH) / halfH * -moveForce this.rotateY = (left / width * rotateForce * 2) - rotateForce this.rotateX = -((top / height * rotateForce * 2) - rotateForce) } mounted() { this.$nextTick(() => { document.addEventListener('mousemove', this.move) document.addEventListener('touchmove', this.move) }) } beforeDestroy() { document.removeEventListener('mousemove', this.move) document.removeEventListener('touchmove', this.move) } }
Также замените скрипт в Error404.vue
var Quasar = require('quasar') import * as Vue from 'vue' import Component from 'vue-class-component' @Component({}) export default class ErrorComponent extends Vue { canGoBack = window.history.length > 1 goBack() { window.history.go(-1) } data() { return { canGoBack: window.history.length > 1 } } }
Большая разница в том, что теперь мы используем классы, обернутые декоратором компонентов. Это очень похоже на синтаксис Angular 2. Подробнее о том, почему мы это делаем, читайте здесь.
Шаг 9. Замените системный загрузчик в router.ts
Я предпочитаю напрямую импортировать свои компоненты, но вы также можете использовать здесь require.
import * as Vue from 'vue' import * as VueRouter from 'vue-router' import HomeComponent from './components/Index.vue' import ErrorComponent from './components/Error404.vue' Vue.use(VueRouter) export const AppRouter = new VueRouter({ routes: [ { path: '/', component: HomeComponent }, // Default { path: '/login', component: LoginComponent }, // Default { path: '*', component: ErrorComponent } // Not found ] }) export default AppRouter
Шаг 10: Обновите main.ts
import * as Vue from 'vue' import * as Quasar from 'quasar' import router from './router' import app from './App.vue'; Vue.use(Quasar) // Install Quasar Framework Quasar.start(() => { /* eslint-disable no-new */ new Vue({ el: '#q-app', router, render: h => h(app) }) })
Шаг 11: Уборка и постройка круто!
Вот и все. Теперь у нас должна быть возможность запустить quasar dev
, чтобы запустить наш сервер, и теперь у нас есть инструментальная поддержка TypeScript. Любые зависимости, которые нам больше не нужны, можно безопасно удалить. Удачного программирования!