表单
当你在制作后台管理系统时,就会接触到很多表单输入选项。Gyron.js 的表单数据绑定和默认表单数据提交是不同的行为。
在 HTML 表单中,提交数据由 DOM 元素属性和值提供。在 Gyron.js 中,需要自定义数据的绑定以更灵活地掌控自己的数据变化。
基本例子
我们用两种不同用法对比他们的优缺点。
<form>
<label>
名字:
<input type="text" name="name" />
</label>
<input type="submit" value="提交" />
</form>
这种写法的优点是简洁明了,用户只需在表单中输入完成后点击提交按钮即可。然而,它的缺点在于我们无法方便地修改用户输入的值。针对这个问题,Gyron.js 提供了自定义数据绑定的方法,以便更好地掌控数据变化。在使用 Gyron.js 的表单数据绑定时,我们需要自己处理数据的绑定操作,但这样能够更灵活地控制数据的变化。
import { useReactive, FC } from 'gyron'
const Form = FC(() => {
const state = useReactive({
name: '',
})
const handleSubmit = (e) => {
// 自定义提交行为
e.preventDefault()
}
return (
<form onSubmit={handleSubmit}>
<label>
名字:
<input
type="text"
name="name"
value={state.name}
onChange={(e) => (state.name = e.target.value)}
/>
</label>
<input type="submit" value="提交" />
</form>
)
})
受控组件
还需要注意的就是某些控件的值不是 value,比如<input type="checkbox" checked />
的 value 就是 checked,在绑定值的时候请使用 checked。
有一个特殊的例子就是select
标签,它的 value 是根据 option 的 checked 的状态来决定的,这在我们内部做了兼容处理,所以只需要关心 value 的值即可。
import { useValue, FC } from 'gyron'
const App = FC(() => {
const selected = useValue(['bar'])
const handleChange = (e) => {
const value = Array.from(e.target.selectedOptions).map(
(select) => select.value
)
selected.value = value
}
return (
<select multiple={true} value={selected.value} onChange={handleChange}>
<option value="foo">foo</option>
<option value="bar">bar</option>
</select>
)
})
上面的例子就是一个简单的多选例子,在发生变更的时候通过 selectedOptions 来更新绑定的值,如果绑定的值发生变更也会更新 select 的状态。
如果你想管理输入状态或者需要组合输入的状态管理可以使用 onInput 或者使用onCompositionstart/onCompositionend
事件。
注意:如果依赖的值没有发生变更,可以使用 update 进行更新操作
import { useValue, FC } from 'gyron'
const App = FC(({ component }) => {
const code = useValue('')
const handleInput = (e) => {
code.value = e.target.value.toLocaleUpperCase()
component.update()
}
return <input value={code.value} onInput={handleInput} />
})
Input
input
控件的事件和浏览器内置的事件在有些情况下表现不一样,这样做是为了兼容输入类型的控件在事件上行为保持一致。
input 控件的 change
事件在行为上和其它控件一样,在内容发生变更后立马调用,这一点和浏览器不一样,浏览器是在输入变更后焦点离开才会触发 change
事件。
import { FC } from 'gyron'
const App = FC(() => {
function handleInput() {}
return (
<div>
<input onChange={handleInput} />
{/* 行为一致 */}
<input onInput={handleInput} />
</div>
)
})