Vue 3: 如何使用 Watch/WatchEffect 在 Typed.js 短语完成时触发消息?



我有一些 Vue 2 代码,我正在尝试升级到 Vue 3,但我在Typed.js库的实例上遇到了很多麻烦。这是我在 Vue 2 中拥有的最小工作示例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CDN with Vue 2</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>Here's the typed phrase:</h1>
<h2 id="typing"></h2>
<div v-if="showMessage">
And now the typing is complete and this message appears!
</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/typed.js/2.0.0/typed.min.js"></script>
<script>
var app = new Vue({
el: '#app',
data() {
return {
typed: "",
showMessage: false,
};
},
mounted() {
this.initTyped();
},
methods: {
initTyped() {
this.typed = new Typed("#typing", {
strings: ["Hi, I'm Bill. <br/> I'm a developer."],
loop: false,
showCursor: false,
typeSpeed: 35,
});
}
},
watch: {
"typed.typingComplete": function () {
if (this.typed.typingComplete) {
this.showMessage = true;
}
},
},
})
</script>
</body>
</html>

上面的代码应该可以按原样工作,只需将其粘贴到文件中并查看即可。它应该输入一个句子,当它完成键入时,将出现一条消息。

我是 Vue 3 的新手,所以对以下可能出现的所有错误表示歉意,但这是我想开始工作的要点:

<html>
<head>
<meta charset="UTF-8">
<title>CDN with Vue 2</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<h1>Here's the typed phrase:</h1>
<h2 id="typing"></h2>
<div v-if="showMessage">
And now the typing is complete and this message appears!
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typed.js/2.0.0/typed.min.js"></script>
<script>
const { ref, createApp, onMounted, watchEffect } = Vue
createApp({
setup() {
let showMessage = ref(false)
const initTyped = () => {
const typed = new Typed("#typing", {
strings: ["Hi, I'm Bill. <br/> I'm a developer."],
loop: false,
showCursor: false,
typeSpeed: 35,
});
}
onMounted(() => {
initTyped()
})
watchEffect(() => {
if (typed.typingComplete) {
showMessage = true;
}
});
return {
showMessage
}
}
}).mount('#app')
</script>
</body>
</html>

我不知道我是否应该使用 Watch/WatchEffect,我猜我声明和更新showMessage变量都是错误的,我不知道如何设置typed变量以便它可供watchEffect使用,而且我通常不知道我在用组合 API 做什么!

同样在你推荐vue-typed-js之前,这个库似乎还与 Vue 3 不兼容;但我还是没有在 Vue 2 中使用它。

任何帮助都值得赞赏,Vue 3 中的一些代码会很棒!

等效的 Vue 3 代码是:

  1. typed声明为ref

  2. initTyped()中,将typed的值设置为新的Typed实例(通过其.value属性)。

  3. 在观察程序中,设置showMessage的值true(通过其.value属性)。

1️⃣
let typed = ref()
const initTyped = () => {
2️⃣
typed.value = new Typed("#typing", {⋯});
}

onMounted(() => {
initTyped()
})
watchEffect(() => {
if (typed.typingComplete) {
3️⃣
showMessage.value = true;
}
});

<html>
<head>
<meta charset="UTF-8">
<title>CDN with Vue 2</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<h1>Here's the typed phrase:</h1>
<h2 id="typing"></h2>
<div v-if="showMessage">
And now the typing is complete and this message appears!
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typed.js/2.0.0/typed.min.js"></script>
<script>
const { ref, createApp, onMounted, watchEffect } = Vue
createApp({
setup() {
let showMessage = ref(false)
let typed = ref()

const initTyped = () => {
typed.value = new Typed("#typing", {
strings: ["Hi, I'm Bill. <br/> I'm a developer."],
loop: false,
showCursor: false,
typeSpeed: 35,
onComplete: () => showMessage.value = true
});
}
onMounted(() => {
initTyped()
})
watchEffect(() => {
if (typed.typingComplete) {
showMessage.value = true
}
})

return {
showMessage
}
}
}).mount('#app')
</script>
</body>
</html>

但是,您不需要存储对Typed实例的引用。Typed选项包括一个onComplete回调属性,可用于代替观察程序,因此您的代码可以简化为:

const initTyped = () => {
new Typed("#typing", {
⋮
onComplete: () => showMessage.value = true, 
});
}
onMounted(() => {
initTyped()
})

<html>
<head>
<meta charset="UTF-8">
<title>CDN with Vue 2</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<h1>Here's the typed phrase:</h1>
<h2 id="typing"></h2>
<div v-if="showMessage">
And now the typing is complete and this message appears!
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/typed.js/2.0.0/typed.min.js"></script>
<script>
const { ref, createApp, onMounted } = Vue
createApp({
setup() {
let showMessage = ref(false)
const initTyped = () => {
new Typed("#typing", {
strings: ["Hi, I'm Bill. <br/> I'm a developer."],
loop: false,
showCursor: false,
typeSpeed: 35,
onComplete: () => showMessage.value = true
});
}
onMounted(() => {
initTyped()
})
return {
showMessage
}
}
}).mount('#app')
</script>
</body>
</html>

最新更新