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

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

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

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

1回答

620閲覧

Spring 画面遷移後もメニューの選択、開閉状態が維持されるようにしたい

ransuS_T

総合スコア106

Vue.js

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

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2023/11/19 04:05

実現したいこと

・メニュー選択後に選択したメニューがアクティブ状態(選択されたことがわかるように色が変わった状態)になるようにしたい
・開いたメニューが画面遷移後も維持された状態にしたい

現状の画面と理想の状態のイメージを添付いたします
現状のmain.htmlの表示内容
イメージ説明
データ管理画面1を選択し画面遷移
イメージ説明
理想とするデータ管理画面1への画面遷移
イメージ説明

前提

Java, Spring, vue.js, el-element を用いたWebアプリ開発を行っていたところ
上記の実装方法で行き詰ってしまったためご質問させてください。

おそらく PageController で mav.addObject() を使用して
画面上にパラメータを渡してあげることでの実現も可能と考えておりますが
今回はできれば PageController から渡すことなく実現可能な方法があればと考えております。

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

メニューから遷移先画面を選択すると、本来は選択されたメニュー名が
アクティブ状態(色が変わって選択されたことがわかるように)なるのですが
画面遷移されたことで vue の変数がリセットされてしまい選択状態がリセットされてしまう

該当のソースコード

現在開発中のプログラムそのまま載せるのは難しいため一部書き換えさせていただいております
その関係でそのままの使用はできないことがあるかもしれません。

header.html

1<html xmlns:th="http://www.thymeleaf.org"> 2 <head th:fragment="meta_header(title,link,script)"> 3 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 4 5 <!-- 共通で読み込む css と js ファイル --> 6 <script th:src="@{/webjars/jquery/jquery.min.js}"></script> 7 <script th:src="@{/webjars/vue/vue.js}"></script> 8 <script th:src="@{/webjars/swiper/js/swiper.js}"></script> 9 <script th:src="@{/webjars/momentjs/moment.js}"></script> 10 <script th:src="@{/webjars/element-ui/lib/index.js}"></script> 11 <script th:src="@{/webjars/element-ui/lib/umd/locale/ja.js}"></script> 12 <link rel="stylesheet" th:href="@{/webjars/element-ui/lib/theme-chalk/index.css}"/> 13 14 <script th:src="@{/js/common.js}"></script> 15 <link rel="stylesheet" th:href="@{/css/style.css}"/> 16 <link rel="stylesheet" th:href="@{/css/menu.css}"/> 17 18 <!-- 表示するタイトル --> 19 <title th:text="${title}"></title> 20 21 <!-- 各htmlで読み込む css と js ファイル --> 22 <th:block th:replace="${link} ?: _"/> 23 <th:block th:replace="${scripts} ?: _"/> 24 </head> 25</html>

template.html

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org" th:fragment="meta_body(title,body,link,script)"> 3 <head th:replace="common/header :: meta_header(${title},~{::link},~{::script})"> 4 </head> 5 <body> 6 <div class="header">タイトル</div> 7 <div id="app"> 8 <!-- menu テンプレート表示 --> 9 <div id="menu" class=menu> 10 <el-menu default-active="1" :default-active="targetMenu" active-text-color="#ffd04b"> 11 <el-submenu v-for="(menu, mIndex) in menus" :index="String(mIndex)" :title="menu" :key="mIndex"> 12 <template slot="title"> 13 <i :class= "menu.icon"></i> 14 {{menu.name}} 15 </template> 16 <el-menu-item-group> 17 <el-menu-item v-for="(submenu, sIndex) in menu.submenus" :index="mIndex + '-' + sIndex" :key="mIndex + '-' + sIndex" @click="pageMove(mIndex + '-' + sIndex, submenu.url)"> 18 {{submenu.name}} 19 </el-menu-item> 20 </el-menu-item-group> 21 </el-submenu> 22 </el-menu> 23 </div> 24 25 <!-- 各ページ本体 --> 26 <div th:replace="${body}"></div> 27 28 </div> 29 </body> 30 <script type="application/javascript" th:inline="javascript"> 31 /*<![CDATA[*/ 32 let bodyFunc = new Vue({ 33 el: '#menu', 34 data: { 35 targetMenu: null, 36 menus: [ 37 // メニュー 38 { 39 name: 'メイン', 40 icon: 'el-icon-house', 41 submenus: [ 42 {name: 'メイン画面',url: 'main'} 43 ], 44 }, 45 { 46 name: 'データ管理', 47 icon: 'el-icon-s-order', 48 submenus: [ 49 {name: 'データ管理画面1',url: 'test1'}, 50 {name: 'データ管理画面2',url: 'test2'}, 51 {name: 'データ管理画面3',url: 'test3'}, 52 {name: 'データ管理画面4',url: 'test4'} 53 ] 54 }, 55 { 56 name: 'データアップロード', 57 icon: 'el-icon-upload', 58 submenus: [ 59 {name: 'データアップロード',url: 'upload'} 60 ] 61 } 62 ] 63 }, 64 methods: { 65 pageMove(index, url) { 66 this.targetMenu = index; 67 window.location.href = url; 68 } 69 } 70 }) 71 /*]]>*/ 72 </script> 73</html>

