Обзор: Недавно я изучал vue и typeScript и обнаружил, что есть некоторые методы и методы написания, которые необходимо разобрать и обобщить. В основном ссылаются на справочные статьиvue-property-decorator,vue-class-component, поэтому выберите несколько ключевых моментов для осаждения и размышлений.
опубликовать: 2019-09-15
Доступен сReact и Redux в TypeScript — руководство по статической типизациисравнивать
содержание
- Введение, конфигурация среды (vue-cli)
- Vue — шаблон компонента (использование vue-property-decorator)
- Vuex — управление состоянием (использование vuex-module-decorators, vuex-class)
Введение, конфигурация среды
vue-cli содержит параметры машинописного текста, просто выберите
vue create repo
# 手动配置的时候需要选择 TypeScript
Check the features needed for your project:
◉ Babel
◉ TypeScript
◯ Progressive Web App (PWA) Support
◯ Router
◉ Vuex
❯◉ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
Ознакомление с декораторами vuex-module-decorators и vuex-class см.
официальная документация vuex-module-decorators
Vue — шаблон компонента
Использование Typescript для разработки Vue, в основном с использованием vue-property-decorator, чтобы предоставить классу компонентов различные возможности, в частности
-
@ComponentВ основном используется для реализации компонентов Vue в виде стиля класса.import { Component, Vue } from 'vue-property-decorator'; @Component export default class HelloWorld extends Vue { public render() { return (<h5>Hello world</h5>); } }с предыдущим
.vueОтличие в том, что с помощьюrenderдля визуализации компонента. В настоящее времяclass Hello worldСостояние и логика компонентов, реализованных в-
dataСостояние компонента, критическое в vuedataкак толькоclassсвойства для достиженияimport { Component, Vue } from 'vue-property-decorator'; @Component export default class HelloWorld extends Vue { private message: string = 'world'; public render() { const { message }: HelloWorld = this; return (<h5>Hello {message}</h5>); } }использовать
privat messageкак состояние компонента; -
computedЧасто используются вычисляемые свойства компонентов в компонентах vue в виде class-style.get()оператор для реализации@Component export default class HelloWorld extends Vue { private message: string = 'world'; get subMessage(): string { return `boy ${this.message}`; } public render() { const { message, subMessage }: HelloWorld = this; return ( <div> <h5>Hello {message}</h5> <span>{subMessage}</span> </div> ); } } -
methodsа такжеdataТочно так же он также реализован как атрибут класса, который часто используется для реализации событий операций на странице, таких как клики, выбор и т. д.@Component export default class HelloWorld extends Vue { private message: string = 'world'; get subMessage(): string { return `boy ${this.message}`; } public setMessage(msg: string): void { this.message = msg; } public render() { const { message, subMessage, setMessage }: HelloWorld = this; return ( <div> <h5>Hello {message}</h5> <span>{subMessage}</span> <button onClick={() => setMessage('person')}> Click </button> </div> ); } }
-
-
@PropЯвляясь ключевой частью реализации однонаправленного потока данных, он также является ключом к передаче данных между компонентами.import { Component, Prop, Vue } from 'vue-property-decorator'; @Component export default class HelloWorld extends Vue { @Prop({ default: 'Click' }) public readonly porpA!: string; public render() { const { porpA }: HelloWorld = this; return ( <div> <h5>{porpA}</h5> </div> ); } }допустимый
@PropКонфигурация, связанная с параметрамиoptions, и vue-property-decorator также предоставляет@PropSync, Так и будетpropsа такжеcomputedСоставное использование, конкретное использование// 父组件 parent <Child name="hello world" @update:name="handleUpdate" /> // 子组件 child @Component export default class Child extends Vue { @PropSync('name', { type: String }) syncedName!: string public setSyncedName() { this.syncedName = 'delete'; } }Эквивалентно предыдущему однофайловому компонентному режиму
export default { props: { name: { type: String } }, computed: { syncedName: { get() { return this.name }, set(value) { this.$emit('update:name', value) } } } } -
@EmitЭквивалентноthis.$emit, часто используется для запуска пользовательских событий// tsx @Emit() addToCount(n: number) { this.count += n } // vue methods: { addToCount(n) { this.count += n this.$emit('add-to-count', n) } } -
@WatchОтносится к свойству прослушивания, то есть при прослушиванииdataилиpropsКогда есть изменение, соответствующее изменение будет запущеноimport { Component, Watch, Vue } from 'vue-property-decorator'; @Component export default class HelloWorld extends Vue { private message: string = 'world'; @Watch('message', { immediate: true, deep: true }) public onMsgChange(val: string, oldVal: string) { console.log('onMsgChange', val, oldVal); } public render() { const { message }: HelloWorld = this; return ( <div> <h5>Hello {message}</h5> <input type='text' v-model={this.message}/> </div> ); } }@WatchПервый параметр представляет слушателяpath, второй параметр представляет{ immediate: true, deep: true } //是否立即触发、深度侦听 -
@Provideа также@injectЭти два обычно используются при разработке компонентов.Проще говоря, переменные предоставляются в родительских компонентах через провайдер, а затем переменные вводятся в дочерние компоненты через инъекцию в стиле класса.import { Component, Inject, Provide, Vue } from 'vue-property-decorator' const symbol = Symbol('baz') @Component export class MyComponent extends Vue { @Inject() readonly foo!: string @Provide() foo = 'foo' }
Обратите внимание, что это общий
dataне отвечает
-
@ProvideReactiveтак же как@InjectReactiveТо же использование, что и выше, но общее значение, если оно изменено в родительском компоненте, будет зафиксировано в дочернем компоненте. -
@refЧасто используется для прямого доступа к компонентамimport { Vue, Component, Ref } from 'vue-property-decorator' import AnotherComponent from '@/path/to/another-component.vue' @Component export default class YourComponent extends Vue { @Ref() readonly anotherComponent!: AnotherComponent @Ref('aButton') readonly button!: HTMLButtonElement } # 等同于 export default { computed() { anotherComponent: { cache: false, get() { return this.$refs.anotherComponent as AnotherComponent } }, button: { cache: false, get() { return this.$refs.aButton as HTMLButtonElement } } } } -
@ModelЧасто используется для реализацииv-modelТакая директива в предыдущем компоненте vueexport default { model: { prop: 'checked', event: 'change' }, props: { checked: { type: Boolean } } }В стиле класса просто используйте
@Modelреализоватьimport { Vue, Component, Model } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @Model('change', { type: Boolean }) readonly checked!: boolean }
Vuex — управление состоянием
При использовании Vuex раньше это в основном зависело отstate,getters,mutationsтак же какactions, и они могут быть модульными
-
stateусловиеimport { Module, VuexModule } from 'vuex-module-decorators' @Module export default class Vehicle extends VuexModule { wheels = 2 } // 来替代之前的 export default { state: { wheels: 2 } } -
Getterс классным стилем вcomputedаналогично, также с помощьюgettersдостигатьimport { Module, VuexModule } from 'vuex-module-decorators' @Module export default class Vehicle extends VuexModule { wheels = 2 get axles() { return this.wheels / 2 } } // 来代替之前的 export default { state: { wheels: 2 }, getters: { axles: (state) => state.wheels / 2 } } -
Mutationмодифицироватьstate, как и Vuex в js, можно использовать только для реализации синхронных операцийimport { Module, VuexModule, Mutation } from 'vuex-module-decorators' @Module export default class Vehicle extends VuexModule { wheels = 2 @Mutation puncture(n: number) { this.wheels = this.wheels - n } } // 来替代之前的 export default { state: { wheels: 2 }, mutations: { puncture: (state, payload) => { state.wheels = state.wheels - payload } } } -
actionsИспользуется для реализации асинхронных операцийconst request = require('request') export default { state: { wheels: 2 }, mutations: { addWheel: (state, payload) => { state.wheels = state.wheels + payload } }, actions: { fetchNewWheels: async (context, payload) => { const wheels = await request.get(payload) context.commit('addWheel', wheels) } } } // 来替代之前的 const request = require('request') export default { state: { wheels: 2 }, mutations: { addWheel: (state, payload) => { state.wheels = state.wheels + payload } }, actions: { fetchNewWheels: async (context, payload) => { const wheels = await request.get(payload) context.commit('addWheel', wheels) } } }
Выше мы просто реализовали модуль Vuex, так как же его использовать? Разберите приведенный выше код и настройте его в Vuex, в частности
import { Module, VuexModule } from 'vuex-module-decorators'
@Module({ name: 'Vehicle', namespaced: true, stateFactory: true })
export default class Vehicle extends VuexModule {
public wheels = 2;
get axles() {
return this.wheels / 2;
}
@Mutation
public puncture(n: number): void {
this.wheels = this.wheels - n;
}
}
осторожностьModuleНужная нам конфигурация должна бытьnamespaced: true, назовите пространство и импортируйте его в проект
import Vue from 'vue'
import Vuex from 'vuex'
import Vehicle from './Vehicle'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
Vehicle,
},
})
затем используйтеvuex-class, чтобы получить статус и методы в пространстве имен
import { Component, Vue } from 'vue-property-decorator';
import {
Getter,
Mutation,
namespace,
} from 'vuex-class';
const Vehicle = namespace('Vehicle');
@Component
export default class HelloWorld extends Vue {
// 引入 Vechicle 下的 Getters
@Vehicle.Getter('axles') public axles: number | undefined;
// 引入 Vechicle 下的 puncture
@Vehicle.Mutation('puncture')
public mutationPuncture!: (n: number) => void;
private message: string = 'world';
public render() {
const { message, axles, mutationPuncture }: HelloWorld = this;
return (
<div onClick={ () => mutationPuncture(1) }>
<h5 ref='quickEntry'>Hello {message} { axles }</h5>
</div>
);
}
}
использоватьnamespaceВы можете легко получить модуль Vehicle Vuex, а затем сотрудничать сGetter,MutationВведение можно завершить, да и другие способы введения аналогичны, поэтому не буду вдаваться в подробности.
В заключение
В целом, весь процесс опыта очень похож на ощущения от написания Mobx и React на Typescript раньше, очень похоже. Если использовать его в реальных проектах, ts принесет некоторое удобство, но он также кажется немного надуманным Другое продолжение 3.0, давайте посмотрим, сможет ли он произвести замечательную химическую реакцию с ts.