Javascript Vue页面没有';装载时不要向下滚动

Javascript Vue页面没有';装载时不要向下滚动,javascript,html,firebase,vue.js,dom,Javascript,Html,Firebase,Vue.js,Dom,我很难在加载时使页面向下滚动到最新消息。我有同样的功能,当一个人发送一条新消息时,页面会在发送后直接向下滚动到最新消息。 我尝试了一些方法,比如scrollIntoView,甚至将scrollTop设置为9999。但是,当我在控制台上记录scrollTop时,它仍然指示它为0。在创建消息后,在mounted中调用该函数。 有谁能帮助我为什么它不工作?非常感谢你的帮助,谢谢 <v-container> <div id="top-nav"> &

我很难在加载时使页面向下滚动到最新消息。我有同样的功能,当一个人发送一条新消息时,页面会在发送后直接向下滚动到最新消息。 我尝试了一些方法,比如scrollIntoView,甚至将scrollTop设置为9999。但是,当我在控制台上记录scrollTop时,它仍然指示它为0。在创建消息后,在mounted中调用该函数。 有谁能帮助我为什么它不工作?非常感谢你的帮助,谢谢

<v-container>
  <div id="top-nav">
    <v-avatar id="avatar">
      <img src="../../public/img/icons/myavatar.png" alt="avatar">
    </v-avatar>
    <div id="title-grp">
      <h3 id="sofia-title">Sofia</h3>
      <div id="online-grp">
        <span id="online-circle"></span>
        <p id="online-text">Online</p>
      </div>
    </div>
  </div>
  <div id="msg-container">
    <v-row dense>
      <v-col cols="12">
        <v-card
          style="width: fit-content"
          v-for="(message,index) in messages"
          :key="index"
          :style="{'margin-left': message.isRobot ? '' : 'auto'}"
          :color="message.isRobot? '#F5F3FF' :'#C66BCC'" 
          id="convo-space"
        >
          <p id="timestamp" :style="{'color': message.isRobot? '#808080' : '#000000'}">{{message.timestamp}}</p>
          <v-card-text
            :style="{'color': message.isRobot ? 'black' : 'white', 'font-size': '16px'}"
          >
            {{message.text}}
          </v-card-text>

        </v-card>
        <div id="bottom-scroll" ref="last-message"></div>   
      </v-col>
    </v-row>
  </div>    

  <div id="bottom-container">
    <div class="col-text">
      <input type="text" placeholder="Type here" id="text-input" v-model="userMessage">
    </div>
    <div class="col-btn">
      <button @click="sendMessage" id="btn-color-text"> Send </button>
    </div>
  </div>
</v-container>
        

</template>

<script>

  import {config} from "../config.js"
  const token = config.dialogflow.clientBot;

  import { ApiAiClient } from 'api-ai-javascript';
  const client = new ApiAiClient({accessToken: token});

  import { mapGetters } from "vuex";

  import firebase from "firebase";

  export default {
    data: () => ({
      messages: [],
      userMessage: "", 
    }),
    methods: {
      sendMessage(){
        var timestamp = new Date().toLocaleTimeString(undefined, {hour: '2-digit', minute: '2-digit'});
        const usrMessage = {
          text: this.userMessage,
          isRobot: false,
          timestamp: timestamp
        };

        this.messages.push(usrMessage);

        client.textRequest(this.userMessage).then((response) => {
          const robotMessage = {
            text: response.result.fulfillment.speech,
            isRobot: true,
            timestamp: timestamp
          };

          firebase
          .firestore()
          .collection("users")
          .doc(firebase.auth().currentUser.uid)
          .collection("messages")
          .add({
            userMessage: usrMessage.text,
            robotMessage: robotMessage.text,
            timestamp: timestamp 
          });

          const delay = ms => new Promise(res => setTimeout(res,ms));

          const pushMsg = async () => {
            let randNum = Math.floor(Math.random() * 8000);
            await delay(randNum);
            await this.messages.push(robotMessage);
            this.scrollToEnd();
          };

          pushMsg();
          this.scrollToEnd();
        });
          


        this.userMessage = "";
        console.log(firebase.auth().currentUser.uid);
      },
      scrollToEnd(){
        var container = this.$el.querySelector('#msg-container');
        container.scrollTop = container.scrollHeight;
        console.log(container.scrollHeight);
        console.log(container.scrollTop);
      }
    },

    created(){
      var oldMessages = [];

      firebase
      .firestore()
      .collection("users")
      .doc(firebase.auth().currentUser.uid)
      .collection("messages")
      .get()
      .then( (querySnapshot) => {
        querySnapshot.forEach(function(doc){
          var snapMsg = doc.data();
          let robot = {
            text: snapMsg.robotMessage,
            timestamp: snapMsg.timestamp,
            isRobot: true
          }

          let human = {
            text: snapMsg.userMessage,
            timestamp: snapMsg.timestamp,
            isRobot: false
          }
          
          oldMessages.unshift(human, robot);
          });
          this.messages = oldMessages;
          });
    },
    mounted(){
      var bottomDiv = this.$el.querySelector('#bottom-scroll');
      bottomDiv.scrollIntoView();
      console.log(bottomDiv);
      console.log(bottomDiv.scrollIntoView());

      // var bottomDiv = this.$el.querySelector('#msg-container');
      // bottomDiv.scrollTop = 9999;      
      // console.log(bottomDiv.scrollTop);

      navigator.serviceWorker.addEventListener('message', (e) => {
        console.log('Push Notification received');
        console.log(e.data.firebaseMessagingData.notification.body);
        var timestamp = new Date().toLocaleTimeString(undefined, {hour: '2-digit', minute: '2-digit'});
        const robotMessage = {
          text: e.data.firebaseMessagingData.notification.body,
          isRobot: true,
          timestamp: timestamp
        }
        firebase
        .firestore()
        .collection("users")
        .doc(firebase.auth().currentUser.uid)
        .collection("messages")
        .add({
          robotMessage: robotMessage.text,
          timestamp: robotMessage.timestamp
        });

        this.messages.push(robotMessage);
      });
    },
    computed: {
      ...mapGetters({
        user: "user"
      })
    }
  }
