Vue 3 事件与响应性入门
2022年8月 · 预计阅读时间: 3 分钟
到现在,我们把 Vue 基本的展示逻辑介绍完了,覆盖了常见的场景:
- 在开合标签内引用 data 里的数据。
- 在标签属性中引用 data 的数据。
- 展示列表数据。
- 根据条件展示数据。
不过,这些都是静态的展示,没有数据的变化,体现不了 vue 的优点。这篇文章我们将通过处理 html DOM 事件,来修改 data 里的数据,并看到页面根据 data 的变化而变化,也就是 vue 的响应性机制。
注册事件
我们先看一下怎么在 vue 项目中注册事件。在 vue 中注册事件,使用 v-on 加上冒号:后面跟上事件的名字:
<button v-on:click=""></button>
这里事件的名字,就是普通 html 事件,去掉 on 剩余的部分,常见的事件名可以查看这个表格:
HTML 事件名 | Vue 事件名 |
---|---|
onclick | click |
onchange | change |
onblur | blur |
onfocus | focus |
onsubmit | submit |
onreset | reset |
因为注册事件也是前端开发中经常要用到的功能,所以 v-on 也提供了简写形式,使用一个 "@" 符号,这个时候就不需要加冒号了:
<button @click=""></button>
事件处理
在事件处理的时候,可以给事件监听传递一个函数,或者直接使用 JavaScript 表达式,但是现在我们还没接触到在 vue 中如何定义函数/方法(methods),所以我们就用简单的 JavaScript 表达式来处理事件。 在事件处理代码中,可以直接访问和修改 data 中的属性,这段代码把 data 中,布尔类型的 showAnswer 属性进行了 toggle 操作,也就是每次点击按钮的时候,把 true 和 false 进行取反操作,用于切换 showAnswer 的 true 和 false 值,:
<button v-on:click="showAnswer = !showAnswer"></button>
data() { return { showAnswer: false, }; }
这时,事件的操作会修改 data 中 showAnswer 的值。如果这个时候,在 html 模板中有其它使用到 showAnswer 属性的地方,例如在一个标签的 v-show 中,根据它的值来判断是不是要显示这个标签,那么在 showAnswer 变化的时候,v-show 的判断也会动态变化,当 showAnswer 的值变为 true 时,这个标签就会渲染到 html 中,如果为 false 则不会,这个就是 vue 响应性机制的体现:
<p v-show="showAnswer" class="answer">
答:Vue 是一套用于构建用户界面的渐进式框架。
</p>
示例
好,我们来实际运行一下这个示例。假设我们要做一个 Q&A 问答卡片:
- 卡片一开始只显示问题,和显示答案按钮。
- 当点击显示答案时,在问题的下方展示答案,而显示答案按钮的文案变成隐藏答案。
我们来看一下实现过程。首先在我们的 vue 模板项目中,打开 index.js 文件,在 data() 函数返回的对象中,定义一个 showAnswer 属性,默认为 false,即不显示答案:
// 示例:事件处理和响应性入门
const app = Vue.createApp({
data() {
return {
showAnswer: false,
};
},
});
app.mount("#app");
接着,打开 index.html,在里边定义卡片的结构:
<div class="question">
<p>问:Vue 是一个什么样的框架?</p>
<p class="answer">答:Vue 是一套用于构建用户界面的渐进式框架。</p>
<button>显示答案</button>
</div>
这里:
- 使用一个 div 来定义卡片的容器。
- 在容器里边,使用一个 p 元素来显示一个问题。
- 再在它的下边,使用另一个 p 元素来显示答案。
- 最后,定义一个 button 元素,用于显示/隐藏答案。
现在这个页面是静态的,我们给按钮添加一个点击事件,让它在点击的时候,让 showAnwser 在 true 和 false 之间来回切换。这里:
- 我们使用 v-on 的简写形式注册了 click 点击事件。
- 之后给它设置处理代码,就是把 showAnswer 的值进行取反操作,并把结果再更新到 showAnswer 里。
<button @click="showAnswer = !showAnswer">显示答案</button>
接着,我们给存放答案的 p 元素,加上一个 v-show 指令,让它根据 showAnswer 的值,来决定是否要显示答案,如果 showAnswer 的值为 true 就显示答案,如果为 false 就隐藏答案:
<p v-show="showAnswer" class="answer">
答:Vue 是一套用于构建用户界面的渐进式框架。
</p>
好,现在我们点击一下按钮,可以看到答案就显示出来了,再点一下,答案就隐藏了。不过,这里有一个小问题,就是按钮的文案没有发生变化,在显示了答案之后,按钮的文案还是显示答案,这时应该改为隐藏答案。那么我们也可以在模板插值中,根据 showAnswer 属性的值,来显示不同的文本,因为模板插值中我们可以直接使用 JavaScript 表达式,所以这里我们可以使用三目运算符来控制按钮的文案。这里变化的文案是『显示』和『隐藏』两个字,而『答案』这两个字不变,所以我们可以这样写 {{ showAnswer ? "隐藏" : "显示" }}答案
:
<button @click="showAnswer = !showAnswer">
{{ showAnswer ? "隐藏" : "显示" }}答案
</button>
这样,vue 就会根据 showAnswer 属性的值,来改变按钮的文案了,点击一下,在显示答案的时候,按钮变成了隐藏答案,而答案隐藏时,按钮就又变成了显示答案。
小结
这个就是在 vue 中注册和处理事件的方法,使用 v-on: 或 @ 简写形式,加上去掉 on 的 html 事件名来注册事件,之后在指令的值中,使用 JavaScript 表达式来处理事件。另外也见识到了 vue 响应性的魅力,当处理事件时,改变了 data 中的某个属性值,那么所有使用到这个属性值的地方都会进行更新。