在 Vue.js 框架中,与 HTML 页面元素的交互方式没有像原生 JavaScript 接口那么直接,它是经过先在 HTML 元素标签中嵌入一系列相似于普通标签属性的 Vue 指令属性来绑定数据,而后再经过在 JavaScript 代码中修改这些被绑定的数据来修改页面元素的显示方式与内容。在编程方法上,咱们一般将这种用数据内容的变化来驱动整个程序业务运做的方式称之为"数据驱动开发"。这部分笔记将记录如何利用数据驱动的开发方式来完成数据绑定、事件响应,以实现控制页面元素与 CSS 样式等各项基本功能。html
在以前的01_sayHello
程序中,咱们如今<h1>
标签中使用模版语法绑定了一个名称为sayHello
的数据,该模版语法其实是v-text
指令的语法糖。换句话说,该<h1>
标签更规范的语法应该是:前端
<h1 v-text="sayHello"></h1>
考虑到咱们传统上编写 HTML 标签的习惯,使用{{ data_name }}
这样的模版标记会是更让人舒服的作法。固然了,v-text
指令设置的是当前元素标签下面的文本内容,若是要为标签自己的属性绑定数据,就得要使用v-bind
指令,具体语法是在要设置的标签属性名前面加上v-bind:
前缀。例如,若是想为<img>
标签的src
属性绑定数据,就能够这样作:vue
<img v-bind:src="vueLogo" style="width:200px">
另外,v-bind
指令还有一个简写形式,只须要在要绑定数据的标签属性名以前加一个:
前缀便可。在以前的01_sayHello
程序中,我采用的就是这种形式。在页面元素上绑定了数据以后,接下来就能够在相对应的 JavaScript 脚本中建立 Vue 实例了,这就是我以前在01_sayHello
程序的main.js
文件中编写的内容。这个 Vue 实例对象中至少要定义如下两个成员:node
el
成员:该成员用于设置当前 Vue 实例所对应的元素容器,这一般是一个<div>
元素,某些状况也能够是 HTML5 提供的<header>
、<footer>
等容器类标签。该成员的值能够是任何一个符合 CSS 选择器语法的字符串,例如#ID
、.CLASSNAME
等。data
成员:该成员用于设置页面元素中绑定的数据,它的值自己也是一个 JSON 格式的对象,该对象的每一个成员都对应一个页面元素中绑定的对象,例如在以前的01_sayHello
程序中,我绑定了sayHello
和vueLogo
这两个数据,就必需要在 Vue 对象的data
成员中为为它们设置相应的值。固然,01_sayHello
程序目前只是一个单向显示数据的业务。若是想要让其具有交互能力,还须要为页面元素绑定事件。在 Vue.js 框架中,绑定事件首先要经过v-on
指令来为目标元素标签注册事件处理函数,例如若是咱们想在01_sayHello
程序用一个按钮来控制<img>
元素的显示与否,能够将该程序的index.htm
代码修改以下:编程
<!DOCTYPE html> <html lang="zh-cn"> <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"> <script defer="defer" src="../node_modules/vue/dist/vue.js"></script> <script defer="defer" src="js/main.js"></script> <title>你好,Vue.js</title> </head> <body> <div id="app"> <h1> {{ sayHello }} </h1> <!-- 上述模版语法背后真正的 Vue 语法: <h1 v-text="sayHello"></h1> --> <img :src="vueLogo" v-show="isShow" style="width:200px"> <!-- 上述简写指令的完整 Vue 语法: <img v-bind:src="vueLogo" style="width:200px"> --> <input type="button" :value="isShow?'隐藏':'显示'" @click="toggleShow" /> <!-- 上述简写指令的完整 Vue 语法: <input type="button" v-bind:value="isShow?'隐藏':'显示'" v-on:click="toggleShow" /> --> </div> </body> </html>
在这里,我主要作了以下修改:浏览器
<img>
标签中增长了一个v-show
指令,该指令可用于绑定一个布尔类型的数据(即这里的isShow
),以此来决定是否显示其所在的标签。v-bind
指令设置了该标签的value
属性,该属性的值是一个条件表达式,它将根据isShow
的值显示不一样的文本。v-on
指令(@
是该指令v-on:
前缀的简写形式)为新增的按钮标签注册了一个名为toggleShow
的单击事件处理函数。下面继续来对main.js
中的代码进行修改,具体以下:app
const app = new Vue({ el: '#app', data:{ sayHello: '你好,Vue.js!', vueLogo: 'img/logo.png', isShow: true }, methods:{ toggleShow: function() { this.isShow = !this.isShow; } } });
在这里,我主要作了以下修改:框架
data
成员中定义了以前绑定的布尔类型数据isShow
,并将其默认值设置为 true。methods
的成员。该成员用于设置页面元素中注册的事件处理函数,它的值也是一个 JSON 格式的对象。该对象的每一个成员都对应一个已在页面元素中用v-on
指令注册的事件处理函数。在这里就是toggleShow
,该函数每次调用都会将isShow
的值取反。这样一来,当咱们在 Web 浏览器中打开该应用程序就会看到以前的 Vue 图标旁边多了个文本内容为隐藏
的按钮。当按钮被单击以后,图标就会消失,按钮上的文本也变成显示。以后,若是该按钮再次被单击,一切又会恢复原状。函数
对于用户来讲,除了触发事件以外,容许用户在运行时输入具体的数据也是一个应用程序必不可少的一项功能。下面将经过编写一个"待办事项"的程序来学习如何使用 Vue.js 框架实现能处理用户输入数据的应用程序界面。为此,我须要在code
目录下建立一个名为02_toDoList
的目录,并在该目录中建立一个名为index.htm
的文件,其代码以下:学习
<!DOCTYPE html> <html lang="zh-cn"> <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"> <script defer="defer" src="../node_modules/vue/dist/vue.js"></script> <script defer="defer" src="js/main.js"></script> <title>待办事项</title> </head> <body> <div id="app"> <h1>待办事项</h1> <div id="todo"> <ul> <li v-for="( task,index ) in taskList"> <input type="checkbox" v-model="doneList" :value="task"> <label :for="task">{{ task }}</label> <input type="button" value="删除" @click="remove(index)"> </li> </ul> </div> <div id="done" v-if="doneList.length > 0"> <h2>已完成事项</h2> <ul> <li v-for="task in doneList"> <label :for="task">{{ task }}</label> </li> </ul> </div> <input type="text" v-model="newTask" @keyup.enter="addNew"> <input type="button" value="添加新任务" @click="addNew"> </div> </body> </html>
接下来,我会在同一目录下再建立一个名为js
的目录,并在该目录下建立main.js
脚本文件,其代码以下:
// 程序名称: toDoList // 实现目标: // 1. 学习 v-model、v-for 等指令 // 2. 掌握如何处理用户输入 const app = new Vue({ el: '#app', data:{ newTask: '', taskList: [], doneList: [] }, methods:{ addNew: function() { if(this.newTask !== '') { this.taskList.push(this.newTask); this.newTask = ''; } }, remove: function(index) { if(index >= 0) { this.taskList.splice(index,1); } } } });
下面来具体分析一下这个程序。在一般状况下,Web 应用程序在前端接受用户输入信息的方式主要有两种:第一种方式是用文本框元素来获取用户从键盘输入的信息。在 Vue.js 框架中,咱们能够用v-model
指令将<input type="text">
标签绑定到newTask
数据中,该指令与v-bind
指令不一样的在于,它是一种双向绑定。也就是说,v-model
指令不止可让 JavaScript 代码中对绑定数据的修改反映到页面元素中,也可让页面元素获取到的用户输入数据同步到 JavaScript 代码中。在 JavaScript 代码获取到文本框中的用户输入内容以后,咱们就能够经过事件处理函数addNew
将其加入到一个名为taskList
的数据列表中,而后将该事件处理函数注册给输入回车和鼠标单击事件。
第二种方式是用单选钮、复选框等选择性元素来获取用户用鼠标勾选的信息。例如在上面这个程序中,我在<div id="todo">
元素中用v-for
指令建立了一系列<input type="checkbox">
,它们都提供v-model
指令将本身双向绑定到了另外一个名为doneList
数据列表上。在 Vue.js 框架中,若是一组复选框元素被v-model
指令绑定到了一个列表类型的数据上,那么当这些复选框被选上时,它们的value
属性值就会被自动添加到这个被绑定的数据列表中。
为了证实被选中的复选框被加入到了doneList
数据列表中,我还在页面中添加了一个<div id="done">
元素,并对doneList
数据列表进行了遍历显示。须要说明的是,用于遍历数据列表的v-for
指令主要有两种形式:
v-for="item in dataList"
,这时候数据列表(dataList
)中的每一项数据就会在遍历过程当中逐一被迭代变量(item
)说读取。v-for="( item,index ) in dataList"
,这时候数据列表(dataList
)在遍历过程当中,每一项数据的值会被item
变量读取,而每一项数据的索引会被index
变量读取。最后须要说明的是,对于<div id="done">
元素自己,我使用了v-if
指令,它的效果与以前的v-show
指令基本相同,惟一的区别是:v-if
指令会直接在 DOM 树上增长或删除其所在的元素节点,而v-show
指令则是单纯经过其所在元素的style
属性隐藏或显示该元素而已。在执行效率上,v-show
指令要更高效一些。在这里,咱们设置了当doneList
列表中没有数据时,程序就直接将<div id="done">
元素从页面中移除,反之则在页面中添加该元素。下面来看一下02_toDoList
程序运行的效果: