I'm trying to rewrite a component for vue 3, more specifically to use their new setup script so that the code looks cleaner, this is what it currently looks like.
export default { name: "typeWriter", data: () => { return { typeValue: "", typeStatus: false, displayTextArray: ['Art', 'Science', 'Math', 'Everything'], typingSpeed: 70, erasingSpeed: 70, newTextDelay: 1000, displayTextArrayIndex: 0, charIndex: 0, }; }, created() { setTimeout(this.typeText, this.newTextDelay + 200); }, methods: { typeText() { if (this.charIndex < this.displayTextArray[this.displayTextArrayIndex].length) { if (!this.typeStatus) { this.typeStatus = true; } this.typeValue += this.displayTextArray[this.displayTextArrayIndex].charAt(this.charIndex); this.charIndex++; setTimeout(this.typeText, this.typingSpeed); } else { this.typeStatus = false; // stop the typing once we hit the last thing we wish to type. if (this.displayTextArrayIndex + 1 >= this.displayTextArray.length) { return } setTimeout(this.eraseText, this.newTextDelay); } }, eraseText() { if (this.charIndex > 0) { if (!this.typeStatus) { this.typeStatus = true; } this.typeValue = this.displayTextArray[this.displayTextArrayIndex].substring(0, this.charIndex - 1); this.charIndex -= 1; setTimeout(this.eraseText, this.erasingSpeed); } else { this.typeStatus = false; this.displayTextArrayIndex++; setTimeout(this.typeText, this.typingSpeed + 1000); } }, }, };
This is the new vue 3 code using
let typeValue = "" let typeStatus = false let displayTextArray = ['Art', 'Science', 'Math', 'Everything'] let typingSpeed = 70 let erasingSpeed = 70 let newTextDelay = 1000 let displayTextArrayIndex = 0 let charIndex = 0 setTimeout(typeText, newTextDelay); function typeText() { if (charIndex < displayTextArray[displayTextArrayIndex].length) { if (!typeStatus) { typeStatus = true; } typeValue += displayTextArray[displayTextArrayIndex].charAt(charIndex); charIndex++; setTimeout(typeText, typingSpeed); } else { typeStatus = false; // stop the typing once we hit the last thing we wish to type. if (displayTextArrayIndex + 1 >= displayTextArray.length) { return } setTimeout(eraseText, newTextDelay); } } function eraseText() { if (charIndex > 0) { if (!typeStatus) { typeStatus = true; } typeValue = displayTextArray[displayTextArrayIndex].substring(0, charIndex - 1); charIndex -= 1; setTimeout(eraseText, erasingSpeed); } else { typeStatus = false; displayTextArrayIndex++; setTimeout(typeText, typingSpeed + 1000); } }
The problem I have is that the vue 2 code will correctly update the div with the value in typeValue
, the new vue 3 code will not update the div, I added a console .log, you can see that the code is indeed firing and working, the div just doesn't recognize this change in typeValue
and I have absolutely no idea why this is happening.
I'm still new to vue 3, so maybe I'm missing something, but this looks correct to me, so I don't understand why the div isn't updating like it used to.
P粉6148403632024-01-11 16:33:07
Try using ref
to make the data reactive一个>:
const { ref } = Vue const app = Vue.createApp({ setup() { let typeValue = ref("") let typeStatus = false let displayTextArray = ['Art', 'Science', 'Math', 'Everything'] let typingSpeed = 70 let erasingSpeed = 70 let newTextDelay = 1000 let displayTextArrayIndex = ref(0) let charIndex = 0 setTimeout(typeText, newTextDelay); function typeText() { if (charIndex < displayTextArray[displayTextArrayIndex.value].length) { if (!typeStatus) { typeStatus = true; } typeValue.value += displayTextArray[displayTextArrayIndex.value].charAt(charIndex); charIndex++; setTimeout(typeText, typingSpeed); } else { typeStatus = false; if (displayTextArrayIndex.value + 1 >= displayTextArray.length) { return } setTimeout(eraseText, newTextDelay); } } function eraseText() { if (charIndex > 0) { if (!typeStatus) { typeStatus = true; } typeValue.value = displayTextArray[displayTextArrayIndex.value].substring(0, charIndex - 1); charIndex -= 1; setTimeout(eraseText, erasingSpeed); } else { typeStatus = false; displayTextArrayIndex.value++; setTimeout(typeText, typingSpeed + 1000); } } return { typeValue, eraseText, typeText }; }, }) app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> <div id="demo"> <input type="text" :value="typeValue" /> </div>