Vue基础--Vue中的双向绑定v-model指令
一、v-model的作用和使用场景
1.1 v-model指令介绍
期望的绑定值类型:根据表单输入元素或组件输出的值而变化
可以下下面元素使用:
<input>
<select>
<testarea>
components
<checkbox>
<radio>
<select>
表单输入元素都是可以使用的
v-model支持的修饰符:
.lazy
——监听change
事件而不是input
.number
——将输入的合法符串转为数字.trim
—移除输入内容两端空格
1.2 v-model指令的作用
在表单输入元素或组件上创建双向绑定。
它会根据控件类型自动选取正确的方法来更新元素。
它负责监听用户的输入事件来更新数据,并在某种极端场景下进行一些特殊处理。
毕竟表单提交是开发中非常常见的功能,也是和用户交互的重要手段。
用户在登录、注册时需要提交账号密码,检索、新建、更新数据时,需要提交数据,这些都离不开表单提交。
1.3 什么是双向绑定
Vue
中的的双向数据绑定是指model
模型(Vue
中data
下定义的变量)和view
(视图)的双向绑定。
其中一个发生改变,另一个也会更新改变。
但是更通俗和常用的讲就是当表单元素的值发生变化时。和它绑定的Vue
中的data
变量也发生改变。,
二、v-model的基本使用
2.1 代码示例和解析
<div id="app"><!-- 1.使用v-model实现input的双向绑定 --><input type="text" v-model="message"><h2>input: {{message}}</h2><hr><!-- 2.使用v-model实现textarea的双向绑定 --><textarea cols="30" rows="10" v-model="content"></textarea><h2>textarea: {{content}}</h2><hr><!-- 3.使用v-model实现checkbox的双向绑定 --><!-- 3.1 checkbox单选框: 绑定到属性中的值是一个Boolean --><!-- label的作用是点击label中的文本时,相当于点击到绑定的input元素 --><label for="agree"><input id="agree" type="checkbox" v-model="isAgree"> 同意协议</label><h2>checkbox单选: {{isAgree}}</h2><hr><!-- 3.2 checkbox多选框: 绑定到属性中的值是一个Array --><!-- checkbox单选框; 绑定到属性中的值是单选框的value --><div class="hobbies"><h2>请选择你的爱好:</h2><label for="sing"><input id="sing" type="checkbox" v-model="hobbies" value="sing"> 唱</label><label for="jump"><input id="jump" type="checkbox" v-model="hobbies" value="jump"> 跳</label><h2>爱好: {{hobbies}}</h2></div><hr><!-- 4.使用v-model实现radio的双向绑定 --><!-- radio单选框: 绑定到属性中的值是单选框的value --><div class="gender"><label for="male"><input id="male" type="radio" v-model="gender" value="male"> 男</label><label for="female"><input id="female" type="radio" v-model="gender" value="female"> 女</label><h2>性别: {{gender}}</h2></div><hr><!-- 4.使用v-model实现select的双向绑定 --><!-- 4.1 select单选框的值绑定 --><select v-model="fruit"><option v-for="item in allFruits" :key="item.value" :value="item.value">{{item.text}}</option></select><h2>单选: {{fruit}}</h2><!-- 4.2 select多选框的值绑定 --><select multiple size="3" v-model="fruits"><option v-for="item in allFruits" :key="item.value" :value="item.value">{{item.text}}</option></select><h2>多选: {{fruits}}</h2><hr>
</div><script src="../lib/vue.js"></script>
<script>// 1.创建appconst app = Vue.createApp({data() {return {message: "Hello Model", //v-model绑定的input数据content: "", //v-model绑定的textarea数据isAgree: false, //v-model绑定的checkbox单选框数据 hobbies: [] //v-model绑定的checkbox多选框数据gender: "female" //v-model绑定的radio单选框数据fruit: "orange", //v-model绑定的select单选框数据fruits: [], //v-model绑定的select多选框数据allFruits: [{ value: "apple", text: "苹果" },{ value: "orange", text: "橘子" },{ value: "banana", text: "香蕉" },], // 水果}}})// 2.挂载appapp.mount("#app")
</script>
可以看到,使用v-model
的方式非常简单:
- 在支持
v-model
的表单输入元素上加上v-model
指令 - 在
Vue
的data
选项API
中定义数据变量,赋值给v-model
就实现了数据的双向绑定
这些也都是对基础的表单元素进行操作。实际开发大多会使用各种各样的组件库开发。
但是使用的方式和原理都是一样的。
2.2 v-model和值绑定:
所谓值绑定,其实并不是很高深的东西,只是Vue
官方提供的一个概念。
意思就是表单元素中的value
值并不是写死的,而是来自于服务器或者配置文件。
我们就可以先将值请求下来,绑定到data返回的对象中,
再使用条件渲染指令和列表渲染指令把值动态绑定到表单元素上,最后通过v-bind
指令来进行绑定。
这个过程就是值绑定。
例如上面代码中select
的绑定方式:
<div id="app"> <!-- select单选框的值绑定 --><select v-model="fruit"><option v-for="item in allFruits" :key="item.value" :value="item.value">{{item.text}}</option></select><h2>单选: {{fruit}}</h2></div><script src="../lib/vue.js"></script>
<script>// 1.创建appconst app = Vue.createApp({data() {return {fruit: "orange", //v-model绑定的select单选框数据 allFruits: [{ value: "apple", text: "苹果" },{ value: "orange", text: "橘子" },{ value: "banana", text: "香蕉" },], // 水果}}})// 2.挂载appapp.mount("#app")
</script>
在这段代码中,<select>
中<option>
的值并不是直接写死在表单元素上的。
它们的值来自allFruits
数组,这个数组可能来自于服务器或者配置文件。
这也是开发中常见的情况。
三、v-model的修饰符
3.1 v-model支持的修饰符:
.lazy
——监听change
事件而不是input
默认情况下,
v-model
在进行双向绑定时,绑定的是input事件。那么会在每次内容输入后就将最新的值和绑定的属性进行同步。
如果在
v-model
后跟上lazy
修饰符,那么会将绑定的事件切换为 change 事件。只有在提交(或者回车)时才会触发。
.number
——将输入的合法符串转为数字.trim
——移除输入内容两端空格
3.2 代码示例
<div id="app"><!-- 1.lazy: 绑定change事件 --><input type="text" v-model.lazy="message"><h2>message: {{message}}</h2><hr><!-- 2.number: 自动将内容转换成数字 --><!-- 这里有个冷知识:vue2.x中 如果input中输入的是数字,v-model也会自动把数字转为字符串,除非加上.number修饰符vue2.x中 如果input中输入的是数字,将可以直接获取到数字,而不用再加.number修饰符--><input type="text" v-model.number="counter"><h2>counter:{{counter}}-{{typeof counter}}</h2><input type="number" v-model="counter2"><h2>counter2:{{counter2}}-{{typeof counter2}}</h2><hr><!-- 3.trim: 去除收尾的空格 --><input type="text" v-model.trim="content"><h2>content: {{content}}</h2><hr><!-- 4.使用多个修饰符 --><input type="text" v-model.lazy.trim="content"><h2>content: {{content}}</h2>
</div><script src="../lib/vue.js"></script>
<script>// 1.创建appconst app = Vue.createApp({// data: option apidata() {return {message: "Hello Vue",counter: 0,counter2: 0,content: ""}},watch: {content(newValue) {console.log("content:", newValue)}}})// 2.挂载appapp.mount("#app")
</script>
四、手写v-model原理
官方文档中有提到,v-model
的原理其实是背后有两个操作:
v-bind
绑定value
属性的值v-on
绑定input
事件监听到函数中,函数会获取最新的值赋值到绑定的属性中
依旧上面的原理,可以手写一个v-model
的实现:
<div id="app"><!-- 手动的实现双向绑定:先使用v-bind语法糖把message绑定到input的value上再使用v-on语法糖绑定input元素的input事件--><input type="text" :value="message" @input="change">
</div><script src="../lib/vue.js"></script>
<script>// 1.创建appconst app = Vue.createApp({data() {return {message: "Hello Model"}},methods: {change(event) {// 获取当前input表单元素中的内容this.message = event.target.value}}})// 2.挂载appapp.mount("#app")
</script>
至于如果程序中的message
发送变化,Vue
会有另一部分代码监听数据的变化,并把变化的数据渲染到视图上。
再结合v-model
就完成了Vue
中数据的双向绑定。
五、v-model用于组件上
5.1 v-model在组件上的基本使用
通过上面的说明可以知道,表单元素上的v-model
使用方式如下:
<input v-model="searchText" />
上面的代码其实等价于下面这段 (编译器会对 v-model
进行展开):
<input:value="searchText"@input="searchText = $event.target.value"
/>
而当使用在一个组件上时,v-model
会被展开为如下的形式:
<CustomInput:modelValue="searchText"@update:modelValue="newValue => searchText = newValue"
/>
因此<CustomInput>
组件内部需要做两件事:
将内部原生
input
元素的value
属性绑定到modelValue
的prop
组件上输入新的值时在
input
元素上触发update:modelValue
事件
<!-- CustomInput.vue -->
<template><input:value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/>
</template><script>
export default {props: ['modelValue'],emits: ['update:modelValue']
}
</script>
5.2 自定义组件中处理v-model 的参数
默认v-model
在组件上都是使用 modelValue
作为 prop,并以 update:modelValue
作为对应的事件。
我们可以通过给 v-model
指定一个参数来更改这些名字。
<MyComponent v-model:title="bookTitle" />
此时子组件应声明一个 title
prop,并通过触发 update:title
事件更新父组件值:
<!-- MyComponent.vue -->
<template><inputtype="text":value="title"@input="$emit('update:title', $event.target.value)"/>
</template><script>
export default {props: ['title'],emits: ['update:title']
}
</script>
5.3 自定义组件中处理多个v-model 绑定
我们可以在一个组件上创建多个 v-model
双向绑定,每一个 v-model
都会同步不同的prop
。
<UserNamev-model:first-name="first"v-model:last-name="last"
/>
<script>
export default {props: {firstName: String,lastName: String},emits: ['update:firstName', 'update:lastName']
}
</script><template><inputtype="text":value="firstName"@input="$emit('update:firstName', $event.target.value)"/><inputtype="text":value="lastName"@input="$emit('update:lastName', $event.target.value)"/>
</template>
5.4 自定义组件中处理 v-model 修饰符
v-model
有一些内置的修饰符。例如 .trim
,.number
和 .lazy
。
在某些场景下,你可能想要一个自定义组件的 v-model
支持自定义的修饰符。
例如创建一个自定义的修饰符 capitalize
,它会自动将 v-model
绑定输入的字符串值第一个字母转为大写:
<MyComponent v-model.capitalize="myText" />
组件的 v-model
上所添加的修饰符,可以通过 modelModifiers
prop 在组件内访问到。
在下面的组件中,声明了 modelModifiers
这个 prop
,它的默认值是一个空对象:
<script>
export default {props: {modelValue: String,modelModifiers: {default: () => ({})}},emits: ['update:modelValue'],created() {console.log(this.modelModifiers) // { capitalize: true }}
}
</script><template><inputtype="text":value="modelValue"@input="$emit('update:modelValue', $event.target.value)"/>
</template>
注意:
组件
prop
中的modelModifiers
的 包含了capitalize
且其值为true
。因为它在模板中的
v-model
绑定上被使用了。
有了 modelModifiers
这个 prop,我们就可以在原生事件侦听函数中检查它的值。
然后决定触发的自定义事件中要向父组件传递什么值。
<script>
export default {props: {modelValue: String,modelModifiers: {default: () => ({})}},emits: ['update:modelValue'],methods: {emitValue(e) {let value = e.target.value// 如果有capitalize的值为true,则做一些对应的操作if (this.modelModifiers.capitalize) {value = value.charAt(0).toUpperCase() + value.slice(1)}this.$emit('update:modelValue', value)}}
}
</script><template><input type="text" :value="modelValue" @input="emitValue" />
</template>
对于又有参数又有修饰符的 v-model
绑定,生成的 prop 名将是 arg + "Modifiers"
。
示例:
<MyComponent v-model:title.capitalize="myText">
export default {props: ['title', 'titleModifiers'],emits: ['update:title'],created() {console.log(this.titleModifiers) // { capitalize: true }}
}
六、v-model官方文档
https://cn.vuejs.org/api/built-in-directives.html#v-model
Vue基础--Vue中的双向绑定v-model指令相关推荐
- vue基础小节 v-mode属性双向绑定 跑马灯 十秒挑战 计算器 v-for和key属性 v-if与v-show用法区别 tap切换
vue代码基本结构 <!-- 视图层 --><div class="app"><!-- 差值表达式 --><div>{{mge}} ...
- Vue之组件间的双向绑定
何为组件间双向绑定 我们都知道当父组件改变了某个值后,如果这个值传给了子组件,那么子组件也会自动跟着改变,但是这是单向的,使用v-bind的方式,即子组件可以使用父组件的值,但是不能改变这个值.组件间 ...
- vue与elementUI中给el-input绑定键盘按键--按键修饰符
vue怎么写键盘事件 vue允许将按键值作为修饰符来使用,如监听回车事件,有两种写法,如下代码: <input type="text" @keyup.13="con ...
- react中的双向绑定
前言:因为项目原因需要学习另一个超级火的框架react, 因为之前一直使用vue进行开发,所以在学习react中会不自觉的代入一些vue中的概念来理解react中的实现,下面就通过对比学习的方式记录下 ...
- iviewUI组件库中select双向绑定不生效
前端小伙伴们有没有遇到过这样的场景,iviewUI组件库中select双向绑定数据时,修改了绑定值,但是页面中渲染的值还是之前的值,不管是去打印还是使用vue插件去查看变量,均显示绑定值已修改,可是页 ...
- Vue 中实现双向绑定的 4 种方法
1. v-model 指令 <input v-model="text" /> 复制代码 上例不过是一个语法糖,展开来是: <input:value="t ...
- VUE 入坑系列 一 双向绑定
html代码 <div id="app"><p>{{message}}</p><span>message1</span> ...
- vue.js 入门案例,双向绑定实现任务清单
vue.js 开发环境安装成功. http://localhost:8080/ 使用vue.js双向绑定实现类似这样一个任务清单页面. 下面是我的学习笔记. //app.vue页面 <templ ...
- Vue是怎么实现数据双向绑定的
vue数据双向绑定原理 vue数据双向绑定是通过数据劫持结合发布者-订阅者模式的方式来实现的,那么vue是如果进行数据劫持的,我们可以先来看一下通过控制台输出一个定义在vue初始化数据上的对象是个什么 ...
最新文章
- python中二进制以什么开头_Python二进制表示和位操作
- 瘫痪小姐姐“自主”行走视频火了,曾借助轮椅完成舞蹈表演,网友:灵魂是战士...
- 记录几个vim的命令
- Python3.X新特性之print和exec
- 提升销售人员的信息处理能力
- OpenCASCADE:拓扑 API之历史支持
- OpenLiberty:注入时出错,适用于TomEE和Wildfly
- .rpt文件内容读取java_好程序员前端教程-nodejs如何读取文件夹目录的内容
- 地震与地球的内部构成
- 【机器学习】隐马尔可夫模型及其三个基本问题(三)模型参数学习算法及python实现
- JS中var和let
- JAVA程序打包为EXE
- 一线顶级互联网公司offer的成功经验【转自IT面试】
- 大数据可视化(七)复杂数据可视化
- 引力波数据居然是用 Python 分析的
- 移动端某些网络下域名无法解析的DNS问题
- SpringAOP实现报错Bean named ‘userServiceImpl‘ is expected to be of type ‘.....‘
- 第三届上海大学生网络安全大赛 - 登机牌WP
- python彼岸图网爬取1200像素预览图
- MySQL入门实战 一