Share
Embed
Vue.js * How to make front-end / vuejs how to make front-end
src: https://github.com/nrslib/vue-sample-assortment
# URL
HomePage: https://nrslib.com
Twitter: https://twitter.com/nrslib
nrs
September 25, 2019
Transcript
258 slides
-
クライアントの システムエラー クライアントの 回復可能エラー サーバーの システムエラー サーバーの 回復可能エラー サ ー
バ ク ラ イ ア ン ト システムエラー 回復可能エラー 22 -
クライアントの システムエラー クライアントの 回復可能エラー サーバーの システムエラー サーバーの 回復可能エラー サ ー
バ ク ラ イ ア ン ト システムエラー 回復可能エラー 23 -
クライアントの システムエラー クライアントの 回復可能エラー サーバーの システムエラー サーバーの 回復可能エラー サ ー
バ ク ラ イ ア ン ト システムエラー 回復可能エラー 24 -
クライアントの システムエラー クライアントの 回復可能エラー サーバーの システムエラー サーバーの 回復可能エラー サ ー
バ ク ラ イ ア ン ト システムエラー 回復可能エラー 32 -
Mail: [email protected] Name: naruse Password: ******** duplicated-email, duplicated-username duplicated-email だからメール欄に
エラー表示して duplicated-username だからユーザ名欄に エラー表示して 39 -
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); } } -
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); } } -
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 メソッドへ -
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 本体 -
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 (通信ライブラリ)をラップ -
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 の取り回しを 確認してみよう -
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 -
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 エラーハンドラー選定 -
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)); }; -
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)); }; デフォルト実装 -
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)); }; デフォルト=メッセージシステムに通知 -
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)); }; デフォルト=メッセージシステムに通知 具体的なメッセージは? -
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 さきほどのコード -
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 レスポンスからエラー用メッセージの生成 -
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; } } エラーメッセージ生成処理 -
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; } } エラーコードからキーを生成 -
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; } } メッセージのデータファイルから読み取り -
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" : "ユーザー名が長すぎます" } } } } } } -
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; } } エラーメッセージが見つからない時は デフォルトメッセージ -
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); } } -
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); } } -
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); } } -
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); } } エラーハンドラー登録用 -
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}; } } -
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}; } } ページ遷移してエラー通知する -
できごと ハンドリング 成功 する 失敗 する or しない 例外 セッション切れ
権限変更 (パーミッション変更) 81 -
できごと ハンドリング 成功 する 失敗 する or しない 例外 する
or しない セッション切れ 権限変更 (パーミッション変更) 82 -
できごと ハンドリング 成功 する 失敗 する or しない 例外 する
or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) 83 -
できごと ハンドリング 成功 する 失敗 する or しない 例外 する
or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) 84 -
できごと ハンドリング 成功 する 失敗 する or しない 例外 する
or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) 85 -
86 できごと ハンドリング 成功 する 失敗 する or しない 例外
する or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) export interface IOptionParameter<T> { onError?: IErrorHandler; onErrored?: () => void; onUnexpectedError?: UnexpectedErrorHandler<T>; config?: AxiosRequestConfig; } -
87 できごと ハンドリング 成功 する 失敗 する or しない 例外
する or しない セッション切れ ログイン画面へ 権限変更 (パーミッション変更) しない(権限エラー通知) export interface IOptionParameter<T> { onError?: IErrorHandler; onErrored?: () => void; onUnexpectedError?: UnexpectedErrorHandler<T>; config?: AxiosRequestConfig; } -
99 import LoginRootPage from "@/views/login/LoginRootPage.vue"; export default { path: '/login',
name: 'login', component: LoginRootPage, meta: { noAuth: true } }; -
100 import LoginRootPage from "@/views/login/LoginRootPage.vue"; export default { path: '/login',
name: 'login', component: LoginRootPage, meta: { noAuth: true } }; ページに認証不要を設定 (未設定=認証必要) -
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(); } ルート変更時のグローバルフック -
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(); } -
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; } -
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; } 遷移先は認証が必要か -
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; } 認証の確認 -
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; } 認証していなかったらセッション確認 -
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; } 未認証ならログイン画面へ -
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; } -
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; } 遷移先を保存 -
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'}); } } } ログイン画面 -
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'}); } } } ログイン後、保存された遷移先へ -
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 関連 -
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, }, ... ] } 最高権限が必要 -
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 権限 -
121 export default { path: '/', component: TopRootPage, meta: {role:
'any'}, children: [ { path: '', name: 'top', component: TopIndexPage } ] }; Top ページ -
122 export default { path: '/', component: TopRootPage, meta: {role:
'any'}, children: [ { path: '', name: 'top', component: TopIndexPage } ] }; 権限不要 -
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(); } ルート変更時のグローバルフック -
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(); } 認証後に認可の確認がある -
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; } -
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; } -
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); } そもそも認証が要求されるか確認 -
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; } -
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')); } 認可が不要か確認 -
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; } -
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); } }) } 自身の権限と照らし合わせる -
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へ遷移しエラー表示 -
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); }); -
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); }); -
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; } }; -
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へ遷移 -
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 -
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 -
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 -
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 相互参照 -
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 を渡してると 怪しいかも -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
TabButton TabButton TabButton TabButton TabButtonGroup Un Select Un Select Un
Select Un Select 201 -
TabButton TabButton TabButton TabButton TabButtonGroup Un Select Un Select Un
Select Un Select 202 -
TabButton TabButton TabButton TabButton TabContent TabButtonGroup Tab Un Select Un
Select Un Select Un Select Un Select 209 -
TabButton TabButton TabButton TabButton TabContent TabButtonGroup Tab Un Select Un
Select Un Select Un Select Un Select 210 -
TabButton TabButton TabButton TabButton TabContent TabButtonGroup Tab Select (B) Select
メソッド Vue などでは これをバインディングで 実現する 225 -
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(); }); } ... -
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(); }); } ... 子コンポーネントのイベントをハンドリング -
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(); }); } ... -
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(); }); } ... 子コンポーネントの操作は あくまでそれを保持するコンポーネント -
<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 { -
<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 { -
<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 { -
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(); }); } ... } -
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(); }); } ... } -
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(); }); } ... } 通信はフォームで行わずルートで行っている