2017-05-30 2489 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); 

Altenatively,而不是超时可以使用Vue.nextTick是这样做的更多技术上正确的方法。

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

感谢这个例子现在允许我选择元素,但它不滚动到元素的底部。任何想法为什么?没有错误似乎没有发生。 –

+0

为了简单起见,我也试过使用'container.scrollTop = 0',这也不起作用。我已经使用了像你提到的Vue.nextTick。 –

+0

试着'console.log'' container.scrollTop'和'container.scrollHeight'的值,检查它们是什么。还要确保'#conversation__tram-x'元素是您想要滚动的_actual_元素。 – varbrad