【问题标题】:Vue scroll element into view after it is shown显示后Vue滚动元素进入视图
【发布时间】:2021-08-06 08:15:04
【问题描述】:

我有一个表格,可以计算 2 个值,然后显示结果卡。在所有的值都填写并提交之前,不会显示结果卡(使用v-if)。

我将 Vuetify 用于 UI 框架。

这是我尝试过的:

<template>
  <v-container>
    <v-row class="mt-2" justify="center">
      <v-col cols="12" sm="8" md="6">
        <v-form ref="form" @submit.prevent="onSubmit">
          <v-row class="mb-1">
            <v-col cols="6">
        
              <v-select
                v-model="fighter1"
                :items="fighters"
                item-text="name"
                item-value="id"
                return-object
                label="Player 1"
                :rules="[(v) => !!v || 'Required.']"
              />
            </v-col>

            <v-col cols="6">
  
              <v-select
                v-model="fighter2"
                :items="fighters"
                item-text="name"
                item-value="id"
                return-object
                label="Player 2"
                :rules="[(v) => !!v || 'Required.']"
              />
            </v-col>
          </v-row>

          <!-- This is the submit button -->
          <ReadyToFight />
        </v-form>
      </v-col>
    </v-row>

    <v-row>
      <v-col>

        <!-- This is the result card -->
        <v-card v-if="result" id="result" class="pb-2">
          <h1 class="text-center text-uppercase result-score">{{ result }}</h1>
          <h2 class="text-center text-uppercase result-text">
            {{ resultText }}
          </h2>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script lang="ts">
import { Fighter, fighters } from '@/data/fighters'
import matchupsChart from '@/data/matchups'
import Vue from 'vue'
import { MatchupTypes, toResult } from '~/data/matchupTypes'

type IndexPageType = {
  fighters: Fighter[]
  fighter1: Fighter | undefined
  fighter2: Fighter | undefined
  result: MatchupTypes | undefined
}

export default Vue.extend({
  name: 'IndexPage',
  data(): IndexPageType {
    return {
      fighters,
      fighter1: undefined,
      fighter2: undefined,
      result: undefined
    }
  },
  computed: {
    resultText(): string {
      if (this.result) return toResult(this.result)
      return `Can't get result`
    }
  },
  
  // I tried watching the result
  // So after the result changed it will scroll
  watch: {
    result(newResult) {
      if (newResult) document.querySelector('#result')?.scrollIntoView()
    }
  },
  methods: {
    onSubmit() {
      ;(this.$refs.form as any).validate()
      if (this.fighter1 && this.fighter2) {
        this.result = matchupsChart
          .get(this.fighter1.id)
          ?.get(this.fighter2.id) as MatchupTypes
      }
    }
  }
})
</script>

基本上我尝试做的是:
观看result,如果变为truthy,则scrollIntoView()

但这不起作用,因为我认为 result 先发生变化,然后元素才会被渲染。

有人知道我该怎么做吗?

【问题讨论】:

    标签: javascript vue.js vuejs2 vuetify.js


    【解决方案1】:

    这是因为当观察者被触发时,元素#result 尚未在实际 DOM 中呈现。在尝试将元素滚动到视图中之前,您需要等待 this.$nextTick() 以确保 DOM 确实已更新,即:

    watch: {
        result(newResult) {
            if (newResult) {
                this.$nextTick().then(() => document.querySelector('#result')?.scrollIntoView());
            }
        }
    },
    

    如果你熟悉 async/await,你也可以这样做:

    watch: {
        async result(newResult) {
            if (newResult) {
                await this.$nextTick();
                document.querySelector('#result')?.scrollIntoView();
            }
        }
    },
    

    【讨论】:

      猜你喜欢
      • 2013-12-08
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-01
      • 2022-01-16
      • 2020-12-29
      相关资源
      最近更新 更多