Vue/Nuxt 3 -无法设置null的属性(设置“textContent”)

d8tt03nd  于 2023-05-18  发布在  Vue.js
关注(0)|答案(3)|浏览(397)

我有一个功能,应该每隔几秒就改变一次单词。一切都按预期工作,但我在VSC控制台中每隔几秒就会收到以下错误:
TypeError:Cannot set properties of null(setting 'textContent')at Timeout._onTimeout(.../components/home/Hero.vue:36:28)at listOnTimeout(node:internal/timers:564:17)
我不明白为什么会出现这个错误,因为当我console.logword.value时,我得到了元素。所以我可以访问它并且功能正在工作,单词每隔几秒钟就会改变,正如预期的那样。我有点困惑,不知道如何解决这个问题。我没有得到谷歌Chrome控制台的错误,只有在VSC。

<span ref="word"></span>
onMounted(() => {
  randomizeText()
  wordChanger
})

onBeforeRouteLeave(() => {
  clearTimeout(wordChanger)
})

const wordChanger = setInterval(randomizeText, 4000)

const word = ref(null)
const words = reactive(['Word-1', 'Word-2'])
let i = 0

function randomizeText() {
  i = randomNum(i, words.length)
  const newWord = words[i]

  setTimeout(() => {
    word.value.textContent = newWord
  }, 200) // time to allow opacity to hit 0 before changing word
}

function randomNum(num, max) {
  let j = Math.floor(Math.random() * max)

  // ensure diff num every time
  if (num === j) {
    return randomNum(i, max)
  } else {
    return j
  }
}
t3irkdon

t3irkdon1#

而不是使用const word = ref(null)作为refs。您可以直接将其称为模板中的常量word。它应该还是一样的工作。

<template>
  <div>
    <span>{{ word }}</span>
  </div>
</template>

setTimeout函数中,将word.value.textContent = newWord更改为word.value = newWord
这是更新的代码。测试和它的工作。

<script setup lang="ts">
onMounted(() => {
  randomizeText()
  wordChanger
})

onBeforeRouteLeave(() => {
  clearTimeout(wordChanger)
})

const wordChanger = setInterval(randomizeText, 4000)

const word = ref('') // UPDATED
const words = reactive(['Word-1', 'Word-2'])
let i = 0

function randomizeText() {
  i = randomNum(i, words.length)
  const newWord = words[i]

  setTimeout(() => {
    word.value = newWord // UPDATED
  }, 200) // time to allow opacity to hit 0 before changing word
}

function randomNum(num, max) {
  let j = Math.floor(Math.random() * max)

  // ensure diff num every time
  if (num === j) {
    return randomNum(i, max)
  } else {
    return j
  }
}
</script>
<template>
  <div>
    <span>{{ word }}</span>
  </div>
</template>

希望对你有帮助。

gopyfrb3

gopyfrb32#

这可能是一个计时问题(当代码更改元素时,元素未被装入)
您可以在不直接设置textContent属性的情况下做到这一点,方法是使用v-html指令,只需更改引用的变量(ref)。

import {onMounted, reactive, ref} from "vue";
import {onBeforeRouteLeave} from "vue-router";

let wordChanger;

onMounted(() => {
    randomizeText()
    wordChanger = setInterval(randomizeText, 4000);
})

onBeforeRouteLeave(() => {
    clearTimeout(wordChanger)
})

let word = ref('Hoi')
const words = reactive(['Word-1', 'Word-2'])
let i = 0

function randomizeText() {
    i = randomNum(i, words.length)
    const newWord = words[i]

    setTimeout(() => {
        word.value = newWord
    }, 200) // time to allow opacity to hit 0 before changing word
}

function randomNum(num, max) {
    let j = Math.floor(Math.random() * max)

    // ensure diff num every time
    if (num === j) {
        return randomNum(i, max)
    } else {
        return j
    }
}
<span v-html="word"></span>
4ioopgfo

4ioopgfo3#

你可能用错了ref 'word',我在下面分享了一些其他细节:-注意:我在更改的行中添加注解,以帮助您更好地理解

setup() {
    

    const word = ref(null);
    const words = reactive(['Word-1', 'Word-2']);

    function randomizeText(i) {
      const p = randomNum(i, words.length);
      const newWord = words[p];

      setTimeout(() => {
        word.value = newWord;
      }, 200); // time to allow opacity to hit 0 before changing word
    }

    function randomNum(num, max) {
      let j = Math.floor(Math.random() * max);

      // ensure diff num every time
      if (num === j) {
        // notice here as well I use num instead of i
        return randomNum(num, max);
      } else {
        return j;
      }
    }
    
    const wordChanger = setInterval(randomizeText, 4000);
    
    onMounted(() => {
      randomizeText(0); // start with 0
      // wordChanger; // no need using this here
    });

    onBeforeRouteLeave(() => {
      clearTimeout(wordChanger);
    });

    return {
      word,
    };
  },
<span>{{ word }}</span>

这里有一个演示:-https://stackblitz.com/edit/vue-rap7bb?file=src/components/HelloWorld.vue

相关问题