Vue.js * How to make front-end / vuejs how to make front-end

E37b4344ef4bfd0fc4826c04971e54fb?s=47 nrs
September 25, 2019

Vue.js * How to make front-end / vuejs how to make front-end

E37b4344ef4bfd0fc4826c04971e54fb?s=128

nrs

September 25, 2019
Tweet

Transcript

  1. 29.

    29

  2. 35.

    35

  3. 39.

    Mail: naruse@example.com Name: naruse Password: ******** duplicated-email, duplicated-username duplicated-email だからメール欄に

    エラー表示して duplicated-username だからユーザ名欄に エラー表示して 39
  4. 42.

    42

  5. 43.

    43

  6. 48.

    48 export default class WraxiosCore { ... public get<T>(url: string,

    params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } }
  7. 49.

    49 export default class WraxiosCore { ... public get<T>(url: string,

    params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } }
  8. 50.

    50 export default class WraxiosCore { ... public get<T>(url: string,

    params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } } request メソッドへ
  9. 51.

    export default class WraxiosCore { ... public request<T>(method: Method, url:

    string, data?: any, aParams?: IOptionParameter<T>): Pr const params = aParams === null || aParams === void 0 ? {} : aParams!; const requestConfig: AxiosRequestConfig = !params || !params.config ? {} : params.config; requestConfig.method = method; requestConfig.url = url; requestConfig.data = data; const calledQueueNum = this.queueNum; return new Promise<WraxiosResponse<T>>((resolve, reject) => { axios.request<T>(requestConfig) .then(res => { if (calledQueueNum !== this.queueNum) { return; } const response = new WraxiosResponse(res.data); resolve(response); }) .catch((e: AxiosError) => { if (calledQueueNum !== this.queueNum) { 51 request 本体
  10. 52.

    export default class WraxiosCore { ... public request<T>(method: Method, url:

    string, data?: any, aParams?: IOptionParameter<T>): Pr const params = aParams === null || aParams === void 0 ? {} : aParams!; const requestConfig: AxiosRequestConfig = !params || !params.config ? {} : params.config; requestConfig.method = method; requestConfig.url = url; requestConfig.data = data; const calledQueueNum = this.queueNum; return new Promise<WraxiosResponse<T>>((resolve, reject) => { axios.request<T>(requestConfig) .then(res => { if (calledQueueNum !== this.queueNum) { return; } const response = new WraxiosResponse(res.data); resolve(response); }) .catch((e: AxiosError) => { if (calledQueueNum !== this.queueNum) { 52 axios (通信ライブラリ)をラップ
  11. 53.

    export default class WraxiosCore { ... public request<T>(method: Method, url:

    string, data?: any, aParams?: IOptionParameter<T>): Pr const params = aParams === null || aParams === void 0 ? {} : aParams!; const requestConfig: AxiosRequestConfig = !params || !params.config ? {} : params.config; requestConfig.method = method; requestConfig.url = url; requestConfig.data = data; const calledQueueNum = this.queueNum; return new Promise<WraxiosResponse<T>>((resolve, reject) => { axios.request<T>(requestConfig) .then(res => { if (calledQueueNum !== this.queueNum) { return; } const response = new WraxiosResponse(res.data); resolve(response); }) .catch((e: AxiosError) => { if (calledQueueNum !== this.queueNum) { 53 axios の取り回しを 確認してみよう
  12. 54.

    axios.request<T>(requestConfig) .then(res => { ... }) .catch((e: AxiosError) => {

    ... if (response.status === 400) { const clientErrorResponse = this.makeResponse(response.data); const errorHandler = this.selectErrorHandler(params.onError); errorHandler(clientErrorResponse); if (!!params.onErrored) { params.onErrored(); } } else { const unExpectedErrorHandler = this.selectUnexpectedErrorHandler(params.onUnexpectedE unExpectedErrorHandler(resolve, reject, e); } }); 54
  13. 55.

    axios.request<T>(requestConfig) .then(res => { ... }) .catch((e: AxiosError) => {

    ... if (response.status === 400) { const clientErrorResponse = this.makeResponse(response.data); const errorHandler = this.selectErrorHandler(params.onError); errorHandler(clientErrorResponse); if (!!params.onErrored) { params.onErrored(); } } else { const unExpectedErrorHandler = this.selectUnexpectedErrorHandler(params.onUnexpectedE unExpectedErrorHandler(resolve, reject, e); } }); 55 エラーハンドラー選定
  14. 56.

    56 export default class WraxiosCore { ... private selectErrorHandler<T>(handler?: IErrorHandler):

    IErrorHandler { if (handler === null || handler === void 0) { return notifyErrorToMessage; } return handler; } } const notifyErrorToMessage: IErrorHandler = (response: IErrorResponse) => { response.errors .map((x) => x.message) .forEach((message) => ServiceLocator.instance.messageService .addMessage(MessageType.Error, message)); };
  15. 57.

    57 export default class WraxiosCore { ... private selectErrorHandler<T>(handler?: IErrorHandler):

    IErrorHandler { if (handler === null || handler === void 0) { return notifyErrorToMessage; } return handler; } } const notifyErrorToMessage: IErrorHandler = (response: IErrorResponse) => { response.errors .map((x) => x.message) .forEach((message) => ServiceLocator.instance.messageService .addMessage(MessageType.Error, message)); }; デフォルト実装
  16. 58.

    58 export default class WraxiosCore { ... private selectErrorHandler<T>(handler?: IErrorHandler):

    IErrorHandler { if (handler === null || handler === void 0) { return notifyErrorToMessage; } return handler; } } const notifyErrorToMessage: IErrorHandler = (response: IErrorResponse) => { response.errors .map((x) => x.message) .forEach((message) => ServiceLocator.instance.messageService .addMessage(MessageType.Error, message)); }; デフォルト=メッセージシステムに通知
  17. 59.

    59 export default class WraxiosCore { ... private selectErrorHandler<T>(handler?: IErrorHandler):

    IErrorHandler { if (handler === null || handler === void 0) { return notifyErrorToMessage; } return handler; } } const notifyErrorToMessage: IErrorHandler = (response: IErrorResponse) => { response.errors .map((x) => x.message) .forEach((message) => ServiceLocator.instance.messageService .addMessage(MessageType.Error, message)); }; デフォルト=メッセージシステムに通知 具体的なメッセージは?
  18. 60.

    axios.request<T>(requestConfig) .then(res => { ... }) .catch((e: AxiosError) => {

    ... if (response.status === 400) { const clientErrorResponse = this.makeResponse(response.data); const errorHandler = this.selectErrorHandler(params.onError); errorHandler(clientErrorResponse); if (!!params.onErrored) { params.onErrored(); } } else { const unExpectedErrorHandler = this.selectUnexpectedErrorHandler(params.onUnexpectedE unExpectedErrorHandler(resolve, reject, e); } }); 60 さきほどのコード
  19. 61.

    axios.request<T>(requestConfig) .then(res => { ... }) .catch((e: AxiosError) => {

    ... if (response.status === 400) { const clientErrorResponse = this.makeResponse(response.data); const errorHandler = this.selectErrorHandler(params.onError); errorHandler(clientErrorResponse); if (!!params.onErrored) { params.onErrored(); } } else { const unExpectedErrorHandler = this.selectUnexpectedErrorHandler(params.onUnexpectedE unExpectedErrorHandler(resolve, reject, e); } }); 61 レスポンスからエラー用メッセージの生成
  20. 62.

    62 export default class WraxiosCore { ... private makeResponse<T>(data: any):

    IErrorResponse { const response = data as IErrorResponse; if (!!response && !!response.errors) { for (const error of response.errors) { const errorMessageKey = 'error.api.' + error.code; const errorMessage = i18n.t(errorMessageKey).toString(); if (!errorMessage || errorMessage === errorMessageKey) { error.message = i18n.t( 'common.wraxios.unregistered-error-message’, { errorCode : "code:¥"" + error.code + "¥""} ).toString(); } else { error.message = errorMessage; } } } return data; } } エラーメッセージ生成処理
  21. 63.

    63 export default class WraxiosCore { ... private makeResponse<T>(data: any):

    IErrorResponse { const response = data as IErrorResponse; if (!!response && !!response.errors) { for (const error of response.errors) { const errorMessageKey = 'error.api.' + error.code; const errorMessage = i18n.t(errorMessageKey).toString(); if (!errorMessage || errorMessage === errorMessageKey) { error.message = i18n.t( 'common.wraxios.unregistered-error-message’, { errorCode : "code:¥"" + error.code + "¥""} ).toString(); } else { error.message = errorMessage; } } } return data; } } エラーコードからキーを生成
  22. 64.

    64 export default class WraxiosCore { ... private makeResponse<T>(data: any):

    IErrorResponse { const response = data as IErrorResponse; if (!!response && !!response.errors) { for (const error of response.errors) { const errorMessageKey = 'error.api.' + error.code; const errorMessage = i18n.t(errorMessageKey).toString(); if (!errorMessage || errorMessage === errorMessageKey) { error.message = i18n.t( 'common.wraxios.unregistered-error-message’, { errorCode : "code:¥"" + error.code + "¥""} ).toString(); } else { error.message = errorMessage; } } } return data; } } メッセージのデータファイルから読み取り
  23. 65.

    65 export default class WraxiosCore { ... private makeResponse<T>(data: any):

    IErrorResponse { const response = data as IErrorResponse; if (!!response && !!response.errors) { for (const error of response.errors) { const errorMessageKey = 'error.api.' + error.code; const errorMessage = i18n.t(errorMessageKey).toString(); if (!errorMessage || errorMessage === errorMessageKey) { error.message = i18n.t( 'common.wraxios.unregistered-error-message’, { errorCode : "code:¥"" + error.code + "¥""} ).toString(); } else { error.message = errorMessage; } } } return data; } } メッセージのデータファイルから読み取り { "ja" : { "common" : { "routing" : { "no-authority" : "権限が足りません" }, "wraxios" : { "unregistered-error-message" : "予期せぬエラー({errorCode})", "role-changed" : "権限が不足しています" } }, "error" : { "api" : { "/user" : { "POST" : { "too-long-name" : "ユーザー名が長すぎます" } } } } } }
  24. 66.

    66 export default class WraxiosCore { ... private makeResponse<T>(data: any):

    IErrorResponse { const response = data as IErrorResponse; if (!!response && !!response.errors) { for (const error of response.errors) { const errorMessageKey = 'error.api.' + error.code; const errorMessage = i18n.t(errorMessageKey).toString(); if (!errorMessage || errorMessage === errorMessageKey) { error.message = i18n.t( 'common.wraxios.unregistered-error-message’, { errorCode : "code:¥"" + error.code + "¥""} ).toString(); } else { error.message = errorMessage; } } } return data; } } エラーメッセージが見つからない時は デフォルトメッセージ
  25. 70.

    70 export default class WraxiosCore { ... public get<T>(url: string,

    params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } }
  26. 71.

    71 export default class WraxiosCore { ... public get<T>(url: string,

    params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } }
  27. 72.

    72 export interface IOptionParameter<T> { onError?: IErrorHandler; onErrored?: () =>

    void; onUnexpectedError?: UnexpectedErrorHandler<T>; config?: AxiosRequestConfig; } export default class WraxiosCore { ... public get<T>(url: string, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } }
  28. 73.

    73 export interface IOptionParameter<T> { onError?: IErrorHandler; onErrored?: () =>

    void; onUnexpectedError?: UnexpectedErrorHandler<T>; config?: AxiosRequestConfig; } export default class WraxiosCore { ... public get<T>(url: string, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('get', url, null, params); } public post<T>(url: string, data?: any, params?: IOptionParameter<T>): Promise<WraxiosResponse<T>> { return this.request('post', url, data, params); } } エラーハンドラー登録用
  29. 74.

    74 export default class UserAddConfirmPage extends Vue { ... public

    onSubmitButtonClick() { wraxios.post<IUserCreateResponse>( 'user', this.model, { onError: (res) => { pushNextWithError(res, this.backLocation()); }}) .then(res=> { const data = res.data; this.$router.push({name: "user-detail", params: { id: data.createdUuid }}) }); } private backLocation(): RawLocation { return {name: 'user-add-input', params: <any>this.model}; } }
  30. 75.

    75 export default class UserAddConfirmPage extends Vue { ... public

    onSubmitButtonClick() { wraxios.post<IUserCreateResponse>( 'user', this.model, { onError: (res) => { pushNextWithError(res, this.backLocation()); }}) .then(res=> { const data = res.data; this.$router.push({name: "user-detail", params: { id: data.createdUuid }}) }); } private backLocation(): RawLocation { return {name: 'user-add-input', params: <any>this.model}; } } ページ遷移してエラー通知する
  31. 76.

    76

  32. 77.

    77

  33. 82.

    できごと ハンドリング 成功 する 失敗 する or しない 例外 する

    or しない セッション切れ 権限変更 (パーミッション変更) 82
  34. 83.

    できごと ハンドリング 成功 する 失敗 する or しない 例外 する

    or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) 83
  35. 84.

    できごと ハンドリング 成功 する 失敗 する or しない 例外 する

    or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) 84
  36. 85.

    できごと ハンドリング 成功 する 失敗 する or しない 例外 する

    or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) 85
  37. 86.

    86 できごと ハンドリング 成功 する 失敗 する or しない 例外

    する or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) export interface IOptionParameter<T> { onError?: IErrorHandler; onErrored?: () => void; onUnexpectedError?: UnexpectedErrorHandler<T>; config?: AxiosRequestConfig; }
  38. 87.

    87 できごと ハンドリング 成功 する 失敗 する or しない 例外

    する or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) export interface IOptionParameter<T> { onError?: IErrorHandler; onErrored?: () => void; onUnexpectedError?: UnexpectedErrorHandler<T>; config?: AxiosRequestConfig; }
  39. 99.

    99 import LoginRootPage from "@/views/login/LoginRootPage.vue"; export default { path: '/login',

    name: 'login', component: LoginRootPage, meta: { noAuth: true } };
  40. 100.

    100 import LoginRootPage from "@/views/login/LoginRootPage.vue"; export default { path: '/login',

    name: 'login', component: LoginRootPage, meta: { noAuth: true } }; ページに認証不要を設定 (未設定=認証必要)
  41. 102.

    102 export default async function globalBeforeEach(to: Route, from: Route, next:

    Function) { if (await transferLoginWhenNoAuth(to, from, next)) { return; } if (await transferWhenNoRole(to, from, next)) { return; } next(); } ルート変更時のグローバルフック
  42. 103.

    103 export default async function globalBeforeEach(to: Route, from: Route, next:

    Function) { if (await transferLoginWhenNoAuth(to, from, next)) { return; } if (await transferWhenNoRole(to, from, next)) { return; } next(); }
  43. 104.

    104 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; }
  44. 105.

    105 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; } 遷移先は認証が必要か
  45. 106.

    106 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; } 認証の確認
  46. 107.

    107 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; } 認証していなかったらセッション確認
  47. 108.

    108 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; } 未認証ならログイン画面へ
  48. 109.

    109

  49. 112.

    112 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; }
  50. 113.

    113 async function transferLoginWhenNoAuth(to: Route, from: Route, next: Function) :

    Promise<boolean> { if (isAuthorised(to)) { if (!accountStoreFacade.hasInfo()) { await accountStoreFacade.loadAccountInfo(); if (!accountStoreFacade.hasInfo()) { if (!ServiceLocator.instance.routeService.endure) { ServiceLocator.instance.routeService.releaseOverwrite(); ServiceLocator.instance.routeService.saveBackRoute(to); } next({name: 'login'}); return true; } } } return false; } 遷移先を保存
  51. 114.

    114 export default class LoginRootPage extends Vue { @Action("account/loadAccountInfo") public

    loadAccountInfo!: () => Promise<void>; public async onLoggedIn() { await this.loadAccountInfo(); const routeService = ServiceLocator.instance.routeService; if (routeService.hasBackRoute) { const nextRoute = routeService.pathToBack(); routeService.clear(); this.$router.push(nextRoute); } else { this.$router.push({name: 'top'}); } } } ログイン画面
  52. 115.

    115 export default class LoginRootPage extends Vue { @Action("account/loadAccountInfo") public

    loadAccountInfo!: () => Promise<void>; public async onLoggedIn() { await this.loadAccountInfo(); const routeService = ServiceLocator.instance.routeService; if (routeService.hasBackRoute) { const nextRoute = routeService.pathToBack(); routeService.clear(); this.$router.push(nextRoute); } else { this.$router.push({name: 'top'}); } } } ログイン後、保存された遷移先へ
  53. 118.

    118 export default { path: '/user', component: UserRootPage, children: [

    { path: '', name: 'user-index', component: UserIndexPage, meta: {role: AccountRole.Advanced}, }, { path: ':id', name: 'user-detail', component: UserDetailPage, meta: {role: AccountRole.Advanced}, }, { path: 'add/input', name: 'user-add-input', component: UserAddInputPage, }, ... ] } User 関連
  54. 119.

    119 export default { path: '/user', component: UserRootPage, children: [

    { path: '', name: 'user-index', component: UserIndexPage, meta: {role: AccountRole.Advanced}, }, { path: ':id', name: 'user-detail', component: UserDetailPage, meta: {role: AccountRole.Advanced}, }, { path: 'add/input', name: 'user-add-input', component: UserAddInputPage, }, ... ] } 最高権限が必要
  55. 120.

    120 export default { path: '/user', component: UserRootPage, children: [

    { path: '', name: 'user-index', component: UserIndexPage, meta: {role: AccountRole.Advanced}, }, { path: ':id', name: 'user-detail', component: UserDetailPage, meta: {role: AccountRole.Advanced}, }, { path: 'add/input', name: 'user-add-input', component: UserAddInputPage, }, ... ] } Advanced 権限
  56. 121.

    121 export default { path: '/', component: TopRootPage, meta: {role:

    'any'}, children: [ { path: '', name: 'top', component: TopIndexPage } ] }; Top ページ
  57. 122.

    122 export default { path: '/', component: TopRootPage, meta: {role:

    'any'}, children: [ { path: '', name: 'top', component: TopIndexPage } ] }; 権限不要
  58. 124.

    124 export default async function globalBeforeEach(to: Route, from: Route, next:

    Function) { if (await transferLoginWhenNoAuth(to, from, next)) { return; } if (await transferWhenNoRole(to, from, next)) { return; } next(); } ルート変更時のグローバルフック
  59. 125.

    125 export default async function globalBeforeEach(to: Route, from: Route, next:

    Function) { if (await transferLoginWhenNoAuth(to, from, next)) { return; } if (await transferWhenNoRole(to, from, next)) { return; } next(); } 認証後に認可の確認がある
  60. 126.

    126 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; }
  61. 127.

    127 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; }
  62. 128.

    128 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; } function isAuthorised(to: Route): boolean { return to.matched.every(record => !record.meta.noAuth); } そもそも認証が要求されるか確認
  63. 129.

    129 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; }
  64. 130.

    130 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; } function isAnonymous(to: Route): boolean { return to.matched.some((record => !!record.meta && record.meta.role === 'any')); } 認可が不要か確認
  65. 131.

    131 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; }
  66. 132.

    132 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; } function isAllowed(to: Route): boolean { return to.matched.some(record => { if (!record || !record.meta) { return false; } const metaRole = record.meta.role; if (metaRole instanceof Array) { const allowedRoles = <AccountRole[]>metaRole; return accountStoreFacade.isAllowedAny(allowedRoles); } else { const allowedRole = !!metaRole ? <AccountRole>metaRole : AccountRole.Administrator; return accountStoreFacade.isAllowed(allowedRole); } }) } 自身の権限と照らし合わせる
  67. 133.

    133 async function transferWhenNoRole(to: Route, from:Route, next: Function): Promise<boolean> {

    if (!isAuthorised(to)) { return false; } if (isAnonymous(to)) { return false; } if (isAllowed(to)) { return false; } const showMessage = from.name === 'top' ? (message: string) => ServiceLocator.instance.messageService.addMessage(MessageType.Erro : (message: string) => ServiceLocator.instance.messageService.reserve(MessageType.Error, const mesasge = i18n.t("common.routing.no-authority").toString(); showMessage(mesasge); next({name: "top"}); return true; } 権限がないのでTOPへ遷移しエラー表示
  68. 136.

    136 router.get('', authorize("advanced"), (req, res) => { const json =

    debugDataLoader("user", "get"); res.json(json); }); router.post('', authorize(), (req, res) => { const json = debugDataLoader("user", "post"); res.json(json); }); router.get('/:id', authorize("advanced"), (req, res) => { const json = debugDataLoader("user", "get-detail"); res.json(json); });
  69. 137.

    137 router.get('', authorize("advanced"), (req, res) => { const json =

    debugDataLoader("user", "get"); res.json(json); }); router.post('', authorize(), (req, res) => { const json = debugDataLoader("user", "post"); res.json(json); }); router.get('/:id', authorize("advanced"), (req, res) => { const json = debugDataLoader("user", "get-detail"); res.json(json); });
  70. 139.

    139 const notifyMessageWhenUnexpectedErrorHandler: IUnexpectedErrorHandler = <T>( resolve: (value?: WraxiosResponse<T> |

    PromiseLike<WraxiosResponse<T>>) => void, reject: (reason?: any) => void, error: AxiosError<T> ) => { ... const statusCode = response.status; switch (statusCode) { case 401: router.push({name: 'login'}); break; case 403: const message = i18n.t('common.wraxios.role-changed').toString(); ServiceLocator.instance.messageService.reserve(MessageType.Info, message); router.push({name: 'top'}); break; default: router.push({name: 'error-server'}); break; } };
  71. 140.

    140 const notifyMessageWhenUnexpectedErrorHandler: IUnexpectedErrorHandler = <T>( resolve: (value?: WraxiosResponse<T> |

    PromiseLike<WraxiosResponse<T>>) => void, reject: (reason?: any) => void, error: AxiosError<T> ) => { ... const statusCode = response.status; switch (statusCode) { case 401: router.push({name: 'login'}); break; case 403: const message = i18n.t('common.wraxios.role-changed').toString(); ServiceLocator.instance.messageService.reserve(MessageType.Info, message); router.push({name: 'top'}); break; default: router.push({name: 'error-server'}); break; } }; 権限エラーメッセージを予約してTOPへ遷移
  72. 148.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 148
  73. 149.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 149
  74. 150.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 150
  75. 151.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 151 相互参照
  76. 152.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 152 相互参照 コンストラクタに this を渡してると 怪しいかも
  77. 153.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 153
  78. 154.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 154
  79. 155.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 155
  80. 156.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 156
  81. 157.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } } class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { ... this.objectA.methodForB(); } 157
  82. 159.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 159
  83. 160.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 160
  84. 161.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 161
  85. 162.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 162
  86. 163.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 163
  87. 164.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 164
  88. 165.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 165
  89. 166.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 166
  90. 167.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 167
  91. 168.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 168
  92. 169.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 169
  93. 170.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 170
  94. 171.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 171
  95. 172.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 172
  96. 173.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 173
  97. 174.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 174
  98. 175.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 175
  99. 176.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 176
  100. 177.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 177
  101. 178.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 178
  102. 179.

    class ObjectA { private objectB = new ObjectB(this); public method()

    { this.objectB.methodForA(); } public methodForB() { ... } public methodForB2() { ... this.objectB.methodForA2(); } public methodForB3() { this.objectB.methodForA3(); ... this.objectB.methodForA4(); } public methodForB4() { ... class ObjectB { public constructor( private readonly objectA: ObjectA) { } public method() { this.objectA.methodForB(); } public methodForA() { this.objectA.methodForB(); ... this.objectA.methodForB2(); } public methodForA2() { ... this.objectA.methodForB3(); } public methodForA3() { ... } public methodForA4() { 動作順序 把握できました? 179
  103. 185.

    class Parent { private readonly objectA = new ObjectA(); private

    readonly objectB = new ObjectB(); public method() { this.objectB.methodForA(); this.objectA.methodForB(); this.objectA.methodForB2(); this.objectB.methodForA2(); this.objectA.methodForB3(); this.objectB.methodForA3(); this.objectB.methodForA4(); } } 185
  104. 186.

    class Parent { private readonly objectA = new ObjectA(); private

    readonly objectB = new ObjectB(); public method() { this.objectB.methodForA(); this.objectA.methodForB(); this.objectA.methodForB2(); this.objectB.methodForA2(); this.objectA.methodForB3(); this.objectB.methodForA3(); this.objectB.methodForA4(); } } class ObjectA { public methodForB() { ... } public methodForB2() { ... } public methodForB3() { ... } public methodForB4() { ... } } class ObjectB { public methodForA() { ... } public methodForA2() { ... } public methodForA3() { ... } public methodForA4() { ... } } 186
  105. 187.

    class Parent { private readonly objectA = new ObjectA(); private

    readonly objectB = new ObjectB(); public method() { this.objectB.methodForA(); this.objectA.methodForB(); this.objectA.methodForB2(); this.objectB.methodForA2(); this.objectA.methodForB3(); this.objectB.methodForA3(); this.objectB.methodForA4(); } } class ObjectA { public methodForB() { ... } public methodForB2() { ... } public methodForB3() { ... } public methodForB4() { ... } } class ObjectB { public methodForA() { ... } public methodForA2() { ... } public methodForA3() { ... } public methodForA4() { ... } } オブジェクトは シンプルに 187
  106. 188.

    class Parent { private readonly objectA = new ObjectA(); private

    readonly objectB = new ObjectB(); public method() { this.objectB.methodForA(); this.objectA.methodForB(); this.objectA.methodForB2(); this.objectB.methodForA2(); this.objectA.methodForB3(); this.objectB.methodForA3(); this.objectB.methodForA4(); } } 188
  107. 189.

    class Parent { private readonly objectA = new ObjectA(); private

    readonly objectB = new ObjectB(); public method() { this.objectB.methodForA(); this.objectA.methodForB(); this.objectA.methodForB2(); this.objectB.methodForA2(); this.objectA.methodForB3(); this.objectB.methodForA3(); this.objectB.methodForA4(); } } コードを見れば 一目瞭然 189
  108. 225.

    TabButton TabButton TabButton TabButton TabContent TabButtonGroup Tab Select (B) Select

    メソッド Vue などでは これをバインディングで 実現する 225
  109. 227.

    227 <template> <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate>

    </template> <script lang="ts"> export default class LoginRootPage extends Vue { ... public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ...
  110. 228.

    228 <template> <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate>

    </template> <script lang="ts"> export default class LoginRootPage extends Vue { ... public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ... 子コンポーネントのイベントをハンドリング
  111. 229.

    229 <template> <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate>

    </template> <script lang="ts"> export default class LoginRootPage extends Vue { ... public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ...
  112. 230.

    230 <template> <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate>

    </template> <script lang="ts"> export default class LoginRootPage extends Vue { ... public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ... 子コンポーネントの操作は あくまでそれを保持するコンポーネント
  113. 243.

    <template> <ContentsWithBreadcrumbs> ... <v-container> <List> <ListItem v-for="(user, index) in users"

    :key="index"> <ListTitle> <LinkComponent :to="{name:'user-detail', params: {id: user.id}}"> {{user.name}} </LinkComponent> </ListTitle> </ListItem> </List> </v-container> ... </template> <script lang="ts"> ... export default class UserIndexPage extends Vue {
  114. 244.

    <template> <ContentsWithBreadcrumbs> ... <v-container> <List> <ListItem v-for="(user, index) in users"

    :key="index"> <ListTitle> <LinkComponent :to="{name:'user-detail', params: {id: user.id}}"> {{user.name}} </LinkComponent> </ListTitle> </ListItem> </List> </v-container> ... </template> <script lang="ts"> ... export default class UserIndexPage extends Vue {
  115. 245.

    <template> <ContentsWithBreadcrumbs> ... <v-container> <List> <ListItem v-for="(user, index) in users"

    :key="index"> <ListTitle> <LinkComponent :to="{name:'user-detail', params: {id: user.id}}"> {{user.name}} </LinkComponent> </ListTitle> </ListItem> </List> </v-container> ... </template> <script lang="ts"> ... export default class UserIndexPage extends Vue {
  116. 251.

    251 <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate> </template>

    <script lang="ts"> ... export default class LoginRootPage extends Vue { @Action("account/loadAccountInfo") public loadAccountInfo!: () => Promise<void>; public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ... }
  117. 252.

    252 <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate> </template>

    <script lang="ts"> ... export default class LoginRootPage extends Vue { @Action("account/loadAccountInfo") public loadAccountInfo!: () => Promise<void>; public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ... }
  118. 253.

    253 <NoAuthorityTemplate> <Contents> <LoginForm :disabled="formDisabled" @submit="onSubmit" /> </Contents> </NoAuthorityTemplate> </template>

    <script lang="ts"> ... export default class LoginRootPage extends Vue { @Action("account/loadAccountInfo") public loadAccountInfo!: () => Promise<void>; public formDisabled: boolean = false; public onSubmit(model: ILoginRequest) { ServiceLocator.instance.messageService.clearMessage(); this.formDisabled = true; wraxios.post('/login', model, { onErrored: () => { this.formDisabled = false; }}) .then(_ => { this.onLoggedIn(); }); } ... } 通信はフォームで行わずルートで行っている