main.html

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org" th:replace="common/template :: meta_body('メイン',~{::body/content()},~{::link},~{::script})"> 3 <body> 4 </body> 5</html>

test1.html

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org" th:replace="common/template :: meta_body('test1',~{::body/content()},~{::link},~{::script})"> 3 <head> 4 <link rel="stylesheet" th:href="@{/css/datalist/test1.css}"/> 5 <link rel="stylesheet" th:href="@{/css/components/tableComponent.css}"/> 6 </head> 7 <body> 8 <div id="content"> 9 10 </div> 11 <script type="application/javascript" th:inline="javascript"> 12 /*<![CDATA[*/ 13 new Vue({ 14 el:'#content', 15 data: { 16 }, 17 methods: { 18 }, 19 // 画面初期表示時処理 20 created() { 21 } 22 }) 23 /*]]>*/ 24 </script> 25 </body> 26</html>

PageControoller.java

1@Controller 2public class PageController { 3 4 @RequestMapping(value="/main", method=RequestMethod.GET) 5 public ModelAndView mainDisp(ModelAndView mav) { 6 mav.setViewName("main"); 7 return mav; 8 } 9 10 @RequestMapping(value="/test1", method=RequestMethod.GET) 11 public ModelAndView equipSearchDisp(ModelAndView mav) { 12 mav.setViewName("dataManagementPage/test1"); 13 return mav; 14 } 15 16 @RequestMapping(value="/test2", method=RequestMethod.GET) 17 public ModelAndView equipLevelSearchDisp(ModelAndView mav) { 18 mav.setViewName("dataManagementPage/test2"); 19 return mav; 20 } 21 22 @RequestMapping(value="/test3", method=RequestMethod.GET) 23 public ModelAndView abilitySearchDisp(ModelAndView mav) { 24 mav.setViewName("dataManagementPage/test3"); 25 return mav; 26 } 27 28 @RequestMapping(value="/test4", method=RequestMethod.GET) 29 public ModelAndView skillPointSearchDisp(ModelAndView mav) { 30 mav.setViewName("dataManagementPage/test4"); 31 return mav; 32 } 33 34 @RequestMapping(value="/xmlFileUploadPage", method=RequestMethod.GET) 35 public ModelAndView xmlFileUploadDisp(ModelAndView mav) { 36 mav.setViewName("xmlFileUploadPage/upload"); 37 return mav; 38 } 39}

試したこと

現行 window.location を使用しての遷移を ajax 等を使用して コンテンツ部分のみの画面遷移
(header.html と template.html が書き換えられることなく遷移する方法)を実現できないか調査中

補足情報(FW/ツールのバージョンなど)

Java15
Spring 2.4.1
element-ui 2.14.0
vue 2.6.11
webjars-locator 0.34

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

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

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

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

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

shiketa

2023/11/20 00:14 編集

