2017-05-30 5 views
1

チャットスタイルフォームを作成しようとしています。そのため、ユーザーはデータを入力してから、テンプレート内のボタンをcontinue-btnのクラスで使用します。Vue.jsがquerySelectorを使用して要素を見つけることができません

continue-btnを押すと、nextStepメソッドが使用され、counterデータプロパティに1が追加されます。

テンプレート内では、v-if="counter >= 1"を使用して、チャットダイアログと入力フィールドの次のセクションを表示します。

次に、scrollTopを使用して、ページを新しいセクションに自動的にスクロールし、IDが#conversation__tram-1であるようにしようとしています。私はもともとcounterが1の値を与えられていた直後のコードブロックを実行してみました:

const container = this.$el.querySelector("#conversation__tram-" + this.counter); 
container.scrollTop = container.scrollHeight; 

私は#conversation__tram-1要素はまだDOMに追加されていない推測しているので、これはかかわらず動作しませんでした。

だから私はタイムアウト機能でそれをラップしようとしたテストのために:

setTimeout(function(){ 
    const container = this.$el.querySelector("#conversation__tram-" + this.counter); 
    container.scrollTop = container.scrollHeight; 
    }, 3000); 

このしようとしたとき、私はこのエラーが残っていますが:ここ

Uncaught TypeError: Cannot read property 'querySelector' of undefined 

は私の全体の単一VUEですファイル:

<template> 

    <div id="conversation-app"> 
     <!-- <div v-for="item in items"> 
     {{ item.text }} 
     </div> --> 
     <div class="conversation__track"> 
     <div id="conversation__tram-0"> 
      <div class="conversation__item agent"> 
      <img src="/assets/cdn.annuityadvicecentre.dev/images/theme-f/michael-chat-agent.jpg" class="conversation__item-prof-img" alt="Michael Chat Agent" /> 
      <div class="conversation__item-content"> 
       <p> 
       Hello my name is {{ agent }}, we'll compare the whole annuity market to bring you back the best annuity rates from the top providers for you. Let's get started, what's your name? 
       </p> 
      </div> 
      </div> 
      <div class="conversation__item customer" id="title-fullname"> 
      <div class="conversation__item-content"> 
       <p> 
       Hi {{ agent }}, my name is... 
       </p> 
       <div class="row"> 
       <div class="col-4"> 
        <select id="title" class="field-title" name="payload[title]"><option value="mr">Mr</option><option value="mrs">Mrs</option><option value="miss">Miss</option><option value="ms">Ms</option></select> 
       </div> 
       <div class="col-8"> 
        <input v-model="customerName" id="full_name" class="field-full_name" name="payload[full_name]" type="text"> 
       </div> 
       </div> 
      </div> 
      </div> 
     </div> 
     <transition name="fade"> 
      <div id="conversation__tram-1" v-if="counter >= 1"> 
      <div class="conversation__item agent"> 
       <img src="/assets/cdn.annuityadvicecentre.dev/images/theme-f/michael-chat-agent.jpg" class="conversation__item-prof-img" alt="Michael Chat Agent" /> 
       <div class="conversation__item-content"> 
       <p> 
        Thanks {{ firstName }}, nice to meet you. To process your instant quote please can I have your Pension Value? 
       </p> 
       </div> 
      </div> 
      <div class="conversation__item customer"> 
       <div class="conversation__item-content"> 
       <p> 
        Sure, my pension value is... 
       </p> 
       <input id="pension_value" class="field-pension_value" placeholder="£" pattern="\d*" name="payload[pension_value]" type="number"> 
       <div class="error-wrap error_pension_value is-hidden" data-format="<div class=&quot;error-text&quot;>:message</div>"></div> 
       </div> 
      </div> 
      </div> 
     </transition> 
     <div id="conversation__buttons"> 
      <button type="button" class="continue-btn" 
      v-on:click="nextStep" 
      >Continue&nbsp;<i class="fa fa-chevron-right" aria-hidden="true"></i></button> 
     </div> 
     </div> 
    </div> 
</template> 

<script> 
export default { 
    name: 'conversation-app', 
    data() { 
    return { 
     agent: 'Brick', 
     counter: 0, 
     customerName: '', 
    } 
    }, 
    methods: { 
    nextStep: function() { 
     this.counter += 1; 
     setTimeout(function(){ 
     const container = this.$el.querySelector("#conversation__tram-" + this.counter); 
     container.scrollTop = container.scrollHeight; 
     }, 3000); 

    }, 
    }, 
    computed: { 
    firstName() { 
     return this.customerName.split(' ')[0]; 
    } 
    } 
} 
</script> 

なぜこれが機能しないのでしょうか?ありがとう。

答えて

1

これは、thisのコンテキストを保持するので、矢印関数を使用するのに適しています。

nextStep: function() { 
    this.counter += 1; 
    setTimeout(() => { 
    const container = this.$el.querySelector("#conversation__tram-" + this.counter); 
    container.scrollTop = container.scrollHeight; 
    }, 3000); 

代わりにあなたがこれを行うための、より技術的に正しい方法であるVue.nextTickを使用することができ、タイムアウトのAltenatively、。

nextStep: function() { 
    this.counter += 1 
    this.$nextTick(() => { ... }) 
+0

ありがとう、この例では、要素の下端までスクロールしていないが、要素を選択できるようになりました。どんな考え?エラーなしで何も起こっていないようです。 –

+0

簡単にするために 'container.scrollTop = 0'を使ってみましたが、これはうまくいきません。私はあなたが言及したようにVue.nextTickを使用しました。 –

+0

'container.scrollTop'と' container.scrollHeight'の値を 'console.log'してみて、それらが何であるかを確認してください。また、 '#conversation__tram-x'要素がスクロールしたい_actual_要素であることを確認してください。 – varbrad

関連する問題