表单双向绑定

v-model
表单基础知识,请访问 web - formform event
v-modal
v-bind:是单向数据绑定:逻辑层数据流向渲染层
数据双向绑定 - 多用于表单
将表单输入框的内容同步给 JavaScript 中的数据:数据可以影响到表单;表单也可以影响到数据
数据可以是数值类型 number,也可以是字符串类型 string,还可以是布尔类型 true/false
绑定后会忽略任何表单元素上初始的 value、checked 或 selected attribute
表单事件
submit:表单提交;通常会阻止该行为的默认跳转
在事件对象的事件目标中获取值 e.target.value 或选择状态 e.target.checked、e.target.selected
<form @submit.prevent="submit">
    <input type="text" name="msg" required maxlength="16" v-model.trim="msg">
    <button>submit</button>
</form>
表单元素事件
input:输入过程中触发
change:状态改变后触发;如从选中状态变为取消选中状态;根据改变后的状态,执行相应的逻辑
常见表单元素的双向绑定
元素 绑定属性 事件类型
<input> - text value 属性 input 事件
<textarea> value 属性 input 事件
<input> - radio checked 属性 change 事件
<input> - checkbox checked 属性 change 事件
<select> value 属性 change 事件
<input> - text
单行文本输入
let msg = ref('')
传统方式 - 通过事件和属性绑定实现双向绑定;这里采用内联事件|行内事件
<input type="text" @input="msg = $event.target.value" :value="msg" required>
<input type="text" @input="(e) => { msg = e.target.value }" :value="msg" required>
<div>{{ msg }}</div>
双向绑定
<input type="text" v-model="msg" required>
<div>{{ msg }}</div>
<input> - radio
单选;多选一
不指定 value 的话,只能获取单选框的选中状态 checked 是 true 还是 false,并不知道选择了谁
值为静态数据 male、female
let gender = ref('')
传统方式
<input type="radio" name="gender" value="male" @change="(e) => gender = e.target.value">male
<input type="radio" name="gender" value="female" @change="(e) => gender = e.target.value">female
<div>{{ gender }}</div>
双向绑定 - 选项都绑定gender
<input type="radio" name="gender" value="male" v-model="gender">male
<input type="radio" name="gender" value="female" v-model="gender">female
<div>{{ gender }}</div>
<input> - checkbox
多选
通常需要为每个 <input> 指定值 value,并使用同一个名字 name 以确保它们是同一组
如果不指定数据|value,只能获取复选框的选中状态 checked 是 true 还是 false,并不知道选择了谁
<input type="checkbox" @change="selItem">
const selItem = (e) => {
    console.log(e.target.checked)
}
值为静态数据:code、sing、game、read
like是数组类型,不能是字符串
let like = ref([])
传统方式
<input type="checkbox" name="ulike" @change="sel" value="code">code
<input type="checkbox" name="ulike" @change="sel" value="sing">sing
<input type="checkbox" name="ulike" @change="sel" value="game">game
<input type="checkbox" name="ulike" @change="sel" value="read">read
<div>{{ like }}</div>
const sel = (e) => {
    e.target.checked ? like.value.push(e.target.value) : like.value = like.value.filter(item => item !== e.target.value)
}
双向绑定 - 选项都绑定数据like,就可以知道选择了哪些
<input type="checkbox" name="ulike" v-model="like" value="code">code
<input type="checkbox" name="ulike" v-model="like" value="sing">sing
<input type="checkbox" name="ulike" v-model="like" value="game">game
<input type="checkbox" name="ulike" v-model="like" value="read">read
<div>{{ like }}</div>
<input>的 radio 类型和 checkbox 类型,绑定的是 checked 属性 并侦听 change 事件
如果不指定 value,其默认值是 on - The default value for checkboxes and radio buttons is on
<textarea>
留言、评论
let msg = ref('')
传统方式 - 通过事件和属性绑定实现双向绑定;这里采用内联事件|行内事件
<textarea @input="(e) => { msg = e.target.value }" :value="msg" required></textarea>
<div>{{msg}}</div>
双向绑定
<textarea v-model="msg" required></textarea>
<div">{{msg}}</div>
不可以使用插值表达式{{}}
<textarea v-model="msg" required>{{msg}}</textarea>
<input> 的 text 类型和 <textarea>,绑定的是 value 属性 并侦听 input 事件
<select>
下拉列表;下拉框;值为静态数据 123
请自行完成传统方式的双向绑定
<select v-model = 'sel'>
    <option value='1'>1</option>
    <option value='2'>2</option>
    <option value='3'>3</option>
</select>
<div>{{sel}}</div>
<select> 绑定的是 value 属性 并侦听 change 事件
值的绑定
通常情况下,绑定时,当状态变化时,对应不同的的静态值,如男、女
有时候,我们希望使用动态数据,以满足更多场景,如在列表渲染中动态指定值:使用 v-bind 绑定实现
同一份逻辑,既可以实现性别的选择,也可以实现其它两个状态的应用,如:是否在岗?是否婚配?是否成年?给什么数据,就绑定什么数据 - 响应式数据;
采用值绑定,可以拓展逻辑;如性别单选中,非男即女,是对立的两个状态;绑定后,响应式数据可以任意指定,甚至可以是完全不相关的场合
多用于单选、多选和下拉列表
<input> - radio
<input type="radio" id="male" v-model="ugender" :value="maleVal">
<label for="male">male</label>
<input type="radio" id="female" v-model="ugender" :value="femaleVal">
<label for="female">female</label>
为两个状态指定响应式数据,可以是任何值,而不是简单的静态 male 和 female
let ugender = ref('')
let maleVal = reactive({
    id: 10,
    name: 'gl'
})
let femaleVal = reactive({
    id: 20,
    name: 'gz'
})
<input> - checkbox
参照前例,修改静态值为动态绑定;内容自定
提示:列表渲染
<select>
参照前例,修改静态值为动态绑定;内容自定
提示:列表渲染
实现绑定后,后续的逻辑仍然需要事件的支持,如 change后根据状态变化执行相应的逻辑
双向绑定引发的性能问题
修饰符
.number
把 v-model 的值转换成数值类型
如果输入的第一个字是字符串,那 number 这个修饰符就不会生效
输入的第一个只能是数字或者小数点或者是正负号
既然需要转换为数字,那么就请输入数字吧
.lazy
在默认情况下,v-model 在 input 事件中同步输入框的值与数据,实时渲染
指定 lazy,会把 oninput 事件改成 onchange 事件
当失去焦点或按下回车时才触发更新
.trim
过滤用户输入时首尾的空格字符
[] 使用须知、记住密码
使用单个复选框实现;不需要指定 value,需要的只是是否选中
<label>
    <input type="checkbox" v-model="isAgree">已阅读并同意服务条款
</label>
let isAgree = ref(false)
[] 代办事项
[] 注册和登录
传统方式:用户名和密码、手机
现在方式:第三方
[] 购物车 - 全选
思路:状态改变时,检查选中数据和原始数据是否一致 - 可通过长度判断
Summary
<input> 的 text 类型和 <textarea>,绑定的是 value 属性 并侦听 input 事件
<input> 的 radio 类型和 checkbox 类型,绑定的是 checked 属性 并侦听 change 事件
<select> 绑定的是 value 属性 并侦听 change 事件