template.htmlのmenuを、sessionStorageで管理すればいいのでは?たとえば。 * https://developer.mozilla.org/ja/docs/Web/API/Window/sessionStorage 1. keyを決めてsessionStorageからメニュー定義を取得する。取得できないときは初期状態としていまの実装の中身を採用する。 1. メニューを表示する。表示するとき現在のURLとメニュー項目のURLが一致するならアクティブ状態にする 1. リンクをクリックされたり、枝の状態が変わった状態を検知(@click?)して、メニュー定義を更新しsessionStorageに書き込む 1. 画面遷移したら、最初に戻る
ransuS_T

2023/11/20 10:13

まずはコメントいただきありがとうございます。 こちら試してみます
guest

回答1

0

自己解決

shiketa 様から教えていただいた方法で実現できました。
ありがとうございます。

template.html

1<!DOCTYPE html> 2<html xmlns:th="http://www.thymeleaf.org" th:fragment="meta_body(title,body,link,script)"> 3 <head th:replace="common/header :: meta_header(${title},~{::link},~{::script})"> 4 </head> 5 <body> 6 <div class="header">タイトル</div> 7 <div id="app"> 8 <!-- menu テンプレート表示 --> 9 <div id="menu" class=menu> 10 <el-menu :default-active="targetMenu" active-text-color="#ffd04b" :default-openeds="menuOpeneds" @open="submenuOpen" @close="submenuClose"> 11 <el-submenu v-for="(menu, mIndex) in menus" :index="String(mIndex)" :title="menu" :key="mIndex"> 12 <template slot="title"> 13 <i :class= "menu.icon"></i> 14 {{menu.name}} 15 </template> 16 <el-menu-item-group> 17 <el-menu-item v-for="(submenu, sIndex) in menu.submenus" :index="mIndex + '-' + sIndex" :key="mIndex + '-' + sIndex" @click="pageMove(mIndex + '-' + sIndex, submenu.url)"> 18 {{submenu.name}} 19 </el-menu-item> 20 </el-menu-item-group> 21 </el-submenu> 22 </el-menu> 23 </div> 24 25 <!-- 各ページ本体 --> 26 <div th:replace="${body}"></div> 27 28 </div> 29 </body> 30 <script type="application/javascript" th:inline="javascript"> 31 /*<![CDATA[*/ 32 let bodyFunc = new Vue({ 33 el: '#menu', 34 data: { 35 targetMenu: null, 36 menuOpeneds:[], 37 menus: [ 38 // メニュー 39 { 40 name: 'メイン', 41 icon: 'el-icon-house', 42 submenus: [ 43 {name: 'メイン画面',url: 'main'} 44 ], 45 }, 46 { 47 name: 'データ管理', 48 icon: 'el-icon-s-order', 49 submenus: [ 50 {name: 'データ管理画面1',url: 'test1'}, 51 {name: 'データ管理画面2',url: 'test2'}, 52 {name: 'データ管理画面3',url: 'test3'}, 53 {name: 'データ管理画面4',url: 'test4'} 54 ] 55 }, 56 { 57 name: 'データアップロード', 58 icon: 'el-icon-upload', 59 submenus: [ 60 {name: 'データアップロード',url: 'upload'} 61 ] 62 } 63 ] 64 }, 65 methods: { 66 pageMove(index, url) { 67 sessionStorage['targetMenu'] = index; 68 sessionStorage['menuOpeneds'] = this.menuOpeneds.toString(); 69 window.location.href = url; 70 }, 71 submenuOpen(index) { 72 this.menuOpeneds.push(index); 73 }, 74 submenuClose(index) { 75 this.menuOpeneds = this.menuOpeneds.filter(n => n != index); 76 } 77 }, 78 // 初期表示時処理 79 created() { 80 81 // 画面遷移前のメニュー表示状態をセット 82 if (sessionStorage.length != 0 && sessionStorage.getItem('targetMenu') !== undefined) { 83 this.targetMenu = sessionStorage.getItem('targetMenu'); 84 } 85 if (sessionStorage.length != 0 && sessionStorage.getItem('menuOpeneds') !== undefined && sessionStorage.getItem('menuOpeneds') !== "") { 86 this.menuOpeneds = sessionStorage.getItem('menuOpeneds').split(","); 87 } 88 } 89 }) 90 /*]]>*/ 91 </script> 92</html>

投稿2023/11/20 12:31

編集2023/11/20 12:33
ransuS_T

総合スコア106

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問