当前位置: 首页 > 知识库问答 >
问题:

ant-design - 如何使用antDesign的Form组件实现类似Youtube的评论表单?

孟增
2024-06-03

需求

想使用antdesign的Form实现类似youtube的评论表单。

  • 初始包括

    • 头像
    • 输入框

commentBox-form-default.png

  • 聚焦(点击输入框或tab)输入框的时候

    • 输入框下面显示取消按钮评论按钮

      • 两者靠右对齐
      • 当输入框中的内容为空的时候,评论按钮disabled

commentBox-form-focus.png

  • 取消输入框聚焦(鼠标点击其他位置或tab到其他可聚焦元素)的时候,保持不变。
  • 按取消键,输入框底部的两个按钮消失,当前输入框中的内容清空。

尝试

codesandbox

import { Form, Avatar, Flex, Input, Button, Space } from "antd";import React from "react";function CommentForm() {  const [show, setShow] = React.useState(false);  const [form] = Form.useForm();  const comment = Form.useWatch("comment", form);  function handleReset() {    console.log("handle reset");    form.resetFields();    setShow(false);  }  console.log("comment ", comment);  return (    <Flex gap="small" align="start">      <Avatar>P</Avatar>      <Form        onFinish={() => console.log("Finished")}        className="grow"        form={form}      >        <Form.Item name="comment">          <Input            placeholder="添加一条评论"            onFocus={() => !show && setShow(true)}          />        </Form.Item>        {show && (          <Flex justify="end">            <Form.Item wrapperCol={{ span: 4, offset: 0 }}>              <Space>                <Button htmlType="reset" onClick={handleReset}>                  取消                </Button>                <Button htmlType="submit" disabled={!comment}>                  评论                </Button>              </Space>            </Form.Item>          </Flex>        )}      </Form>    </Flex>  );}export default CommentForm;

问题:

  1. 如何在聚焦时候的时候让两个按钮出现同时在取消聚焦的时候保持不变呢?

    • onFocus + show state
    • 还有其他更好的方案吗?
  2. 如何使两个按钮向右对齐?

    • 方案一: 在Form.Item的外面套一层Flex, 设置justify="end"
    • 方案二: Form其实使用了栅格来对Form.Item来进行布局, 设置wrapperCol={{span: ?, offset: ?}}offset只能相对于左侧,设置多少得用眼来估计,并不准确。
    • 还有其他更好的方案吗?
  3. 如何在点击取消按钮的时候使按钮消失,并清空输入框?

    • onClicksetShow(false)使按钮消失
    • 如何清空输入框?

      • 使用Form.useForm()产生一个formInstance传入Form,然后在onClick中调用resetFields,但是当传入Form的时候报错了Cannot set properties of undefined (setting 'name')

        • 后来发现应该是const [form] = Form.useForm()而不是const form = Form.useForm()
  4. 如何知道当前的输入框是否为空?

    • 方案一:设置一个新的状态,将value, onChange绑定到Input上?读文档发现表单控件会自动生成valueonChange来控制数据,不能再使用value来设置数据,不应该使用setState

      • 行不通
    • 方案二:借助Form.useWatch("comment", form)就可以获取当前comment的值了。

还有其他更优雅的实现方案吗?

附文档中相关说明:

被设置了 name 属性的 Form.Item 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:

  • 你不再需要也不应该用 onChange 来做数据收集同步(你可以使用 Form 的 onValuesChange),但还是可以继续监听 onChange 事件。
  • 你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。
  • 你不应该用 setState,可以使用 form.setFieldsValue 来动态改变表单值。

共有1个答案

慕宪
2024-06-03
import React from 'react';import { Form, Avatar, Flex, Input, Button, Space } from 'antd';function CommentForm() {  const [form] = Form.useForm();  const [show, setShow] = React.useState(false);  const comment = Form.useWatch("comment", form);  function handleReset() {    form.resetFields();    setShow(false);  }  return (    <Flex gap="small" align="start">      <Avatar>P</Avatar>      <Form form={form} onFinish={() => console.log("Finished")} className="grow">        <Form.Item name="comment">          <Input            placeholder="添加一条评论"            onFocus={() => setShow(true)}          />        </Form.Item>        {show && (          <Flex justify="end" style={{ width: '100%' }}>            <Button htmlType="reset" onClick={handle(Reset)}>              取消            </Button>            <Button type="primary" htmlType="submit" disabled={!comment}>              评论            </Button>          </Flex>        )}      </Form>    </Flex>  );}export default CommentForm;
 类似资料:
  • 怎么一失焦提示就没了?(代码跨度较大,不好提供) 原因:失焦后判断不为空,之前的提示就被消了。 ant为什么这样设计呢?在可能出现多种错误的情况下,已经匹配到某个错误就不应该继续匹配了 ,应该让用户一个一个消除错误嘛。

  • 使用antd中的表格组件怎么实现数据跨行显示 一级目录有两个公司架构的字段,想要公司架构跨行显示。有两个公司架构的话跨两行,有三个的话跨三行显示,请问这个应该怎么实现呢? parentName是一级目录的键名 下面这个是表格大概的数据 用的是vue2的写法 尝试使用了组件库自带的customCell属性,好像不太行,请问这个应该怎么实现

  • 显示评论组件: {:Comments("posts",$object_id)} <!-- 评论文章表里的某个id为$object_id的文章--> Comments方法说明: 参数1:评论内容所在的表,不带表前缀的表名称,如cmf_posts应该改为“posts”; 参数2:评论内容的id: 参数3:数组,目前支持tpl参数,如array("tpl"=>"comment_custom"),这样设

  • Mudu.Room.Comment 评论组件 获取评论页数 // 返回评论页数,类型为int var commentPage = Mudu.Room.Comment.GetPage() 发送评论 Mudu.Room.Comment.Send( // 要发送的评论文本,类型为string '活动很赞很给力', // 发送完成的回调函数,参数为response对象 function

  • 我希望的效果就是这样的(提示666),但这个是react版的。 我的是 vue3 , 这要怎么配置呢?我试了试不行呢。

  • 框架:UNIAPP.先上图: 这是京东的订单评论功能,文本输入框在不选择标签时可正常输入评论,此时有几个标签可供用户选择,选择完标签后,另起一行,在文本框中出现带标签的文字(如图中箭头所示),可输入相关内容,再点击标签时提示请删除标签后内的内容。删除完内容后再按一次键盘上的删除键,整个标签被删除。 想问下这种功能是怎么实现的?