###### tags: `ノート` # 5/4(月) ## [Typescript クラス](http://js.studio-kingdom.com/typescript/handbook/classes) ### 基本 ```typescript= class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return 'Hello, ' + this.greeting; } } let greeter = new Greeter('World'); ``` ### 継承 ```typescript= class Animal { name: string; constructor(name: string) { this.name = name; } move(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters`m) } } class Snake extends Animal { constructor(name: string) { super(name); } move(disranceInMeters: number = 5) { console.log('Slithering...'); super.move(distanceInMeters); } } ``` ### public Typescriptは各メンバはデフォルトでpublicになります。次のように書くこともできます ```typescript= class Animal { public name: string; public constructor(name: string) { this.name = name; } public moved(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters`m); } } ``` ### protected 指定されたメンバが継承先クラスのインスタンスからでもアクセス可能であることをのぞいて、ほとんど`private`と同じように振舞います。 ```typescript= class Person { protected name: string; constructor(name: string) { this.name = name; } } class Employee extends Person { private department: string; constructor(name: string, department: string) { super(name); this.department = department; } public getElevatorPitch() { return `Hello, my name is ${this.name} and I work in ${this.department}.`; } } let howard = new Employee("Howard", "Sales"); console.log(howard.name); // Error nameにアクセスできない console.log(howard.getElevationsPitch); // nameにアクセスできる ``` ### 引数プロパティ 引数プロパティは作成・初期化を1箇所で済ませることを可能にしてくれます ```typescript= class Animal { constructor(private name: string) {} move(distanceInMeters: number) { console.log(`${this.name} moved ${distanceInMeters}m.`); } } ``` ### アクセサ TypeScriptは、オブジェクトのメンバへのアクセスの方法のひとつとして`getter/setter`をサポートしてます。メンバーの各オブジェクトにアクセスする際に、きめ細やかな制御を持たせることを可能にしてくれます。 ```typescript= let passcode = 'secret passcode' class Employee { private _fullName: string; get fullName(): string { return this._fullName; } set fullName(newName: string) { if (passcode && passcode == 'secret passcode') { this._fullName = newName; }else { console.log('Error: Unauthorized update of employee!'); } } } let employee = new Employee(); employee.fullName = 'Bob Smith'; if (employee.fullName) { console.log(employee.fullName); } ``` ## [Vue3](https://qiita.com/ryo2132/items/f055679e9974dbc3f977) ### リアクティブなプロパティの宣言 今までの`data()`に相当するリアクティブなプロパティは`ref()`または`reactive()`で宣言します。 `<template>`で使うプロパティは、必ず`return`で返す必要があります。 ```typescript= <template> <div> <h2>{{ state.messageOne }}</h2> <h2>{{ messageTwo }}</h2> </div> </template> <scrip lang="ts"> import { defineComponent, ref, reactive } from 'vue' export default defineConponent({ setup() { const state = reactive<{ messageOne: string }>({ messageOne: 'Hello' }); const messageTwo = ref<string>('こんばんは'); return { state, messageTwo } } }) </script> ``` ### ライフサイクルフック vueのライフサイクルに合わせて処理を実行するライフサイクルフックは、setup()で、onXXXの形式で設定できます。 ```typescript= import { onMounted, onUpdated, onUnmounted } from 'vue' const MyComponent = { setup() { onMounted(() => { console.log('mounted!') }) onUpdated(() => { console.log('updated!') }) onUnmounted(() => { console.log('unmounted!') }) } } ``` | Vue 2.x | Composition API | | -------- | -------- | | beforeCreate | - | | created | - | | beforeMount | onBeforeMount | | beforeUpdate | onBeforeUpdate | | beforeDestroy | onBeforeUnmount | | destroyed | onUnmounted | | errorCaptured | onErrorCaptured | ## Vue スロット 単純にテキストを表示するだけなら、プロパティでテキストを渡しても良いが、タグを含めたりする場合は、スロットを用います。 ### 単一スロット 子: MyButton ```typescript= <button> <slot>送信</slot> </button> ``` 親: ```typescript= <my-button> 新規登録 </my-button> ``` ### 名前付きスロット 同じコンポーネントにスロットが複数あっても、名前をつけることで解決します。 子: myPage ```typescript= <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"> </footer> ``` 親: ```typescript= <my-page> <h1 slot="header">Ropital Page</h1> <p>Hello World</p> <p slot="footer">Good bye</p> </my-page> ```