質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1894閲覧

Vue3でルーティングを切り分けるには?

nosuke09

総合スコア9

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2023/04/11 02:31

編集2023/04/11 06:15

実現したいこと

Vue3で管理者と一般ユーザーのルーティングを分けたい

前提

実務経験なしの個人開発です。
フロント:Vue3
クイックスタートで$ npm init vue@latestでプロジェクトを立ち上げ。
一般ユーザーのログイン機能を実装した後、管理者にしかできない機能を追加する必要性を感じ、管理者のログイン機能を追加しようとしました。
ログイン画面は切り分けています。

一般ユーザー:ログイン画面→アプリケーションのホーム画面 管理者:(一般ユーザーのログイン画面から「管理者はこちらみたいなリンクを作るかも」)管理者のログイン画面→管理者のホーム画面

上記のようなルートを構想しています。
ここで、一般ユーザーと管理者ではログインの仕様や、ページごとでの認証などに違いがあるのでVue3で言うところのナビゲーションガイドをそれぞれ分ける必要性があると思いました。ページごとにmeta情報を割り振って条件分岐することは不可能ではなさそうですが、運用保守上よくない気がしたので、ルート自体を分けようと言う発想になりました。

発生している問題・エラーメッセージ

色々試して今は下記の状態で止まってしまっていると言う状況です。
ルートをそれぞれ設定して、htmlのタグを2つ用意して、それぞれmountしているといった感じです。
これだとどちらも表示されるようになっており(例えば、一般ユーザーのログイン画面で下にスクロールすると管理者のログイン画面がある)、先に定義しているからか、#user-appにマウントした方はルーティング通り遷移するのですが、管理者画面はアクセスできません。

失礼しました。上記は

JavaScript

