第二章 Vue核心技术
2.1 Vue 入门开发
2.1.1 创建工程
-
在本地创建文件夹
D:\StudentProject\WebStudy
-
打开
VS Code
,点击File > Open Folder
, 找到D:\StudentProject\WebStudy
打开 -
单击
WEBSTUDY
右侧的新建目录图标,创建目录:vue-01-core
)]
2.1.2 创建 HTML 和 安装 vue 模块
-
在 vue-01-core 目录下新建一个页面
01-helloworld.html
-
在 vue-01-core 目录下的命令行窗口,安装2.6.10版本的 vue 模块
npm install vue@2.6.10
2.1.3 编写 HTML 页面
-
编写步骤:
1.采用
<script>
标签引入 vue.js 库2.定义一个
3.
new Vue()
实例化Vue应用程序el
选项: 元素element的缩写,指定被 Vue 管理的 Dom 节点入口(值为选择器 ),必须是一个普通的HTML 标签节点,一般是 div。
data
选项:指定初始化数据,在 Vue 所管理的 Dom 节点下,可通过模板语法来进行使用4.标签体显示数据:
{{xxxxx}}
5.表单元素双向数据绑定:
v-model
6.注意: el 的值不能为 html 或 body
-
源码实现:
<body> <div id="app"> hello,{{ msg }} <br> <input type="text" v-model="msg"> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> var vm = new Vue( { el : '#app', //el 的值不能为 html 或 body data:{ msg:'vue.js123' } } ); </script> </body>
2.2 分析 MVVC 模型
常见面试题:什么是 MVVM 模型?
MVVM
是 Model-View-ViewModel 的缩写,它是一种软件架构风格- Model :模型,数据对象(data选项当中的)
- View :视图,模板页面(用于渲染数据)
- ViewModel:视图模型,其实本质上就是 Vue 实例
- 它的哲学思想是:
- 通过数据驱动视图
- 把需要改变视图的数据初始化到 Vue中,然后再通过修改 Vue 中的数据,从而实现对视图的更新。
- 声明式编程
- 按照 Vue 的特定语法进行声明开发,就可以实现对应功能,不需要我们直接操作Dom元素
- 命令式编程
- Jquery它就是,需要手动去操作Dom才能实现对应功能。
2.3 Vue Devtools 插件安装
Vue Devtools 插件让我们在一个更友好的界面中审查和调试 Vue 项目。
- 谷歌浏览器访问:
chrome://extensions
,然后右上角打开 开发者模式 , 打开的效果如下
-
将 直接拖到上面页面空白处,会自动安装
-
效果如下则安装成功
-
当你访问Vue开发的页面时,按 F12 有 Vue 标签页.就表示安装成功了
2.4 模板数据绑定渲染
可生成动态的HTML页面,页面中使用嵌入 Vue.js 语法可动态生成
{{ xxxx }}
双大括号文本绑定v-xxxx
以v-
开头用于标签属性绑定,称为指令
在 vue-01-core 目录下新建一个页面: 02-模板数据绑定渲染.html
2.4.1 双大括号语法 {{ }}
- 格式 : {{ 表达式 }}
- 作用 :
- 使用在标签体中,用于获取数据
- 可以使用 JavaScript 表达式
- 案例源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<h3>1.双大括号输出文本内容</h3>
<!-- 普通文本 -->
<p>{{ message }}</p>
<!-- 使用js表达式 -->
<p>Js表达式: {{score+1}}</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 元素element的缩写,指定被 Vue 管理的 Dom 节点入口(值为选择器 ),
//必须是一个普通的HTML 标签节点,一般是 div。
var vm = new Vue({ //这里Vue是大写的,跟java一样 严格区分大小写
el: '#app', //被 Vue 管理的 Dom 节点入口(值为选择器 ),
data:{
message:"hhahh",
score:100
}
});
</script>
</body>
</html>
2.4.2 一次性插值 v-once
- 通过使用 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新。
<h3>2.一次性插值 </h3>
<p v-once>这个不会改变 : {{ message }}</p>
2.4.3 输出HTML指令 v-html
-
格式:
v-html='xxxx'
-
作用:
-
如果是HTML格式数据,双大括号会将数据解释为普通文本,为了输出真正的 HTML,你需要使用 v-html指令。
-
Vue 为了防止 XSS 攻击,在此指令上做了安全处理,当发现输出内容有 script 标签时,则不渲染
-
XSS 攻击主要利用 JS 脚本注入到网页中,读取 Cookie 值(Cookie一般存储了登录身份信息),读取
到了发送到黑客服务器,从而黑客可以使用你的帐户做非法操作。
-
XSS 攻击还可以在你进入到支付时,跳转到钓鱼网站。
-
-
<body>
<div id="app">
<h3>3.指令输出真正的html内容 v-html</h3>
<p>双大括号 : {{contentHtml}}</p>
<!--
v-html:
1.如果输出的内容是Html数据,双大括号将数据以普通文本方式输出,
为了输出真正的html效果,就需要使用v-html 指令
2.还可以防止 xss 攻击
-->
<p>使用 v-html : <span v-html="contentHtml"> </span></p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app', //被 Vue 管理的 Dom 节点入口(值为选择器 ),
data:{
contentHtml:`<span style="color:red">此内容为红色字体
<script>alert('hahhah') <\/script>
</span>`
}
});
</script>
</body>
- 效果图
2.4.4 元素绑定指令 v-bind
-
完整格式: v-bind:元素的属性名=‘xxxx’
-
缩写格式: :元素的属性名=‘xxxx’
-
作用:将数据动态绑定到指定的元素上
源码:
<div> <h3>v-bind 属性绑定指令</h3> <img v-bind:src="imgUrl" alt="VueLogo"> <!-- 简写 --> <img :src="imgUrl" alt="VueLogo"> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> var vm = new Vue({ el: '#app', //被 Vue 管理的 Dom 节点入口(值为选择器 ), data:{ imgUrl: 'https://vuejs.org/images/logo.png' } }); </script>
-
效果图
2.4.5 事件绑定指令 v-on
- 完整格式:
v-on:事件名称="事件处理函数名"
- 缩写格式:
@事件名称="事件处理函数名"
注意:@
后面没有冒号 - 作用:用于监听 DOM 事件
- 案例源码:
每点击1次,数据就加1
<h3>5. v-on 事件绑定指令 </h3>
<input type="text" value="1" v-model="num">
<button v-on:click="add">点击+1</button>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
var vm = new Vue({ //这里Vue是大写的,跟java一样 严格区分大小写
el: '#app', //被 Vue 管理的 Dom 节点入口(值为选择器 ),
data:{
num:1
},
methods: { //指定事件处理方法,在模板页面中通过 v-on :事件名 来调用
add:function(){ //key 为方法名
console.log("点击+1");
//this 表示当前 vm 实例
this.num ++ //每次点击都加1
}
},
});
</script>
- 效果图
2.4.6 完整源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Vue-模板数据绑定渲染</title>
</head>
<body>
<div id="app">
<h3>1.双大括号输出文本内容</h3>
<!-- 普通文本 -->
<p>{{ message }}</p>
<!-- 使用js表达式 -->
<p>Js表达式: {{score+1}}</p>
<h3>2.一次性插值 </h3>
<p v-once>这个不会改变 : {{ message }}</p>
<h3>3.指令输出真正的html内容 v-html</h3>
<p>双大括号 : {{contentHtml}}</p>
<!--
v-html:
1.如果输出的内容是Html数据,双大括号将数据以普通文本方式输出,
为了输出真正的html效果,就需要使用v-html 指令
2.还可以防止 xss 攻击
-->
<p>使用 v-html : <span v-html="contentHtml"> </span></p>
<h3>4.v-bind 属性绑定指令</h3>
<img v-bind:src="imgUrl" alt="VueLogo">
<!-- 简写 -->
<img :src="imgUrl" alt="VueLogo">
<h3>5. v-on 事件绑定指令 </h3>
<input type="text" value="1" v-model="num">
<button v-on:click="add">点击+1</button>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
// 元素element的缩写,指定被 Vue 管理的 Dom 节点入口(值为选择器 ),
//必须是一个普通的HTML 标签节点,一般是 div。
var vm = new Vue({ //这里Vue是大写的,跟java一样 严格区分大小写
el: '#app', //被 Vue 管理的 Dom 节点入口(值为选择器 ),
data:{
message:"hhahh",
score:100,
//asdf
//asdf
contentHtml:`<span style="background:red">此内容为红色字体
<script>alert('hahhah') <\/script>
</span>`,
imgUrl: 'https://vuejs.org/images/logo.png',
num:1
},
methods: { //指定事件处理方法,在模板页面中通过 v-on :事件名 来调用
add:function(){ //key 为方法名
console.log("点击+1");
//this 表示当前 vm 实例
this.num ++ //每次点击都加1
}
},
});
</script>
</body>
</html>
2.5 计算属性和监听器
在 vue-01-core
目录下新建一个页面 03-计算属性和监听器.html
2.5.1 计算属性 computed
-
computed
选项定义计算属性 -
计算属性 类似于
methods
选项中定义的函数- 计算属性 会进行缓存,只在相关响应式依赖发生改变时它们才会重新求值。
- 函数 每次都会执行函数体进行计算。
-
需求:输入数学与英语分数,采用
methods
与computed
分别计算出总得分 -
案例源码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> 数学:<input type="text" v-model="mathScore"> 英语:<input type="text" v-model="englishScore"><br> <!-- 注意:函数不能少 括号 --> 总成绩(函数单向绑定):<input type="text" v-model="sumScore()"><br> 总成绩(计算属性 - 单向绑定):<input type="text" v-model="sumScore1"><br> 总成绩(计算属性 - 双向绑定):<input type="text" v-model="sumScore2"><br> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> var vm = new Vue({ el:'#app', data:{ mathScore:80, englishScore:100, }, methods: {//不要少了 s sumScore:function(){ console.log("函数被调用了"); //如果得出的结果是 80100,那么就要将字符串强转为数值 //在控制台输入 vm.sumScore() 每次都会调用 //(this.mathScore-0)+(this.englishScore-0); return (this.mathScore-0)+(this.englishScore-0); } }, computed: { //具有缓存的作用,当监听的两个值,没有改变时,就不会再计算 sumScore1:function(){ //在控制台输入 vm.sumScore1 没有改变时,就不会再计算 console.log("计算属性被调用了"); return (this.mathScore-0)+(this.englishScore-0); }, // 指定 get / set 双向绑定 sumScore2 : { get:function(){ console.log("计算属性 sumScore2 被调用get方法了"); return (this.mathScore-0)+(this.englishScore-0); }, set: function(newValue){ // 为更新后的值 console.log("计算属性 sumScore2 被调用 set 方法了"); var avg = newValue / 2; this.mathScore = avg ; this.englishScore = avg ; } } } }) </script> </body> </html>
computed
选项内的计算属性默认是 getter 函数,所以上面只支持单向绑定,当修改数学和英语的数据才会更新总分,而修改总分不会更新数据和英语
2.5.2 计算属性(双向绑定)
- 计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter
代码如上:
2.5.3 监听器 watch
-
当属性数据发生变化时,对应属性的回调函数会自动调用, 在函数内部进行计算
-
通过
watch
选项 或者 vm 实例的$watch()
来监听指定的属性 -
需求:
1.通过 watch 选项 监听数学分数, 当数学更新后回调函数中重新计算总分sumScore3
2.通过 vm.$watch() 选项 监听英语分数, 当英语更新后回调函数中重新计算总分sumScore3
注意: 在data 选择中添加一个 sumScore3 属性
<body>
<div id="app">
数学:<input type="text" v-model="mathScore">
英语:<input type="text" v-model="englishScore"><br>
<!-- 注意:函数不能少 括号 -->
总成绩(函数单向绑定):<input type="text" v-model="sumScore()"><br>
总成绩(计算属性 - 单向绑定):<input type="text" v-model="sumScore1"><br>
总成绩(计算属性 - 双向绑定):<input type="text" v-model="sumScore2"><br>
总成绩(监听器):<input type="text" v-model="sumScore3"><br>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el:'#app',
data:{
mathScore:80,
englishScore:100,
sumScore3:0
},
methods: {//不要少了 s
sumScore:function(){
console.log("函数被调用了");
//如果得出的结果是 80100,那么就要将字符串强转为数值
//在控制台输入 vm.sumScore() 每次都会调用
//(this.mathScore-0)+(this.englishScore-0);
return (this.mathScore-0)+(this.englishScore-0);
}
},
computed: { //具有缓存的作用,当监听的两个值,没有改变时,就不会再计算
sumScore1:function(){
//在控制台输入 vm.sumScore1 没有改变时,就不会再计算
console.log("计算属性被调用了");
return (this.mathScore-0)+(this.englishScore-0);
},
// 指定 get / set 双向绑定
sumScore2 : {
get:function(){
console.log("计算属性 sumScore2 被调用get方法了");
return (this.mathScore-0)+(this.englishScore-0);
},
set: function(newValue){ // 为更新后的值
console.log("计算属性 sumScore2 被调用 set 方法了");
var avg = newValue / 2;
this.mathScore = avg ;
this.englishScore = avg ;
}
}
},
//监听器方式 1: watch 选项
watch: {
//当数学修改后,更新总分 sumScore3
mathScore : function (newValue , oldValue){
//newValue 就是新输入的数学
console.log("执行数学监听");
this.sumScore3 = (newValue - 0) + (this.englishScore - 0);
}
}
})
//通过 vm 实例 监听英语
// 第一个值 监听的属性名 第二个值 回调函数
vm.$watch('englishScore', function(newValue){
//newValue 就是新输入的英语得分
this.sumScore3 = (newValue-0) + (this.mathScore-0)
})
//如果想使用 watch 搞双向绑定的话
vm.$watch('sumScore3', function(newValue){
var avg = newValue / 2
this.mathScore = avg
this.englishScore = avg
})
</script>
</body>
</html>
2.6 Class 与 Style 绑定 v-bind
通过 class 列表和 style 指定样式是数据绑定的一个常见需求。它们都是元素的属性,都用 v-bind 处理,其中表达式 结果的类型可以是:字符串、对象或数组。
2.6.1 语法格式
v-bind:class='表达式'
或:class='表达式'
- class 的表达式可以为:
- 字符串
:class="activeClass"
- 对象
:class="{active: isActive, error: hasError}"
- 数组
:class="['active', 'error']" 注意要加上单引号,不然是获取data中的值
- 字符串
- class 的表达式可以为:
v-bind:style='表达式'
或:style='表达式'
- style 的表达式一般为对象
:style="{color: activeColor, fontSize: fontSize + 'px'}"
- 注意:对象中的value值 activeColor 和 fontSize 是data中的属性
2.6.2 案例源码
在 vue-01-core
目录下新建一个页面 04-Class与Style绑定.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<style>
.active{
color: green
}
.delete{
background-color: red
}
.error{
font-size: 30px
}
</style>
<body>
<div id="app">
<h3>Class绑定,v-bind:class 或者 :class</h3>
<!--activeClass会从data中获取值为active,则对应样式为绿色-->
<p v-bind:class="activeClass">字符串表表达式</p>
<!-- isDelete为 true,渲染delete样式;当 hasError为false,不取 error 样式;-->
<p :class="{delete: isDelete, error: hasError}">对象表达式</p>
<!--- 渲染 'active', 'error' 样式,注意要加上单引号,不然是获取data中的值 -->
<p :class="['active', 'error']">数组表达式</p>
<h3>Style绑定, v-bind:style 或 :class</h3>
<!--- 注意:font-size 要写成 fontSize 不然要报错,运行不了 -->
<p :style="{color: activeColor, fontSize: fontSize + 'px'}">Style绑定</p>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
isDelete: true,
hasError: true,
//演示 Style 绑定
activeColor: 'red',
fontSize: 100
}
})
</script>
</body>
</html>
2.7 条件渲染 v-if
2.7.1 条件指令
v-if
是否渲染当前元素v-else
v-else-if
v-show
与 v-if类似
,只是元素始终会被渲染并保留在 DOM 中,只是简单切换元素的 CSS 属性 display 来显示或隐藏
2.7.2 案例源码
在 vue-01-core
目录下新建一个页面 05-条件渲染.html
-
效果图:
-
源码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> .box { width: 200px; height: 200px; background-color: red; } </style> </head> <body> <div id="app"> <h2>v-if 条件渲染</h2> <input v-model="seen" type="checkbox">勾选后显示红色小块 <!-- v-if显示的效果图 --> <div v-if="seen" class="box"></div> <!-- v-show 条件渲染 --> <h2>v-show 条件渲染</h2> <div v-show="seen" class="box"></div> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> var vm = new Vue({ el: '#app', data: { seen:true } }) </script> </body> </html>
2.7.3 v-if 与 v-show 比较
-
什么时候元素被渲染
v-if
如果在初始条件为假,则什么也不做,每当条件为真时,都会重新渲染条件元素v-show
不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换 -
使用场景选择
v-if
有更高的切换开销,v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行后条件很少改变,则使用 v-if 较好。
2.8 列表渲染 v-for
2.8.1 列表渲染指令
- v-for 迭代数组
- 语法:
v-for="(alias, index) index array"
- 说明:
alias
:数组元素迭代的别名 ;index
:数组索引值从0开始(可选)。
- 语法:
- v-for 迭代对象的属性
- 语法:
v-for="(value, key, index) in Object"
- 说明:
value
: 每个对象的属性值;key
: 属性名(可选);index
: 索引值(可选) 。 - 注意: 在遍历对象时,是按 Object.keys() 的结果遍历,但不能保证它的结果在不同的 JavaScript 引擎
下是顺序一致的。
- 语法:
- 可用 of 替代 in 作为分隔符
2.8.2 案例源码
在 vue-01-core 目录下新建一个页面 06-列表渲染.html
<div id="app">
<ul>
<!-- e 代表的是数组的别名,index代表的是 数组的下标 ,从0开始的
注意:使用 key 特殊属性 ,它会基于 key 的变化重新排序,并且 会移除 不存在的key
:key 或者 是 v-bind:key
-->
<li v-for="(e,index) in emps" >
编号:{{index+1}}, 姓名:{{e.name}},工资:{{e.salary}}
</li>
</ul>
<p>遍历对象,这个用的很少</p>
<ul>
<li v-for="(value, key, index) in person">
第{{index+1}}个的属性为:{{key}} == {{value}}
</li>
</ul>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
//这里是数组
emps: [
{name: '张三',salary: '20000'},
{name: '李四',salary: '10000'},
{name: '王五',salary: '12000'}
],
// 这里是对象
person: {
name: '小李',
age: 22
}
}
})
</script>
2.9 事件处理 v-on
在 vue-01-core 目录下新建一个页面 07-事件处理.html
2.9.1 事件处理方法
-
完整格式:
v-on:事件名="函数名"
或v-on:事件名="函数名(参数……)"
-
缩写格式:
@事件名="函数名"
或@事件名="函数名(参数……)"
注意:@
后面没有冒号 -
event
:函数中的默认形参,代表原生 DOM 事件- 当调用的函数,有多个参数传入时,需要使用原生DOM事件,则通过
$event
作为实参传入
- 当调用的函数,有多个参数传入时,需要使用原生DOM事件,则通过
-
作用:用于监听 DOM 事件
-
<div id="app"> <h1>事件处理方法</h1> <button @Click="say">Say:{{msg}}</button> <h1>多参数使用原生参数dom的时候</h1> <button @click="warn('infoabcsw',$event)">Warn</button> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> new Vue({ el:'#app', data: { msg:"hello,vue.js" }, methods: { say:function(event){ //this代表当前的实例 alert(this.msg) //event 是原生的dom 事件 alert(event.target.innerHTML) }, warn:function(info, event){ alert(info); //获得当前原生的元素的节点信息 alert(info + ',' + event.target.tagName); //获得当前元素节点的内容信息 alert(event.target.innerHTML); } } }) </script>
2.9.2 事件修饰符
-
.stop
阻止单击事件继续传播event.stopPropagation()
-
.prevent
阻止事件默认行为event.preventDefault()
-
.once
点击事件将只会触发一次<div id="app"> <h1>事件处理方法</h1> <button @Click="say">Say:{{msg}}</button> <h1>多参数使用原生参数dom的时候</h1> <button @click="warn('infoabcsw',$event)">Warn</button> <h2>2. 事件修饰符</h2> <!--单击事件继续传播--> <div @click="todo"> <!--点击后会调用doThis再调用todo--> <button @click="doThis">单击事件会继续传播</button> </div> <br /> <!-- 阻止单击事件继续传播,--> <div @click="todo"> <!--点击后只调用doThis--> <button @click.stop="doThis">阻止单击事件会继续传播</button> </div> <!-- 阻止事件默认行为 --> <a href="http://www.mengxuegu.com" @click.prevent="doStop">梦学谷官网</a> <!-- 点击事件将只会触发一次 --> <button @click.once="doOnly">点击事件将只会触发一次: {{num}}</button> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: "hello,vue.js", num:1 }, methods: { say: function (event) { //this代表当前的实例 alert(this.msg) //event 是原生的dom 事件 alert(event.target.innerHTML) }, warn: function (info, event) { alert(info); //获得当前原生的元素的节点信息 alert(info + ',' + event.target.tagName); //获得当前元素节点的内容信息 alert(event.target.innerHTML); }, todo: function () { alert("todo...."); }, doThis: function () { alert("doThis...."); }, doStop: function () { alert("href默认跳转被阻止....") }, doOnly: function () { this.num++ } } }) </script>
2.9.3 按键修饰符
- 格式:
v-on:keyup.按键名
或@keyup.按键名
- 常用的按键名
.enter
.tab
.delete(捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
- 格式:
-
源码实现
<div id="app"> <h3>3.按键修饰</h3> <input type="text" @keyup.enter="keyEnter"> <!--进入输入框后按回车调用keyEnter--> <input type="text" @keyup.space="keySpace"> <!--进入输入框后按空格调用keySpace--> </div> <script src="./node_modules/vue/dist/vue.js"></script> <script> new Vue({ el: '#app', methods: { keyEnter: function(){ alert("已经按了回车键") }, keySpace: function(){ alert("已经按了空格键") } } }) </script>
2.10 表单数据双向绑定v-model
- 单向绑定:数据变,视图变;视图变(浏览器控制台上更新html),数据不变;上面的都是单向绑定
- 双向绑定:数据变,视图变;视图变(在输入框更新),数据变;
2.10.1 基础用法
v-model
指令用于表单数据双向绑定,针对以下类型:
text
文本textarea
多行文本框radio
单选按钮checkbox
复选框select
下拉框
2.10.2 案例源码
在 vue-01-core
目录下新建一个页面 08-表单数据双向绑定.html
<div id="demo">
<!-- @submit.prevent 阻止事件默认提交行为 -->
<form action="#" @submit.prevent="submitForm">
姓名(文本):<input type="text" v-model="name">
<br><br>
性别(单选按钮):
<input name="sex" type="radio" value="1" v-model="sex"/>男
<input name="sex" type="radio" value="0" v-model="sex"/>女
<br><br>
技能(多选框):
<input type="checkbox" name="skills" value="java" v-model="skills">Java开发
<input type="checkbox" name="skills" value="vue" v-model="skills">Vue.js开发
<input type="checkbox" name="skills" value="python" v-model="skills">Python开发
<br><br>
城市(下拉框):
<select name="citys" v-model="city">
<!-- 动态加载下拉列表 -->
<option value="bj" v-for="c in citys" :value='c.code'>
{{c.name}}
</option>
</select>
<br><br>
说明(多行文本):<textarea cols="30" rows="5" v-model="desc"></textarea>
<br><br>
<button type="submit">提交</button>
</form>
</div>
<script src="./node_modules/vue/dist/vue.js"></script>
<script>
new Vue({
el: '#demo',
//通过v-model与表单中元素关联起来
data:{
name: '',
sex: '0',
skills: ['vue'],
citys:[
{code:'bj', name: '北京'},
{code:'sh', name: '上海'},
{code:'gz', name: '广州'},
],
city:'gz',
desc: ''
},
methods: {
submitForm:function(){
//在这里通过ajax提交数据
alert(this.name + ',' + this.sex + "," + this.skills + "," + this.city + "," +this.desc)
}
},
})
</script>