Опубликовать компонент TypeScript под vue-cli 3.0

TypeScript Vue.js
Опубликовать компонент TypeScript под vue-cli 3.0

vue-cli вот-вот выйдет, а TypeScript становится все более и более популярным, поэтому я воспользовался этой возможностью, чтобы добавить плагин, который написал ранее.vue-loading-templateРефакторинг в TypeScript и добавление некоторых полезных функций.

конфигурация сборки

vue-cli 3.0 предоставляет ряд функций, в том числе готовую поддержку Babel, TypeScript, ESlint, PWA и т. д. В то же время он также предоставляет графический интерфейс в CLI, вам нужно только ввестиvue uiВы можете увидеть интерфейс конфигурации. Здесь не так много объяснений. Заинтересованные студенты могут обратиться к документации: https://cli.vuejs.org/dev-guide/ui-api.html.

построить цель

при использовании командыvue-cli-service build, vue-cli предоставляет различные параметры цели сборки (по умолчанию — приложение). Если цель состоит в том, чтобы собрать и опубликовать пакет npm, мы можем выбрать lib в качестве цели сборки.В этом режиме vue не будет упакован, даже если vue упоминается в вашем проекте:

vue-cli-service build --target lib --name vueLoading [entry]

--nameимя файла,[entry]Построить вход.

В дополнение к созданию библиотеки нам также необходимо создать проект, целью которого является приложение для развертывания на страницах GitHub, поэтому package.json в проекте содержит как минимум две следующие команды:

// package.json
{
  // others..
  "scripts": {
    "build": "vue-cli-service build --dest docs",
    "build-bundle": "vue-cli-service build --target lib --name vueLoading ./src/index.ts",
  }
}

Кроме того, вам необходимо настроить baseUrl в vue.config.js, поскольку URL-адрес на страницах GitHub — https://jkchao.github.io/vue-loading/,

module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
		    ? '/vue-loading/'
		    : '/'
}

Настроить загрузчики

В этом проекте мы импортировали файл svg. По умолчанию конфигурация vue-cli преобразует его в файл base64. В настоящее время необходимо заменить конфигурацию загрузчика vue-cli:

module.exports = {
  // ... other
  chainWebpack: config => {
    const svgRule = config.module.rule('svg')

    svgRule.uses.clear()

    svgRule
      .use('raw-loader')
        .loader('raw-loader')
  }
}

Изменить файл

index.ts

Опубликованные компоненты доступны сообществу двумя способами:

  • Представляйте файлы в одном файле, напримерimport { vueLoading } from 'vue-loading-template', после однофайлового компонентаcomponentsЕго можно использовать, как указано в опциях.

  • Может использоваться как плагин и обеспечивает дополнительную настройку глобальных свойств:

    import Vue from 'vue'
    import vueLoading from 'vue-loading-template'
    Vue.use(vueLoading, {
        type: 'balls',
        color: '#5ac1dd',
        size: {
          width: '30px',
          height: '30px'
        }
    })
    

    После установки компонент vueLoading регистрируется глобально.

Первый пункт реализовать проще, импортируйте написанный компонент и экспортируйте его как член:

import VueLoading from './components/Loading.vue'

export { VueLoading }

Во втором пункте, при использовании в качестве плагина, экспортированные элементы должны предоставить метод установки.Первый параметр установки — это конструктор Vue, а второй параметр — свойства компонента:

import Vue from 'vue'

import VueLoading from './components/Loading.vue'

// VueLoadingOptions 是定义的声明,下文将会出现。
import { VueLoadingOptions } from '../typings/index'

const install = (
  vue: typeof Vue,
  options?: VueLoadingOptions
) => {
  vue.component('vue-loading', VueLoading)
}

export default { install }

Пакет, созданный таким образом, позволяет нам использовать его в качестве плагина.Vue.use(vueLoading), но не принимает один из допустимых необязательных аргументов.

Прежде чем переписать его на TypeScript, мы могли бы присвоить значения параметров свойствам компонента:

const install = (
  vue,
  options
) => {
  if (options) {
    VueLoading.props.type.default = options.type
    VueLoading.props.color.default = options.color
    VueLoading.props.size.default = () => options.size
  }
  vue.component('vue-loading', VueLoading)
}

После перезаписи его в компонент TypeScript (на самом деле подкласс Vue, определенный Vue.extend), реквизиты компонента не могут быть получены напрямую Мы можем ясно понять, напечатав два разных компонента:

Рисунок 1 представляет собой форму экспорта общих компонентов,

Рисунок 2, чтобы использоватьVue.extend()Компонент подкласса, который экспортируется как форма.

При использовании подклассов компонентов вам необходимо создать экземпляр:new VueLoading().

что нам нужноpropsсвойства, которые помещаются в свойства экземпляра$optionsначальство:

Но есть еще некоторые проблемы, когда вы используетеnew VueLoading().$options.props.type, он выдаст предупреждение:

  • Свойство props может не существовать;
  • type не может быть в свойстве props.

Нам нужно утверждать на реквизитах:

import Vue from 'vue'

import VueLoading from '@/components/Loading.vue'
import { VueLoadingOptions } from '../typings/index'

interface Props {
  type: { default: string },
  color: { default: string },
  size: { default: () => any },
  [key: string]: any
}

const install = (
  vue: typeof Vue,
  options?: VueLoadingOptions
) => {
  if (options) {
    const componentProps = new VueLoading().$options.props as Props

    componentProps.type.default = options.type || 'spiningDubbles'
    componentProps.color.default = options.color || '#457e86'
    componentProps.size.default = () => options.size || { width: '40px', height: '40px' }
  }

  vue.component('vue-loading', VueLoading)
}

export { VueLoading }
export default { install }

Файл декларации

В файлах TypeScript файлы объявлений играют очень важную роль при импорте модуля с неотносительным путем.

Если вы хотите узнать больше об импорте в модули TypeScript, вы можете обратиться кэта статья.

Файл объявления модуля, который предоставляет поведенческие подсказки и возможности ограничений для соответствующего модуля. Поэтому нам нужно просто написать файл объявления согласно экспорту модуля:

import Vue from 'vue'

type LoadingType = 'balls' | 'bars' | 'beat' | 'bubbles' | 'cylon' | 'spin' | 'spiningDubbles' | 'barsCylon'

interface VueLoadingOptions {
  // loading type
  type: LoadingType

  // loading color
  color: string

  // loading size
  size: { width: string, height: string }
}

declare function install(vue: typeof Vue, options?: VueLoadingOptions): void

declare class VueLoading extends Vue {}

declare const _default: {
  install: typeof install
}

export { VueLoading, LoadingType, VueLoadingOptions }

export default _default

На данный момент завершен простой пакет компонентов TypeScript.

Немного надуманно?

  • Да, особенно при изменении реквизитов компонента по умолчанию (используяVue.extend()Экспортируемый компонент является конструктором).
  • Кроме того, при использовании в качестве плагина отсутствует информация об ограничениях (подсказках) для входящих параметров (немного отличается от того, что вы себе представляли).

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