-
Notifications
You must be signed in to change notification settings - Fork 259
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
27 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
# 表单处理 | ||
|
||
在 Vue 中,表单可以是简单的 HTML 表单,也可以是复杂的嵌套自定义 Vue 组件表单元素。我们将逐步了解如何与表单元素交互、设置值和触发事件。 | ||
在 Vue 中,表单可以是简单的 HTML 表单,也可以是复杂的嵌套自定义 Vue 组件表单元素。我们将逐步了解如何与表单元素交互、赋值和触发事件。 | ||
|
||
我们将使用的主要方法是 `setValue()` 和 `trigger()`。 | ||
我们主要使用的方法是 `setValue()` 和 `trigger()`。 | ||
|
||
## 与表单元素交互 | ||
|
||
|
@@ -33,11 +33,11 @@ export default { | |
</script> | ||
``` | ||
|
||
### 设置元素值 | ||
### 给元素赋值 | ||
|
||
在 Vue 中,将输入绑定到数据的最常见方法是使用 `v-model`。正如你可能已经知道的,它处理每个表单元素发出的事件以及它接受的 props,使我们更容易处理表单元素。 | ||
在 Vue 中,将输入绑定到数据的最常见方法是使用 `v-model`。你可能知道,它会处理每个表单元素发出的事件,且可以接受一些 props 使表单元素的工作变得更容易。 | ||
|
||
要在 VTU 中更改输入的值,可以使用 `setValue()` 方法。它接受一个参数,通常是一个 `String` 或 `Boolean`,并返回一个 `Promise`,在 Vue 更新 DOM 后解析。 | ||
要在 VTU 中更改输入的值,可以使用 `setValue()` 方法。它接受一个参数,通常是一个 `String` 或 `Boolean`,并返回一个 `Promise`,在 Vue 更新 DOM 后完成解析。 | ||
|
||
```js | ||
test('sets the value', async () => { | ||
|
@@ -52,11 +52,11 @@ test('sets the value', async () => { | |
|
||
如你所见,`setValue` 将输入元素的 `value` 属性设置为我们传递的值。 | ||
|
||
我们使用 `await` 确保 Vue 完成更新,并且更改已反映在 DOM 中,然后再进行任何断言。 | ||
我们使用 `await` 确保在进行任何断言之前,Vue 已经完成更新并且这些更新已反映在 DOM 中。 | ||
|
||
### 触发事件 | ||
|
||
触发事件是处理表单和操作元素时的第二个重要操作。让我们看看之前示例中的 `button`。 | ||
触发事件是处理表单和可交互元素时的第二个重要操作。让我们看看之前示例中的 `button`。 | ||
|
||
```html | ||
<button @click="submit">Submit</button> | ||
|
@@ -82,7 +82,7 @@ test('trigger', async () => { | |
|
||
然后我们可以断言某个操作是否发生。在这种情况下,我们确认发出了正确的事件。 | ||
|
||
让我们将这两个结合起来,测试我们的简单表单是否发出了用户输入。 | ||
让我们将这两个结合起来,测试这个简单的表单是否发出了用户输入。 | ||
|
||
```js | ||
test('emits the input to its parent', async () => { | ||
|
@@ -94,7 +94,7 @@ test('emits the input to its parent', async () => { | |
// 触发元素 | ||
await wrapper.find('button').trigger('click') | ||
|
||
// 断言 `submit` 事件被发出 | ||
// 断言 `submit` 事件被发出 | ||
expect(wrapper.emitted('submit')[0][0]).toBe('[email protected]') | ||
}) | ||
``` | ||
|
@@ -105,7 +105,7 @@ test('emits the input to its parent', async () => { | |
|
||
### 与各种表单元素的协作 | ||
|
||
我们看到 `setValue` 可以与输入元素一起使用,但它更为通用,可以设置各种类型输入元素的值。 | ||
我们看到 `setValue` 可以与输入元素一起使用,事实上它可以给更多元类型的输入元素赋值,因此它非常全能。 | ||
|
||
让我们看一个更复杂的表单,它包含更多类型的输入。 | ||
|
||
|
@@ -152,9 +152,9 @@ export default { | |
</script> | ||
``` | ||
|
||
我们的扩展 Vue 组件稍微长一些,包含更多输入类型,并且 `submit` 处理程序已移至 `<form/>` 元素。 | ||
我们扩展的 Vue 组件稍微长一些,包含更多输入类型,并且 `submit` 处理程序已移至 `<form/>` 元素。 | ||
|
||
就像我们为 `input` 设置值一样,我们也可以为表单中的所有其他输入字段设置值。 | ||
就像我们为 `input` 赋值一样,我们也可以为表单中的所有其他输入赋值。 | ||
|
||
```js | ||
import { mount } from '@vue/test-utils' | ||
|
@@ -171,19 +171,19 @@ test('submits a form', async () => { | |
}) | ||
``` | ||
|
||
如你所见,`setValue` 是一个非常通用的方法。它可以与所有类型的表单元素一起使用。 | ||
如你所见,`setValue` 是一个非常全能的方法。它可以与所有类型的表单元素一起使用。 | ||
|
||
我们在每个地方都使用 `await`,以确保在触发下一个事件之前,每个更改都已应用。这是推荐的做法,以确保在 DOM 更新后进行断言。 | ||
我们在每个地方都使用 `await`,以确保在触发下一个事件之前,每个更改都已生效。这是推荐的做法,以确保在 DOM 更新后进行断言。 | ||
|
||
::: tip | ||
如果你不为 `OPTION`、`CHECKBOX` 或 `RADIO` 传递参数给 `setValue`,它们将被设置为 `checked`。 | ||
如果你处理 `OPTION`、`CHECKBOX` 或 `RADIO` 时没有给 `setValue` 传递参数,它们将被设置为 `checked`。 | ||
::: | ||
|
||
我们已经在表单中设置了值,现在该提交表单并进行一些断言了。 | ||
我们已经为表单赋值,现在该提交表单并进行一些断言了。 | ||
|
||
### 触发复杂事件监听器 | ||
|
||
事件监听器并不总是简单的 `click` 事件。Vue 允许你监听各种 DOM 事件,添加特殊修饰符如 `.prevent` 等。让我们看看如何测试这些。 | ||
事件监听器并不总是服务于简单的 `click` 事件。Vue 允许你监听各种 DOM 事件,添加特殊修饰符如 `.prevent` 等。让我们看看如何测试这些。 | ||
|
||
在上面的表单中,我们将事件从 `button` 移动到 `form` 元素。这是一个好的实践,因为这样可以通过按 `enter` 键提交表单,这是一种更原生的方式。 | ||
|
||
|
@@ -218,14 +218,14 @@ test('submits the form', async () => { | |
要测试事件修饰符,我们直接将事件字符串 `submit.prevent` 复制粘贴到 `trigger` 中。`trigger` 可以读取传递的事件及其所有修饰符,并选择性地应用必要的内容。 | ||
|
||
::: tip | ||
原生事件修饰符如 `.prevent` 和 `.stop` 是 Vue 特有的,因此我们不需要测试它们,Vue 内部已经对此进行了测试。 | ||
诸如 `.prevent` 和 `.stop` 的原生事件修饰符是 Vue 特有的,因此我们不需要测试它们,Vue 内部已经对此进行了测试。 | ||
::: | ||
|
||
然后我们进行简单的断言,检查表单是否发出了正确的事件和载荷。 | ||
|
||
#### 原生表单提交 | ||
|
||
在 `<form>` 元素上触发 `submit` 事件模拟了浏览器在表单提交时的行为。如果我们想以更自然的方式触发表单提交,可以触发提交按钮上的 `click` 事件。由于未连接到 `document` 的表单元素无法提交,因此根据 [HTML 规范](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm),我们需要使用 [`attachTo`](../../api/#attachTo) 将包装器的元素连接起来。 | ||
在 `<form>` 元素上触发 `submit` 事件模拟浏览器在表单提交时的行为。如果我们想以更自然的方式触发表单提交,可以触发提交按钮上的 `click` 事件。由于未连接到 `document` 的表单元素无法提交,因此根据 [HTML 规范](https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm),我们需要使用 [`attachTo`](../../api/#attachTo) 将包装器的元素连接起来。 | ||
|
||
#### 同一事件上的多个修饰符 | ||
|
||
|
@@ -303,13 +303,13 @@ test('emits an event only if you lose focus to a button', () => { | |
}) | ||
``` | ||
|
||
在这里,我们假设代码在 `event` 对象内部检查 `relatedTarget` 是否为按钮。我们可以简单地传递对该元素的引用,模拟用户在 `input` 中输入内容后点击 `button` 的情况。 | ||
这里我们假设代码在 `event` 对象内部检查 `relatedTarget` 是否为按钮。我们可以简单地传递对该元素的引用,模拟用户在 `input` 中输入内容后点击 `button` 的情况。 | ||
|
||
## 与 Vue 组件输入交互 | ||
|
||
输入不仅仅是普通元素。我们经常使用像输入一样的 Vue 组件。它们可以以易于使用的格式添加标记、样式和许多功能。 | ||
输入不仅仅是普通元素。我们经常使用和输入控件行为相似的 Vue 组件。它们可以通过添加标记、样式和许多功能使其更易用。 | ||
|
||
测试使用这些输入的表单起初可能会让人感到棘手,但遵循一些简单的规则后,它很快就变得轻松。 | ||
测试使用这些输入组件的表单起初可能会让人感到棘手,但遵循一些简单的规则后,它很快就变得轻松。 | ||
|
||
以下是一个包装 `label` 和 `input` 元素的组件: | ||
|
||
|
@@ -340,7 +340,7 @@ export default { | |
<custom-input v-model="input" label="Text Input" class="text-input" /> | ||
``` | ||
|
||
与普通元素一样,这些 Vue 驱动的输入通常内部都有一个真实的 `button` 或 `input`。你可以轻松找到该元素并对其进行操作: | ||
与普通元素一样,这些基于 Vue 的输入组件通常内部都有一个真实的 `button` 或 `input`。你可以轻松找到该元素并对其进行操作: | ||
|
||
```js | ||
test('fills in the form', async () => { | ||
|
@@ -356,7 +356,7 @@ test('fills in the form', async () => { | |
|
||
如果你的输入组件不那么简单怎么办?你可能正在使用 UI 库,例如 Vuetify。如果你依赖内部标记以找到正确的元素,那么如果外部库更改其内部结构,你的测试可能会失败。 | ||
|
||
在这种情况下,你可以直接使用组件实例和 `setValue` 设置值。 | ||
在这种情况下,你可以直接使用组件实例和 `setValue` 来赋值。 | ||
|
||
假设我们有一个使用 Vuetify 文本区域的表单: | ||
|
||
|
@@ -385,7 +385,7 @@ export default { | |
</script> | ||
``` | ||
|
||
我们可以使用 `findComponent` 找到组件实例,然后设置它的值。 | ||
我们可以使用 `findComponent` 找到组件实例,然后给它赋值。 | ||
|
||
```js | ||
test('emits textarea value on submit', async () => { | ||
|
@@ -402,7 +402,7 @@ test('emits textarea value on submit', async () => { | |
|
||
## 结论 | ||
|
||
- 使用 `setValue` 设置 DOM 输入元素和 Vue 组件的值。 | ||
- 使用 `setValue` 给 DOM 输入元素和 Vue 组件赋值。 | ||
- 使用 `trigger` 触发 DOM 事件,包括带有和不带修饰符的事件。 | ||
- 使用第二个参数向 `trigger` 添加额外的事件数据。 | ||
- 断言 DOM 发生了变化,并且发出了正确的事件。尽量不要对组件实例的数据进行断言。 | ||
- 断言 DOM 发生了变化,并且发出了正确的事件。尽量不要对组件实例上的数据进行断言。 |