【Vue】v-model 的使用
双向绑定 v-model
- v-model:value=”值” 可简写为 v-model=”值”,用于双向绑定 [表单元素] 的信息
- 双向绑定:表单元素的 value attribute 的值 ↔ data 中对应的值
- 本质上,v-model 是由 v-bind 配合 input 事件实现的
① v-bind 绑定 value 属性、② 在 input 事件的回调函数中更新 value 的值
文本 input [text]
Message is: {{ msg }}
let vm = new Vue({
el: '#app',
data: { msg: 'superman' },
});
上例中,input 的默认值为 data 中的 msg,更新 input 的 value 值 → msg 也会被更新 → p 显示的内容也会被更新
多行文本 textarea
- 对于文本域标签
- 虽然
单选框 input [radio]
因为 v-model 绑定的是 value 值
所以,我们需要设置 value 属性;如果没有设置 value 属性,则获取到的值为 null
sex: {{ sex }}
let vm = new Vue({
el: '#app',
data: {
sex: '',
// sex: "male" // 设置默认值 'male',默认选中 male 选项
},
});
复选框 input [checkbox]
- 没有配置 value 属性,收集的是 checkbox 的 checked 状态,所以会收集到布尔值
let vm = new Vue({ el: '#app', data: { checked: true }, // 绑定 [布尔值]});- 配置了 value 属性,绑定 [非数组],收集的也还是 checkbox 的 checked 状态
所以也还是会收集到布尔值 → ture-全选、false-全不选
篮球足球网球{{checked}}
- 配置了 value 属性,绑定 [数组],才能收集到多选框的 value 值
篮球 足球 网球{{checked}}
let vm = new Vue({
el: '#app',
data: {
checked: [], // 绑定到数组
},
});
- 能获取到多个值的表单元素,都应该绑定 [数组],以存储多个数据
选择框 select > option
- 对于下拉菜单,推荐提供一个值为空的禁用选项,作为默认显示选项
国家 中国 美国 日本Selected: {{ selected }}let vm = new Vue({ el: '#app', data: { selected: '', // selected: "China" // 设置默认值 },});- 如果 option 标签不设置 value 属性,则获取到的是 option 标签的内容
国家 中国 美国 日本Selected: {{ selected }}- 多选时,绑定到一个数组
国家 中国 美国 日本Selected: {{ selected }}let vm = new Vue({ el: '#app', data: { selected: [], // 绑定到数组 },});
标签修饰符
- .lazy:在 change 事件之后同步,即失焦再同步(默认 input 事件之后同步,即一边写一边同步)
- .trim:过滤首尾空白字符
- .number:将输入数据使用 parseFloat() 转为 Number 类型;若这个值无法被 parseFloat() 解析,则会返回输入的字符串
{{ username }}
{{ password }}
{{ age }}
{{ height }}
表单提交事件
- submit 提交表单时触发
- .prevent 阻止默认行为
Vue2 组件使用 v-model
v-model 其实是 v-bind:value + v-on:input 的语法糖
{{ demoText }}
(demoText = ev.target.value)"
/>
export default {
name: 'App',
data() {
return {
demoText: 'demoText',
};
},
};
同理,在自定义组件上使用:
{{ demoText }}
(demoText = val)"
/>
import HelloWorld from '@/components/HelloWorld.vue';
export default {
name: 'App',
components: { HelloWorld },
data() {
return {
demoText: 'demoText',
};
},
};
需要注意的是:自定义组件上的 :value 变成了自定义属性,@input 变成了自定义事件
export default {
name: 'HelloWorld',
props: ['value'], // 接收自定义属性
};
.sync 修饰符
上例可以优化成:
{{ demoText }}
export default {
name: 'HelloWorld',
props: ['title'],
};
这种写法可以使用语法糖
{{ demoText }}
注意:带有 .sync 修饰符的 v-bind 不能和表达式一起使用;eg: v-bind:title.sync=”doc.title + ‘!'” 是无效的
- 当我们用一个对象同时设置多个 prop 的时候,也可以将这个 .sync 修饰符和 v-bind 配合使用
这样会把 doc 对象中的每一个 property (如 title) 都作为一个独立的 prop 传进去,然后各自添加用于更新的 v-on 监听器
注意:将 v-bind.sync 用在一个字面量的对象上,eg: v-bind.sync=”{ title: doc.title }”,是无法正常工作的
因为在解析一个像这样的复杂表达式的时候,有很多边缘情况需要考虑
Vue3 组件使用 v-model
- 在普通标签元素上使用 v-model
{{ textDemo }}
import { ref } from 'vue';
const textDemo = ref('textDemo');
上例等价于
{{ textDemo }}
- 在自定义组件上使用 v-model
import { ref } from 'vue';
import HelloWorld from '@/components/HelloWorld.vue';
const textDemo = ref('Vue.js');
上例等价于
(textDemo = newValue)"
/>
此时,子组件内需要做两件事:
① 将原生 input 元素的 value attribute 绑定到 modelValue prop
② 当原生的 input 事件触发时,触发一个携带了新值的 update:modelValue 自定义事件
{{ modelValue }}
defineProps<{ modelValue: string }>(); // 接收 `modelValue` prop
defineEmits<{ (e: 'update:modelValue', val: string): void }>(); // 接收 `update:modelValue` 自定义事件
v-model 的参数
- 默认情况下,v-model 在组件上都是使用 modelValue 作为 prop,并以 update:modelValue 作为对应的事件
- 可以给 v-model 指定一个参数来更改这些名字
import { ref } from 'vue';import HelloWorld from '@/components/HelloWorld.vue';const textDemo = ref('Vue.js'); {{ title }} defineProps<{ title: string }>(); // v-model 的参数名 title 作为 propdefineEmits<{ (e: 'update:title', val: string): void }>(); // 自定义事件名也变成了 update:title
v-model 的修饰符
- v-model 有一些内置的修饰符 (.trim、.number、.lazy)
- 若使用了自定义修饰符,可通过 modelModifiers prop 在组件内访问该自定义修饰符
- 若 v-model 携带着参数,eg: v-model:title,则 prop 为 titleModifiers
{{ title }} const props = withDefaults( defineProps<{ title: string; titleModifiers: {}; // 接收 prop titleModifiers }>(), { title: '', titleModifiers: () => ({}), // 设置默认值为空对象 });defineEmits<{ (e: 'update:title', val: string): void }>();console.log(props.titleModifiers); // { capitalize: true }上例中,props.titleModifiers 的值为 { capitalize: true },是因为 v-model 使用了修饰符 capitalize。
有了这个 prop,就可以检查 modelModifiers 对象的 key,并编写一个处理函数以改变抛出的值
{{ title }}
const props = withDefaults(
defineProps<{
title: string;
titleModifiers: {};
}>(),
{
title: '',
titleModifiers: () => ({}),
}
);
const emit = defineEmits<{ (e: 'update:title', val: string): void }>();
function emitValue(e: any) {
let value = e.target.value;
if ((props.titleModifiers as any).capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1);
}
emit('update:title', value);
}
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/ca930004b4.html
