Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ✨ 重置表单项为初始值,并移除校验结果 #719

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/component/form.md
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,7 @@ function handleIconClick() {
| -------- | ------------------------------------------------------------------------------ | --------------- | -------- |
| validate | 验证表单,支持传入一个 prop 来验证单个表单项,不传入 prop 时,会验证所有表单项 | `prop?: string` | 0.2.0 |
| reset | 重置校验结果 | - | 0.2.0 |
| resetFields | 重置表单项为初始值,并移除校验结果 | - | $LOWEST_VERSION$ |
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

需要替换版本号占位符

$LOWEST_VERSION$ 需要替换为实际的版本号。

-| resetFields | 重置表单项为初始值,并移除校验结果                                              | -               | $LOWEST_VERSION$    |
+| resetFields | 重置表单项为初始值,并移除校验结果                                              | -               | 1.4.0    |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| resetFields | 重置表单项为初始值,并移除校验结果 | - | $LOWEST_VERSION$ |
| resetFields | 重置表单项为初始值,并移除校验结果 | - | 1.4.0 |


## 外部样式类

Expand Down
8 changes: 8 additions & 0 deletions src/pages/form/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
</wd-cell-group>
<view class="footer">
<wd-button type="primary" size="large" @click="handleSubmit1" block>提交</wd-button>
<wd-button type="primary" size="large" @click="resetFields1" block class="reset">重置</wd-button>
</view>
</wd-form>
</demo-block>
Expand Down Expand Up @@ -194,6 +195,10 @@ function handleSubmit2() {
})
}

function resetFields1() {
form1.value!.resetFields()
}

function handleClick1() {
uni.navigateTo({ url: '/pages/form/demo1' })
}
Expand All @@ -218,5 +223,8 @@ function handleClick4() {
}
.footer {
padding: 16px;
.reset {
margin-top: 10px;
}
}
</style>
4 changes: 4 additions & 0 deletions src/uni_modules/wot-design-uni/components/wd-form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export type FormExpose = {
* 重置表单项的验证提示
*/
reset: () => void
/**
* 重置表单项为初始值,并清空验证提示
*/
resetFields: () => void
}

export type FormInstance = ComponentPublicInstance<FormProps, FormExpose>
21 changes: 20 additions & 1 deletion src/uni_modules/wot-design-uni/components/wd-form/wd-form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { deepClone, getPropByPath, isDef, isPromise } from '../common/util'
import { useChildren } from '../composables/useChildren'
import { useToast } from '../wd-toast'
import { type FormRules, FORM_KEY, type ErrorMessage, formProps, type FormExpose } from './types'
import { onMounted } from 'vue'

const { show: showToast } = useToast('wd-form-toast')
const props = defineProps(formProps)
Expand Down Expand Up @@ -180,7 +181,25 @@ function reset() {
clearMessage()
}

defineExpose<FormExpose>({ validate, reset })
/**
* 重置表单项为初始值,并清空验证提示
*/
let initialValue: any = undefined
function resetFields() {
let model = props.model
children.forEach((field) => {
model[field.prop] = deepClone(initialValue[field.prop])
})

reset()
}
Comment on lines +187 to +195
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

需要增强类型安全性和错误处理

当前实现存在以下问题:

  1. 直接访问和修改 model[field.prop] 缺少类型检查
  2. 没有对 field.prop 进行空值检查
  3. 直接修改 props 可能违反 Vue 的单向数据流原则

建议按照以下方式重构:

-let model = props.model
-children.forEach((field) => {
-  model[field.prop] = deepClone(initialValue[field.prop])
-})
+const model = props.model
+children.forEach((field) => {
+  if (field.prop && initialValue && initialValue[field.prop] !== undefined) {
+    // 建议通过 emit 事件通知父组件更新,而不是直接修改
+    emit('update:model', {
+      ...model,
+      [field.prop]: deepClone(initialValue[field.prop])
+    })
+  }
+})

Committable suggestion skipped: line range outside the PR's diff.


onMounted(() => {
// 保存初始值
initialValue = deepClone(props.model)
})
Comment on lines +197 to +200
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

建议优化初始值的处理机制

当前实现在组件挂载时只保存一次初始值,这可能导致以下问题:

  1. 如果 props.model 后续发生变化,初始值不会更新
  2. 组件卸载时没有清理 initialValue

建议改进如下:

+import { ref, watch } from 'vue'
-let initialValue: any = undefined
+const initialValue = ref<any>(undefined)

+watch(() => props.model, (newModel) => {
+  initialValue.value = deepClone(newModel)
+}, { immediate: true, deep: true })

-onMounted(() => {
-  // 保存初始值
-  initialValue = deepClone(props.model)
-})

+onUnmounted(() => {
+  initialValue.value = undefined
+})

Committable suggestion skipped: line range outside the PR's diff.


defineExpose<FormExpose>({ validate, reset, resetFields })
</script>

<style lang="scss" scoped>
Expand Down