Vue + Typescript + vue-property-decoratorでコンポーネントをクラス宣言的に記述する際、data
はクラスのインスタンス変数として定義し、
method
はクラスのメソッドとして記述できます。
<template> <p v-for="(b, i) in books" :key="i">{{b.name}}</p> </template> <script lang="ts"> import { Component, Vue } from 'nuxt-property-decorator'; import { BookFactory } from '@/service/factory/book'; @Component export default class BookNames extends Vue { books: Book[] = []; fetchBooks(){ books = BookFactory.findBooks(); } } </script>
このとき、これらクラスメンバのアクセス修飾子はどのようにすればよいのか気になりました。
通常のTypeScriptクラス同様、コンポーネントクラスではアクセス修飾子を設定できます。
private books: Book[] = []; private fetchBooks(){ books = BookFactory.findBooks(); }
この修飾子をprivateにしようがpublicにしようが、テンプレートからは参照できます。
<template> <p v-for="(b, i) in books" :key="i">{{b.name}}</p> </template>
では、ref` を使用した外部コンポーネントからの呼び出しではどうなるのでしょうか。
<template> <book-names ref="books"/> </template> <script lang="ts"> import { Component, Vue } from 'nuxt-property-decorator'; import { BookNames } from '@/components/molecules/BookNames'; @Component({ components:{ BookNames } }) export default class Parent extends Vue { mounted(){ console.log(this.$ref.books.books); // [ {name: "hoge"}, ... ] } } </script>
privateでも呼べてしまいます。外部コンポーネントからの呼び出しでも可視性は無視されました。*1
結局、TSをJSにトランスパイルする際にはTSの可視性は無視される(トランスパイルの際の構文チェックでのみ可視性が有効である)ため、
TS(Vue)の静的構文チェックで引っかからない限りアクセス修飾子は意味を成しません。
ex. privateメンバを持つTypeScriptクラスのトランスパイル
export default class Child { private hoge: string = "hoge"; }
↓
"use strict"; exports.__esModule = true; var Child = /** @class */ (function () { function Child() { this.hoge = "hoge"; } return Child; }()); exports["default"] = Child;
ただし、$refs
の持つメンバへの型定義を無理やり行えば、クラスの可視性は有効になります。
export interface Context { readonly refs: { [key: string]: BookName; }; }
ただし、これでは $refs
で BookName
しか参照できなくなります。
特に意味を成さないのであれば、privateはクラス内参照、修飾子なし/publicであれば外部参照用のメソッドなど、あくまで読み手に対するマーカとして使用していくのがベターなんですかね。。。