</script> ```

索非亚

在线

{{message.timestamp}

{{message.text} 发送 从“./config.js”导入{config} const token=config.dialogflow.clientBot; 从“api ai javascript”导入{APAIClient}; const client=new apaiclient({accessToken:token}); 从“vuex”导入{mapGetters}; 从“firebase”导入firebase; 导出默认值{ 数据:()=>({ 信息:[], 用户消息:“”, }), 方法:{ sendMessage(){ var timestamp=new Date(); 常量usrMessage={ text:this.userMessage, 以色列机器人:错, 时间戳:时间戳 }; this.messages.push(usrMessage); client.textRequest(this.userMessage).then((response)=>{ const robotMessage={ 文本:response.result.fulfillment.speech, 是的, 时间戳:时间戳 }; 火基 .firestore() .收集(“用户”) .doc(firebase.auth().currentUser.uid) .收集(“信息”) .添加({ userMessage:usrMessage.text, robotMessage:robotMessage.text, 时间戳:时间戳 }); const delay=ms=>newpromise(res=>setTimeout(res,ms)); const pushMsg=async()=>{ 设randNum=Math.floor(Math.random()*8000); 等待延迟(randNum); 等待。消息。推送(机器人消息); 这个.scrollToEnd(); }; pushMsg(); 这个.scrollToEnd(); }); this.userMessage=“”; log(firebase.auth().currentUser.uid); }, scrollToEnd(){ var container=this.$el.querySelector(“#msg container”); container.scrollTop=container.scrollHeight; console.log(container.scrollHeight); console.log(container.scrollTop); } }, 创建(){ var oldMessages=[]; 火基 .firestore() .收集(“用户”) .doc(firebase.auth().currentUser.uid) .收集(“信息”) .get() .然后((querySnapshot)=>{ querySnapshot.forEach(函数(doc){ var snapMsg=doc.data(); 让机器人={ 文本:snapMsg.robotMessage, 时间戳:snapMsg.timestamp, 以色列机器人:是的 } 让人类={ 文本:snapMsg.userMessage, 时间戳:snapMsg.timestamp, isRobot:false } 旧消息。取消移动(人类、机器人); }); this.messages=旧消息; }); }, 安装的(){ var bottomDiv=this.$el.querySelector(“#底部滚动”); bottomDiv.scrollIntoView(); 控制台日志(bottomDiv); log(bottomDiv.scrollIntoView()); //var bottomDiv=this.$el.querySelector(“#msg container”); //bottomDiv.scrollTop=9999; //控制台日志(bottomDiv.scrollTop); navigator.serviceWorker.addEventListener('message',(e)=>{ log(“收到推送通知”); 日志(e.data.firebaseMessagingData.notification.body); var timestamp=new Date(); const robotMessage={ 文本:e.data.firebaseMessagingData.notification.body, 是的, 时间戳:时间戳 } 火基 .firestore() .收集(“用户”) .doc(firebase.auth().currentUser.uid) .收集(“信息”) .添加({ robotMessage:robotMessage.text, 时间戳:robotMessage.timestamp }); this.messages.push(robotMessage); }); }, 计算:{ …地图绘制者({ 用户:“用户” }) } } ```
发生的情况是,当数据已更新而DOM尚未更新时,您正试图更新UI。当使用nextTick更新Dom/Ui时,调用
scrollToEnd
,每当Dom更新时,都会调用vue nextTick

例如,您的代码

const pushMsg = async () => {
        let randNum = Math.floor(Math.random() * 8000);
        await delay(randNum);
        await this.messages.push(robotMessage);
        this.scrollToEnd();
      };
应该是

 let self= this;
 const pushMsg = async () => {
        let randNum = Math.floor(Math.random() * 8000);
        await delay(randNum);
        await this.messages.push(robotMessage);
  self.$nextTick(function(){
   this.scrollToEnd();
  })
        
      };

嘿,艾曼纽,谢谢你的回答。我试图实现你的建议,但似乎仍然不起作用:(检查,谢谢,伙计。它现在似乎起作用了。我在挂载中实现了nextTick,但不起作用。所以我看到了你的代码,你将nextTick放入了watched中,最后它起作用了。谢谢@emmanuel!@AhmadNurhadi不客气,请将其作为答案投票