1{ 2 path: "/:catchAll(.*)", // 全てのパスに対して 3 redirect: "/" 4 }

というルート設計を入れていたためおかしな挙動をしていたようです。

こちらを消すことで、一応意図通りに動くようにはなったと思うのですが、コンソールを確認すると

console

1vue-router.mjs:35 [Vue Router warn]: No match found for location with path "/"

というワーニングが発生しています。恐らく、常にどちらのルーティングも指定のURLを探しており、例えば"/"のpathの一般ユーザーのログイン画面にいる場合は、管理者のルーティングには"/"のpathがないためワーニングが出るのだと推測しています。

知りたいこと

結局知りたいことですが
一般的にこのようなルーティングを分けたい場合どのように実装するのでしょうか?
私の実装の仕方だと仕様上、回避できないワーニングだと思います。であればそもそも実装の仕方が悪いのだと考えています。
参考になる記事もなかなか見つからないので質問させていただきます。

該当のソースコード

html:index.html

1<body> 2 <div id="user-app"></div> 3 <div id="admin-app"></div> 4 <script type="module" src="/src/main.js"></script> 5</body>

JavaScript:main.js

1import { createApp } from 'vue' 2import App from './App.vue' 3import AdminApp from './adminApp.vue' 4import userRouter from './routes/userRouter' 5import adminRouter from "./routes/adminRouter"; 6 7const app = createApp(App) 8app.use(userRouter) 9app.mount('#user-app') 10 11const adminApp = createApp(AdminApp) 12adminApp.use(adminRouter) 13adminApp.mount('#admin-app')

JavaScript:userRouter.js

1import { createRouter, createWebHistory } from 'vue-router'; 2import Login from '../views/user/Login.vue'; 3import Survey from '../views/user/Survey.vue'; 4import Signup from '../views/user/Signup.vue'; 5import { checkAuth, checkExpiration } from '../controller/user'; 6 7const routes = [ 8 { 9 path: "/survey", 10 name: "Survey", 11 component: Survey, 12 meta: { 13 requiresAuth: true // このルートにはログインが必要 14 } 15 }, 16 { 17 path: "/", 18 name: "Login", 19 component: Login 20 }, 21 { 22 path: "/signup", 23 name: "Signup", 24 component: Signup 25 } 26] 27 28const router = createRouter({ 29 history: createWebHistory(), 30 routes: routes 31})

JavaScript:adminRouter.js

1import { createRouter, createWebHistory } from "vue-router"; 2import AdminLogin from "../views/admin/AdminLogin.vue"; 3import DashBoard from "../views/admin/DashBoard.vue"; 4 5const routes = [ 6 { 7 path: "/admin", 8 name: "/AdminLogin", 9 component: AdminLogin, 10 }, 11 { 12 path: "/admin/dashboard", 13 name: "/Dashboard", 14 component: DashBoard, 15 meta: { 16 requireAdmin: true, // 管理者は認証が必要 17 }, 18 } 19]; 20 21const router = createRouter({ 22 history: createWebHistory(), 23 routes: routes, 24}); 25

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

後日見直し。複数のidを置く方法はイレギュラーだったようなので、マニュアル通りに作ってみました。

一度設定したルーターオブジェクトに対しaddRouteメソッドで追加していく方法が正しいようです。ただ、addRouteメソッドは単一のルーティングしか追加できないようなので、ループ文を使って順次増やしてみました(公式マニュアルを見ても一つ一つ増やしていく書き方だったので)。

vue-router公式(英文)
Dynamic Routing

router.ts

1import { createRouter, createWebHistory } from 'vue-router'; 2import Login from '../user/Login.vue'; 3import Survey from '../user/Survey.vue'; 4import Signup from '../user/Singup.vue'; 5import AdminLogin from "../admin/AdminLogin.vue"; 6//import { checkAuth, checkExpiration } from '../controller/user'; 7import DashBoard from "../admin/DashBoard.vue"; 8 9//メインとなるルーター 10const routes = [ 11 { 12 path: "/", 13 component: Login 14 }, 15 { 16 path: "/survey", 17 component: Survey.default, 18 }, 19 { 20 path: "/signup", 21 component: Signup.default 22 } 23] 24 25//追加したいadminルーター 26const routes2 = [ 27 { 28 path: "/admin", 29 name: "Admin", 30 component: AdminLogin, 31 }, 32 { 33 path: "/admin/dashboard", 34 name: "/Dashboard", 35 component: DashBoard, 36 meta: { 37 requireAdmin: true, // 管理者は認証が必要 38 }, 39 } 40]; 41 42const router = createRouter({ 43 history: createWebHistory(), 44 routes: routes 45}) 46routes2.map((r,i)=>{ 47 router.addRoute(r) //addRouteで増やしていく 48 return r.fullPath //増やしたルートに対しパスを通す 49}) 50//router.replace(urouter.currentRoute.value.fullpath) //今回はいらないかも? 51 52export default router

main.ts

1import { createApp } from 'vue' 2import userApp from './user/userApp.vue' 3import AdminApp from './admin/adminApp.vue' 4import userRouter from './router/userRouter.ts' 5 6createApp(userApp).use(userRouter).mount('#app')

以下の方法は間違っていましたのでオミット

少しアレンジを加えて試してみたところ、createAppを複数作成しても対応できるようです。おそらくアプリケーションを構築するApp.vue上でルーティングがうまくつながっていない状態だと見受けられます。

投稿2023/04/20 06:07

編集2023/07/03 07:33
FKM

総合スコア3640

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nosuke09

2023/06/19 01:26

大変回答が遅くなりました。<router-view>はApp.vue、AdminApp共に記述しております。 回答者様の指摘の通りコメントアウトしてみると、ワーニングの内容は変わらないまま、画面も表示されなくなりました。 私の場合は<router-view>の記述を入れた上で片方にないルートにアクセスした場合このワーニングが表示されるのがどうしても気になっているのです。回答者様はルーティング設計をどの様にされたのでしょうか。 私は上記のコードに載せている通りの設計をしており、たとえば「/admin」のパスはadminRouterの方でしか記述していないのでこのパスに遷移するとuserRouterも反応し「/adminというパスはないよ〜」というエラーを出していると思っています。
nosuke09

2023/07/03 02:45

コンポーネントを指定するのでしょうか?自分が調べた限り、createWebHistoryのオプションを指定するとベースが指定できて、ベースからの相対パスになるという認識です。 また、パスを指定してみたのですが、ワーニングは変わりませんでした。回答者様の設計は私と同じなのでしょうか?
FKM

2023/07/03 03:02 編集

自分の書いたルーティングファイルはこのようになっています。 ```userRouter.ts const urouter = createRouter({ history: createWebHistory('user'), routes: routes }) export default urouter ``` ```adminRouter.ts const arouter = createRouter({ history: createWebHistory('admin'), routes: routes, }); export default arouter ``` ```ts:main.ts import userRouter from './router/userRouter' import adminRouter from './router/adminRouter' createApp(userApp).use(userRouter).mount('#userapp') createApp(AdminApp).use(adminRouter).mount('#adminapp') ```
nosuke09

2023/07/03 05:48

限りなく回答者様と同じ様な設計に思えますが、createWebHistoryに記述を追加してもワーニングが消えず、今度はadminの方にアクセスしようとしてURLにadmin/としてアクセスした際、自動補完の様なものが働き、user/adminとなってアクセスができなくなりました。 本当にお手数なのですが、routesの中身まで見せていただけないでしょうか? 最初にあったことなのですが、user,adminの両方のroutesの設計に'/' ルートのパスがあった時はエラーが出なかったので、どうしてだろうと探っていると、下にスクロールするとadminのページもレンダリングされていました。同じ様なことは起こってないでしょうか?
FKM

2023/07/03 07:35 編集

自分もViteでテストがてらアクセスしたら同じ現象が発生したので、不思議に思いもう一度見直したら公式マニュアルに正しい書き方が載っていました。それでテストしたらうまくいきました。
FKM

2023/07/03 07:35 編集

結論からいえば#appは2つ設けてはいけないようで、動作が不安定になります。なのでaddRouteで一つずつルーティングパスを増やしていくというやり方が正しいようです。
nosuke09

2023/07/05 02:32

タグを二つ生成するのはやはり設計上良くなかったのですね。ただ、ナビゲーションガードの仕様を一般ユーザーと管理者で分けたくてこの話をさせていただいたのですが、これは動的ルーティングとは若干話が違うのかと思います。一つのルートの中でナビゲーションガードを条件分岐させるくらいしか思いつかないのですがあまり賢い書き方には思えません。。
nosuke09

2023/07/08 02:31

meta: { requiresAuth: true, userType: 'admin' } この様な形でページにuserTypeの情報を設けてbeforeEachの中で条件分岐することで単一のrouterで設計することにしました。これが最適な形かは分かりませんがとりあえずこの方向でやってみます。 長々とありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問