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

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

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

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

JavaScript

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

Q&A

解決済

1回答

7649閲覧

Vue.jsで戻るを押したときにスクロールさせたい

aglkjggg

総合スコア769

Vue.js

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

JavaScript

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

1グッド

1クリップ

投稿2017/07/28 05:07

編集2017/07/28 05:14

前提

  • 環境準備方法

bash

1$ vue init webpack my-project 2$ cd my-project 3$ npm install 4$ npm run dev
  • Vue.js で下記2つの画面を用意しています。
  1. ユーザー一覧 (Users)
  2. ユーザー詳細 (UserDetail)

問題点

「戻る」を押したときに常に一番上に戻ってしまいます。

聞きたいこと

常に前のページのスクロール位置を記憶してその場所にスクロールさせたいです。

試したこと

  • scrollBehavior を実装した。

→ scrollBehavior が呼ばれない為効果がなかった。

ソースコード

  • /my-project/src/main.js

js

1import Vue from 'vue' 2import App from './App' 3import router from './router' 4 5Vue.config.productionTip = false 6 7/* eslint-disable no-new */ 8new Vue({ 9 el: '#app', 10 router, 11 template: '<App/>', 12 components: { App } 13}) 14
  • /my-project/src/router/index.js

js

1import Vue from 'vue' 2import Router from 'vue-router' 3import Users from '@/components/Users' 4import UserDetail from '@/components/UserDetail' 5 6Vue.use(Router) 7 8export default new Router({ 9 routes: [ 10 { path: '/users', name: 'Users', component: Users }, 11 { path: '/user/:id', name: 'UserDetail', component: UserDetail } 12 ], 13 scrollBehavior (to, from, savedPosition) { 14 console.log('scroll behavior') 15 if (savedPosition) { 16 console.log(savedPosition) 17 return savedPosition 18 } else { 19 return { x: 0, y: 0 } 20 } 21 } 22})
  • /my-project/src/App.vue

html

1<template> 2 <div id="app"> 3 <router-view></router-view> 4 </div> 5</template> 6 7<script> 8export default { 9 name: 'app' 10} 11</script>
  • /my-project/src/components/Users.vue

html

1<template> 2 <div class="users"> 3 <ul v-for="user in users" :key="user.id"> 4 <li><router-link :to="'/user/' + user.id">{{user.name}}</router-link></li> 5 </ul> 6 </div> 7</template> 8 9<script> 10import axios from 'axios' 11 12export default { 13 name: 'users', 14 data () { 15 return { 16 users: null 17 } 18 }, 19 methods: { 20 getUsers () { 21 var url = 'https://gist.githubusercontent.com/anonymous/f40a3124bf4885a6a97fe6506043e582/raw/32f3edb1239d5b806d586bbf9035138cdb73c401/users.json' 22 axios.get(url).then(x => { this.users = x.data }) 23 } 24 }, 25 mounted () { 26 this.getUsers() 27 } 28} 29</script>
  • /my-project/src/components/UserDetail.vue

html

1<template> 2 <div class="userDetail"> 3 <h1>ユーザー詳細</h1> 4 </div> 5</template> 6 7<script> 8export default { 9 name: 'userDetial' 10} 11</script>
daikitakaya👍を押しています

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

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

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

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

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

guest

回答1

0

自己解決

3点の問題がありました。

1. mode: 'history' でしか動かない

注意: この機能は HTML5 history モードでのみ動作します。

(以下の記事から抜粋)
https://router.vuejs.org/ja/advanced/scroll-behavior.html

つまり、/my-project/src/router/index.js を以下のようにする必要がありました。

js

1export default new Router({ 2 routes: [ ... ], 3 mode: 'history', 4})

また、HTML5 history モードにするとURLが
http://127.0.0.1:8080/#/users
から
http://127.0.0.1:8080/users
に変化します。

また、HTML5 history モードにするとWebサーバ側での設定が必要になります。
下記のドキュメントに詳細が書いてあります。
https://router.vuejs.org/ja/essentials/history-mode.html

2. usersが開かれるたびにJSONデータを取りに行っていた点

/my-project/src/main.js で一度だけJSONを取りに行きその後は再利用する必要がありました。
そもそもコンポーネントでデータを取りに行くのは良くないみたいです。

3. x = 1にする必要がある

savedPosition.x = 1にするとうまくいきました。
yを変えてもダメでした。
1じゃなくても10でも20でも519521のような適当な数でもOKでした。
なぜうまくいくのかは謎です…。
この savedPosition.x= 1 が不要なケースも有りました。謎です…。

js

1scrollBehavior (to, from, savedPosition) { 2 console.log('scroll behavior') 3 if (savedPosition) { 4 savedPosition.x = 1 5 return savedPosition 6 } else { 7 return { x: 0, y: 0 } 8 } 9}

変えたソースコード

  • /my-project/src/main.js

js

1import Vue from 'vue' 2import App from './App' 3import router from './router' 4 5Vue.config.productionTip = false 6 7import axios from 'axios' 8 9/* eslint-disable no-new */ 10new Vue({ 11 el: '#app', 12 router, 13 template: '<App/>', 14 components: { App }, 15 data () { 16 return { 17 users: null 18 } 19 }, 20 methods: { 21 getUsers () { 22 var url = 'https://gist.githubusercontent.com/anonymous/f40a3124bf4885a6a97fe6506043e582/raw/32f3edb1239d5b806d586bbf9035138cdb73c401/users.json' 23 axios.get(url).then(x => { this.users = x.data }) 24 } 25 }, 26 mounted () { 27 this.getUsers() 28 } 29})
  • /my-project/src/router/index.js

js

1import Vue from 'vue' 2import Router from 'vue-router' 3import Users from '@/components/Users' 4import UserDetail from '@/components/UserDetail' 5 6Vue.use(Router) 7 8export default new Router({ 9 routes: [ 10 { path: '/users', name: 'Users', component: Users }, 11 { path: '/user/:id', name: 'UserDetail', component: UserDetail } 12 ], 13 mode: 'history', 14 scrollBehavior (to, from, savedPosition) { 15 console.log('scroll behavior') 16 if (savedPosition) { 17 savedPosition.x = 1 18 return savedPosition 19 } else { 20 return { x: 0, y: 0 } 21 } 22 } 23})
  • /my-project/src/App.vue

変更なし

  • /my-project/src/components/Users.vue

js

1<template> 2 <div class="users"> 3 <div v-if="this.$parent.$parent.$data.users != null"> 4 <ul v-for="user in this.$parent.$parent.$data.users" :key="user.id"> 5 <li><router-link :to="'/user/' + user.id">{{user.name}}</router-link></li> 6 </ul> 7 </div> 8 </div> 9</template> 10 11<script> 12export default { 13 name: 'users' 14} 15</script>
  • /my-project/src/components/UserDetail.vue

変更なし

参考

http://notsleeeping.com/archives/2676

投稿2017/07/28 07:04

編集2017/07/28 07:55
aglkjggg

総合スコア769

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

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

aglkjggg

2018/06/10 14:49

1年ほどたち、ある程度Vueを利用したので追記します。 1.一番の問題は2でした。データ取得が完了するまで要素が無い為スクロールバーも消えて常に一番上にスクロールされたかのような動きになっていました。 2. 1が問題なので、scrollBehaviorを利用する必要はありませんでした。 3. this.$parent.$parent.$data.usersという書き方は見づらい。最悪。何個$parentを書いたか分からなくなる。 4. root要素はthis.$root.usersでアクセスできる。 5. そもそもroot要素にデータを置くのは良くない。StoreパターンやVuexを使うべき。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問