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

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

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

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

Q&A

1回答

1042閲覧

Vue.jsでコンポーネント内のメソッド使い回しがうまくいかない

ink88882

総合スコア24

Vue.js

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

0グッド

0クリップ

投稿2019/06/09 05:39

編集2019/06/09 11:04

困ってること

Vue.jsでサイトを作っており、
インスタンスごとに下記のようなメソッドを使って、ある程度スクロールするとイベントを発火するためのフラグ(isActive)をtrueにする処理を使っています。
(trueになると、isshowなりでコンテンツが現れます。今回その部分は割愛します)

vue

1new Vue({ 2 el:'app', 3 data:{ 4 scrollY:0, 5 isActive:false 6 }, 7 mounted(){ 8 window.addEventListener('scroll',this.handleScroll); 9 10 }, 11 methods: { 12 handleScroll() { 13 this.scrollY = window.scrollY; 14 if (this.scrollY >= 3000 //3000までウインドウがスクロールするとtrueに 15 this.isActive = true; 16 } 17 } 18} 19})

html

1<section class="app"> 2 <div v-show="isActive" > 3 <h1>ある程度スクロールすると現れるコンテンツ </h1> 4 </div> 5</section>

やりたいこと

今はこれを、インスタンスごとに書いて、
コンテンツの位置によって3000の部分(スクロールの値)を変えているのですが、
メンテナンス性がわるいので、methodsのところを1箇所に書き、それを使いまわしたいと思っています。

component化すればいいのかもしれませんが、
componentでtemplateを複数の場所で使う方法はわかるのですが、メソッドの使い回す方法がわかりません。。(公式「https://jp.vuejs.org/v2/guide/components.html」にはコンポーネントでもmethods、オプションを受け入れます。とあるのでできるとは思うのですが。。)

さらに各インスタンス毎のコンテンツの位置も伝えたいのです。

自分で試したこと

こんな感じで試しに書いてみましたが、、コンソール上、

[Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <MoveTest>
<Root>

というエラーになってしまいます。

html

1<div id="test"> 2 <move-test><span v-show="isActive">ここが動くか</span></move-test> 3</div>

vue

1//コンポーネント 2Vue.component('move-test', { 3 props:['position'], 4 mounted(){ 5 window.addEventListener('scroll',this.handleScroll); 6 }, 7 methods: { 8 handleScroll() { 9 this.scrollY = window.scrollY; 10 if (this.scrollY >= position){ 11 this.isActiveup = true; 12 }else{ 13 this.isActive = false; 14 } 15 } 16 } 17}) 18 19new Vue({ 20 el:'#test', 21 data:{ 22 position:2000, 23 isActive:false 24 } 25 }) 26

何か誤っているのか、もしくはそもそも
スクロール時に複数のコンテンツに動きをつけたいなら、もう少し違う方法がないか、などアドバイスいただけますと幸いです。

追記:

<div id="test"> <move-test><span v-show="isActive">ここが動くか</span></move-test> </div> <div id="test2"> <move-test><span v-show="isActive">ここも動くか</span></move-test> </div>

というコンテンツを記載したい時に、
test1とtest2をインスタンス化した時に、それぞれを共通したメソッド(ただし発火のタイミングはtest1.2で異なる)で使う方法があればと思っています。

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

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

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

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

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

guest

回答1

0

間違いだらけなので何が誤っているのかについての
詳細な説明は割愛します。

動作するコードを記載しましたので、こちらのコードと
公式サイトのコンポーネントの基本を見ていただければ
何が問題だったかご理解いただけるかと。

CSS

1body { 2 height: 4000px; 3} 4#test { 5 position: fixed; 6}

HTML

1<div id="test"> 2 <move-test></move-test> 3</div> 4<script src="https://unpkg.com/vue"></script> 5<script> 6//コンポーネント 7Vue.component('move-test', { 8 data() { 9 return { 10 position: 2000, 11 isActive: false 12 } 13 }, 14 template: '<span v-show="isActive">ここが動くか</span>', 15 methods: { 16 handleScroll() { 17 console.log(window.scrollY); 18 if (window.scrollY >= this.position) { 19 this.isActive = true; 20 } else { 21 this.isActive = false; 22 } 23 } 24 }, 25 mounted() { 26 window.addEventListener('scroll', this.handleScroll); 27 } 28}); 29 30new Vue({ 31 el: "#test" 32}); 33</script>

投稿2019/06/09 10:52

yasutomi

総合スコア2937

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

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

ink88882

2019/06/09 11:22

コメントありがとうございます! 「やりたいこと」が説明不足で申し訳ありません。 これであれば動くこと自体はできるかと思うのですが、 2つ目、3つ目のコンテンツで同じメソッド(同じコンポーネント)の使い回しをする際にはコンポーネント側で値を持ってしまうと、全てposition:2000の位置で発火してしまい、 また、templateの内容をコンポーネント側で持ってしまうと、違うコンテンツの記述ができず。。 例:コンテンツ1と2で異なる文章を記載しており、 コンテンツ1はスクロール値1000で、 コンテンツ2はスクロール値2000で動くようなことができればと思っております。 追記を記載いたしましたので、もし方法があればご教授いただけますと助かります。
yasutomi

2019/06/09 11:49

propsを使用すれば可能です。 詳細は公式サイトのコンポーネントの基本をご確認ください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問