一、 双向绑定:
问题: 使用传统的:value绑定表单元素的内容时,虽然界面中更新了表单元素的内容,但是程序中的变量里却无法获得新的表单元素内容。
原因: 单向绑定: 只能将程序中的变量值,更新到页面中显示。无法实时将页面中的修改的新值,反向更新回程序中的变量里。(只能从Model->View,不会从View->Model)比如: :value就是一种单向绑定.
解决: vue中其实提供了双向绑定的方式:
1). 什么是双向绑定: 既能将程序中的变量值,更新到页面中显示。又能实时将页面中的修改的新值,反向更新回程序中的变量里。(既能从Model->View,又能从View->Model)
2). 何时: 今后,只要想实时获得/收集用户在界面上输入或选择的表单元素的新值时,都要用双向绑定。
3). 如何: <表单元素 v-model="变量">
view->model
4). 结果: 只要界面上用户修改了表单元素的值,v-model就会立刻自动将新表单元素值更新回程序中data中的变量里保存。-
示例: 使用双向绑定实现点按钮搜索
v-model.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--VUE 3步
1. 做界面
1.1 唯一父元素包裹
1.2 找可能发生改变的位置
本例中: 只有文本框的内容可能发生变化,所以用:value来绑定文本框的内容。
1.3 找触发事件的元素
本例中: 点按钮触发事件,执行搜索操作-->
<div id="app">
<input v-model="str">
<button @click="search">百度一下</button>
</div>
<script>
//2. 创建new Vue()对象, 监视id为app的区域
var vm=new Vue({
el:"#app",
//3. 创建模型对象:
//3.1 创建data对象
//本例中: 因为界面中只需要一个变量,所以
data:{
str:"" //保存用户在界面上文本框中输入的内容。开局,内容为""
},
//3.2 创建methods对象
//本例中: 因为界面中只需要一个事件处理函数,所以
methods:{
search(){
if(this.str!==""){
console.log(`搜索${this.str}相关的内容...`);
}
}
}
})
</script>
</body>
</html>
运行结果:
5. 原理: 双向绑定的原理: 自动绑定input或change事件+访问器属性+虚拟DOM树
(1). v-model会自动给表单元素绑定input或change事件
(2). 每当界面中表单元素的值发生改变时,就能自动调用事件处理函数。
(3). 在事件处理函数中,可以获得当前表单元素的内容,实时赋值给data中的变量。
(4). 示例: 使用:value和事件模拟实现双向绑定:
_v-model2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--VUE 3步
1. 做界面
1.1 唯一父元素包裹
1.2 找可能发生改变的位置
本例中: 只有文本框的内容可能发生变化,所以用:value来绑定文本框的内容。
1.3 找触发事件的元素
本例中: 点按钮触发事件,执行搜索操作-->
<div id="app">
<!--DOM中每个文本框都有一个input事件
每当在文本框中输入或删除了内容时就会实时触发。-->
<input :value="str" @input="input">
<button @click="search">百度一下</button>
</div>
<script>
//2. 创建new Vue()对象, 监视id为app的区域
var vm=new Vue({
el:"#app",
//3. 创建模型对象:
//3.1 创建data对象
//本例中: 因为界面中只需要一个变量,所以
data:{
str:"" //保存用户在界面上文本框中输入的内容。开局,内容为""
},
//3.2 创建methods对象
//本例中: 因为界面中只需要一个事件处理函数,所以
methods:{
input(e){
//DOM中:
//当前文本框的内容
//赋值给
//data中的str
this.str=e.target .value
},
search(){
if(this.str!==""){
console.log(`搜索${this.str}相关的内容...`);
}
}
}
})
</script>
</body>
</html>
运行结果:
6. 按回车执行搜索: vue中的事件修饰符:
(1). 问题: @keyup可以为元素绑定键盘按下后抬起事件。但是,任何按键都可以触发这个事件。不是我们想要的!我们希望只有按回车键时才能触发事件。
(2). 解决: vue中专门定义了事件修饰符用来限制事件的行为:
比如: @keyup.13="事件处理函数"
只限于按13号键/回车键时才能触发事件。
- watch: (监视)
(1). 什么是: 专门在变量值被修改时自动执行一项任务的特殊监视函数.
(2). 何时: 今后,只要希望一个变量的值一改变,就能立刻执行一个操作时。都用watch
(3). 如何:
new Vue({
el:"#app",
data:{ 变量名: 值, ... },
methods:{},
watch:{
变量名(){
}
}
})
- 示例: 实现按回车搜索和一边输入一边执行搜索
_v-model3.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--VUE 3步
1. 做界面
1.1 唯一父元素包裹
1.2 找可能发生改变的位置
本例中: 希望文本框内容改变,程序中变量自动接到新值,就必须用v-model双向绑定.
1.3 找触发事件的元素
本例中: 点按钮触发事件,执行搜索操作-->
<div id="app">
<input v-model="str" @keyup.13="search">
<button @click="search">百度一下</button>
</div>
<script>
//2. 创建new Vue()对象, 监视id为app的区域
var vm=new Vue({
el:"#app",
//3. 创建模型对象:
//3.1 创建data对象
//本例中: 因为界面中只需要一个变量,所以
data:{
str:"" //保存用户在界面上文本框中输入的内容。开局,内容为""
},
//3.2 创建methods对象
//本例中: 因为界面中只需要一个事件处理函数,所以
methods:{
search(){
if(this.str!==""){
console.log(`搜索${this.str}相关的内容...`);
}
}
},
//因为希望str变量值一变,立刻自动执行搜索操作
watch:{
str(){
this.search();
}
}
})
</script>
</body>
</html>
运行结果:
9. 不同表单元素上的双向绑定效果:
(1). 文本框/textarea :
v-model会自动获得value属性值,并自动更新回程序中data中的变量里保存。
(2). 单选按钮(radio):
a. 特点: 一组单选按钮有多个radio组成。且每个radio的value值都是固定写死的。
b. 如何: 要在每个备选的radio中都写上v-model=sex
<input type="radio" name="sex" value="1" v-model="sex">男
<input type="radio" name="sex" value="0" v-model="sex">女
c. 原理:
1). html中,一组相同name名的radio,只能选一个
2). v-model每次只会把选中的一个radio的value值自动更新回程序中变量里。
3). 如果程序中的变量值改变,也会影响页面上radio的选中状态。v-model会取回变量值和当前radio的value值做比较。哪个radio的value值与变量值相等,哪个radio就选中。
d. 示例: 选择性别:
_v-model_radio.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<div id="app">
性别: <input type="radio" name="sex" value="1" v-model="sex">男
<input type="radio" name="sex" value="0" v-model="sex">女
<br/>
<h3>您选择的性别是:{{sex}}</h3>
</div>
<script>
new Vue({
el:"#app",
data:{
sex:1
}
})
</script>
</body>
</html>
运行结果:
(3). select:
a. 特点:
1). 一个select元素,包含多个option元素
2). select元素中每个value值也都是在每个option上写死的!
b. 如何: v-model只写在select元素上一份即可!
<select v-model="变量">
<option value="备选值1">xxx</option>
<option value="备选值2">xxx</option>
<option value="备选值3">xxx</option>
c. 原理:
1). 首次加载页面时: v-model读取出变量的当前值和每个option的value值作比较。哪个option的value值与变量值相等,select就选中哪个option
2). 每当用户切换了select下的选中项时,v-model只会将选中的一个option的value值自动更新回程序中data中变量里保存。
d. 示例:选择城市,显示城市图片
_v-model_select.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--VUE 3步
1. 做界面
1.1 唯一父元素
1.2 找可能发生变化的位置:
本例中: 2处:
select的选中项会被用户主动改变,所以,应该用双向绑定
img元素的src属性值会被程序自动改变,所以,应该用单向绑定-->
<div id="app">
请选择城市: <select id="sel" v-model="src">
<option value="img/bj.jpg">北京</option>
<option value="img/sh.jpg">上海</option>
<option value="img/hz.jpg">杭州</option>
</select><br/>
<br/>
<br/>
<img style="width:300px" :src="src">
</div>
<script>
//2. 创建new Vue()对象
new Vue({
el:"#app",
//3. 创建模型对象
//本例中: 界面中虽然有两处变化,但是,两处变化用的是同一个变量。
data:{
src:"img/bj.jpg"
}
})
</script>
</body>
</html>
运行结果:
(4). checkbox单用:
a. 特点: 没有value属性。用户选中与不选中改的是checked属性。
b. 如何: <input type="checkbox" v-model="变量">
c. 原理:
1). v-model直接操作和读取checked属性
2). 首次加载页面时,v-model读取变量值。如果变量值为true,则当前checkbox选中。如果变量值为false,则当前checkbox不选中
3). 当用户切换了选中状态,则v-model会直接将checked属性值更新回程序中data中变量里。且值还是bool类型的true或false。
d. 示例: 点同意,启用元素:
_v-model_checkbox.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/vue.js"></script>
</head>
<body>
<!--VUE 3步
1. 做界面
1.1 唯一父元素
1.2 找可能发生变化的位置:
本例中: 2大类情况
checkbox自己的checked状态会被用户主动改变,所以应该用v-model绑定
其它三个表单元素的disabled属性会被程序自动改变,所以应该用:单向绑定。
又因为选中checkbox会影响其它元素的disabled,所以,checkbox和其它元素的disabled属性使用的是同一个变量。
-->
<div id="app">
<br/>
用户名:<input :disabled="!agree"><br/>
<br/>
密码:<input :disabled="!agree" type="password"><br/>
<br/>
<input type="checkbox" v-model="agree">同意<br/>
<br/>
<button :disabled="!agree">注册</button>
</div>
<script>
//2. 创建new Vue()对象
new Vue({
el:"#app",
//3. 创建模型对象
//本例中: 界面上只需要一个变量agree
data:{
agree:false, //表示用户是否同意,开局,默认为不同意
}
})
</script>
</body>
</html>
运行结果: