谷歌也推出了基于组件的第二代Angular框架,致力于开发全平台应用——Web、移动 Web、移动应用、原生应用和桌面原生应用,其最为核心的特色是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等等。javascript
后期之秀Vue.js,其做者尤雨溪在谷歌就任时建立并于2014年发布,自发布以来,因为其设计灵活,方便集成到现有项目中,并能轻松构建复杂的应用程序,所以Vuejs大受欢迎,如今成为三大前端主流框架之一。css
在你阅读本文时,你必定疑惑为何选择Vue,如下的几个理由是否是能打动你选择Vue?html
一、很容易集成上手 到现有项目。你能够在现有的网站中轻松集成Vue,无需引入新的工具设置复杂的流程,若是你习惯使用jQuery,那你也很容易上手Vue的。 前端
二、基于组件的架构。容许应用程序模块化,组件化,方便快速构建现代化的单页面应用程序(SPA)。 vue
三、生态的完整性。几乎你能想到的插件,你都能在社区里找到。更重要的是,其重要的的库好比路由,状态管理等都是有Vue官方团队进行维护,不像React生态,官方并非很积极的提供解决方案。java
四、 普遍的使用。从国外的GitLab到国内的阿里巴巴,尤为国内愈来愈多公司的使用,让其成为国内前端必备技能。同时Vue.js成为PHP流行框架Laravel的默认前端库。因为其使用的普遍性,将来会有更多的人去投入到这个框架中,让其生态更增强大,收益最大的就是咱们每位开发者。react
首先说明下,经过本篇Vue.js基础知识的学习,笔者将带着你们完成以下图所示的练习:npm
主要实现如下功能:数组
为了方便你们快速入门Vue, 本篇文章用最简单的JS文件引入方式来引入Vue框架,下篇文章笔者将详细介绍用构建的方式建立vue项目,以下所示新建一个index.html文件引入Vue文件:浏览器
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>复制代码
注:引入开发版是为了方便咱们进行开发和调试,生产环境应该引入vue.min.js版本
接下来咱们建立Vue实例,代码以下:
new Vue({
el: "#main"
});复制代码
此段代码的意思就是声明Vue实例,并查找DOM的id等于main的元素,用于接下来的数据内容呈现。
为了让上述Vue的实例,加载数据,咱们须要提供数据。Vue内提供data属性,用于加载数据源。data属性是响应式的,当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值,并影响UI的显示。
接下来咱们在data属性里添加一些数据,在实际的应用场景,你会经过接口请求数据,为了方便演示,咱们写死一些数据,示例以下:
new Vue({
el: "#main",
data: {
heading: "前端达人开发部",
employees: [
{
"firstName": "amelia",
"lastName": "austin",
"photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/1.jpg",
"email": "amelia.austin@example.com",
"phone": "(651)-507-3705",
"department": "Engineering"
},
{
"firstName": "bobbie",
"lastName": "murphy",
"photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/2.jpg",
"email": "bobbie.murphy@example.com",
"phone": "(925)-667-7604",
"department": "Management"
}
]
}
});复制代码
如今咱们有了数据,就须要进行界面数据的渲染和呈现,咱们须要使用模板语法——一双大括号 ( {{}} ),进行数据绑定。以下段代码所示:
<h1 class="ui center aligned header">{{ heading }}</h1>复制代码
你能够在这双大括号里包含任何有效的JavaScrip代码,以下所示,咱们在其包含了一个运算语句:
<div id="app"> <p>The price is: ¥{{ price * 1.20 }} (inc. VAT)</p> </div> <script> new Vue({ el: '#app', data: { price: 25 } }); </script>复制代码
双括号区域将会显示
The price is: ¥30 (inc. VAT)复制代码
在实例中,界面呈现前执行了JS语句的运算并将值进行显示。
实现更复杂的页面程序,不能只是简简单单的数据呈现,所以Vue的模板语法还包含循环和条件显示的逻辑指令,让咱们更好的处理页面展示逻辑。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地做用于DOM。(相似AngularJS的ng-*指令)
v-for
前面咱们介绍了加载数据的示例,你可能猜到了咱们须要使用循环遍历的方式遍历集合用于数据的展示,v-for指令的做用就是遍历数据集合中的每项内容,以下段代码所示:
<tbody> <tr v-for="employee in employees"> <td> <img src="https://www.qianduandaren.com/demo/vue/img/women/1.jpg" class="ui mini rounded image" /> </td> <td>{{ employee.firstName }}</td> <td>{{ employee.lastName }}</td> <td>{{ employee.email }}</td> <td>{{ employee.phone }}</td> <td>{{ employee.department }}</td> </tr> </tbody>复制代码
从上述代码咱们能够看出,咱们在tr的属性里,添加了v-for指令,其表明在此DOM区域内进行循环,咱们在此循环显示了雇员的信息。在这里咱们将图片的src属性写死了,下面咱们很快会介绍到用新的指令进行替代。
与react同样,在Vue中渲染列表时,强烈建议您为每一个元素提供一个惟一的键。这有助于Vue框架在添加和删除元素时进行优化。你可使用 :key 指令定义惟一的键值:
<tr v-for="user in users" :key="user.id>复制代码
若是实在没有惟一的键值,你可使用数组索引,示例代码以下
<tr v-for="(employee, index) in employees" :key="index">..</tr>复制代码
v-if
另外一个常见的指令就是条件渲染,v-if 只有当data属性或表达式的计算结果为true时,使用该指令才会致使Vue呈现元素,以下段代码所示:
<tbody> <tr v-for="employee in employees"> ... </tr> <tr v-if="employees.length === 0"> <td colspan="6">No employees found</td> </tr> </tbody>复制代码
上述代码若是employee为空,则会显示 No employees found 的信息,这对于咱们往后调用API加载数据的逻辑处理十分有用。
有v-if指令,天然会有v-else-if指令处理更复杂的条件处理,以下段代码所示:
<tbody> <tr v-for="employee in employees"> ... </tr> <tr v-if="isLoadingData"> <td colspan="6"><img src="spinner.gif" /></td> </tr> <tr v-else-if="employees.length === 0"> <td colspan="6">No employees found</td> </tr> </tbody>复制代码
从上述代码中,咱们加入了一个 isLoadingData 属性,这在咱们动态加载数据的逻辑处理十分有用,由于是异步加载数据涉及网络延迟等问题,数据加载前须要有个信息提示用户数据正在加载中。
v-bind
有时候,你须要将数据绑定到html元素的属性上,例如url上的href属性,img的src属性。
还记得咱们上面的例子,咱们渲染数据时把img属性写死了,如今咱们可使用v-bind指令进行数据绑定,代码以下:
<img v-bind:src="employee.photoUrl" class="ui mini rounded image" />复制代码
除了上述写法外,咱们能够用更简短的语法,只须要在属性前使用:前缀便可,代码以下:
<img :src="employee.photoUrl" class="ui mini rounded image" />复制代码
v-model
Vue还支持表单双向绑定的概念,容许咱们经过表单输入动态更改数据的内容,以下段代码所示:
<div id="app"> <input v-model="text" placeholder="edit me"> <p>Text is: {{ text }}</p> </div> <script> new Vue({ el: '#app', data: { text: 'Good golly, Miss Molly' } }); </script>复制代码
从上面的示例中,v-model指令将数据绑定到表单输入框内,咱们更改输入框的值,p标签区域的内容也随之改变。
v-on
咱们可使用v-on:绑定事件监听器,事件类型由参数指定。表达式能够是一个方法的名字或一个内联语句,若是没有修饰符也能够省略。
以下段代码所示,逻辑简单,点击按钮,将数据heading的属性更改成Hello World,咱们实现了内联语句的绑定:
<button v-on:click="heading = 'Hello World!'">Click Me</button>复制代码
除了使用 v-on:click 语法外,咱们可使用更短的语法进行绑定——@click, 在上面的例子咱们实现了属性的更改,咱们还能够绑定自定义用户方法,以下段代码所示:
new Vue({
el: "#main",
data: {
status: ""
},
methods: {
updateStatus(event) {
const buttons = ['left', 'middle', 'right'];
this.status = `You clicked the ${buttons[event.button]} button.`;
}
}
});复制代码
<div id="main"> <button @mousedown="updateStatus" @contextmenu.prevent="">Toggle Me!</button> <p>{{ status }}</p> </div>复制代码
上述代码,咱们将mousedown事件绑定了updateStatus方法,用于帮助用户肯定是点击了鼠标左键仍是右键,同时咱们添加了第二个事件监听contextmenu.prevent,用来阻止鼠标右键默认的上下文菜单行为。相似的还有其它常见事件修饰符:
Vue对象里专门有Methods的属性,方便咱们自定义相关的方法,并在模板里很容易的调用,正如上个示例,咱们是这样定义方法的:
methods: {
updateStatus(event) {
const buttons = ['left', 'middle', 'right'];
this.status = `You clicked the ${buttons[event.button]} button.`;
}
}复制代码
有时候你须要自定义相关的方法监听计算模板中的数据并进行相应,若是你想避免没必要要的方法开销,你可使用Vue的”计算属性“方案。
一个计算属性其实就是一个函数,用来缓存和返回数据。其函数依赖一个数据项,数据项发生改变,其函数就要从新运算,进行新的数据输出。
为了实践这个属性,咱们在数据项里增长一个排序字段属性,以下所示:
data: {
heading: "Staff Directory",
sortBy: "firstName"
employees: [
...
]
}复制代码
接下来,咱们在标题列里添加点击处理事件,以便更改sortBy的属性,以下段代码所示:
<tr> <th>Avatar</th> <th @click="sortBy = 'firstName'">First Name</th> <th @click="sortBy = 'lastName'">Last Name</th> <th @click="sortBy = 'email'">Email</th> <th @click="sortBy = 'phone'">Phone</th> <th @click="sortBy = 'department'">Department</th> </tr>复制代码
最后,让咱们在Vue属性中,添加一个计算属性,该属性根据键值进行数据排序,以下段代码所示:
computed: {
sortedEmployees() {
return this.employees.sort((a, b) => a[this.sortBy].localeCompare(b[this.sortBy]))
}
}复制代码
接下来咱们更改v-for区域的代码,将咱们的计算属性添加进去,示例代码以下:
<tr v-for="(employee, index) in sortedEmployees" :key="index">
...
</tr>复制代码
因为Vue语句提供的魔法糖,输出数据sortedEmployees被缓存,当sortBy属性改变时,sortedEmployees的值将会从新计算。
基于前面的知识内容,咱们最终完成的index.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>Vue Staff Directory - Jump Start Vue.js</title> <link rel="stylesheet" href="https://www.qianduandaren.com/demo/vue/semantic.min.css"> <style> h1.ui.center.header { margin-top: 3em; } </style> </head> <body> <main id="main"> <h1 class="ui center aligned header">{{ heading }}</h1> <div class="ui container"> <table class="ui celled table"> <thead> <tr> <th>Avatar</th> <th @click="sortBy = 'firstName'">First Name</th> <th @click="sortBy = 'lastName'">Last Name</th> <th @click="sortBy = 'email'">Email</th> <th @click="sortBy = 'phone'">Phone</th> <th @click="sortBy = 'department'">Department</th> </tr> </thead> <tbody> <tr v-for="(employee, index) in sortedEmployees" :key="index"> <td> <img :src="employee.photoUrl" class="ui mini rounded image" /> </td> <td>{{ employee.firstName }}</td> <td>{{ employee.lastName }}</td> <td>{{ employee.email }}</td> <td>{{ employee.phone }}</td> <td>{{ employee.department }}</td> </tr> </tbody> <tfoot> <tr> <th colspan="6"></th> </tr> </tfoot> </table> </div> </main> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script> new Vue({ el: "#main", data: { heading: "前端达人开发部", sortBy: 'department', employees: [ { "firstName": "amelia", "lastName": "austin", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/1.jpg", "email": "amelia.austin@example.com", "phone": "(651)-507-3705", "department": "Engineering" }, { "firstName": "bobbie", "lastName": "murphy", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/2.jpg", "email": "bobbie.murphy@example.com", "phone": "(925)-667-7604", "department": "Management" }, { "firstName": "kristin", "lastName": "terry", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/3.jpg", "email": "kristin.terry@example.com", "phone": "(021)-544-1184", "department": "Sales" }, { "firstName": "brandon", "lastName": "griffin", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/men/1.jpg", "email": "brandon.griffin@example.com", "phone": "(509)-317-9506", "department": "Management" }, { "firstName": "tammy", "lastName": "gibson", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/4.jpg", "email": "tammy.gibson@example.com", "phone": "(815)-727-0663", "department": "Support" }, ] }, computed: { sortedEmployees() { return this.employees.sort((a, b) => a[this.sortBy].localeCompare(b[this.sortBy])); } } }); </script> </body> </html>复制代码
本篇文章的内容就到这里,接下来给你们留个做业题(答案将在下期文章进行公布),基于本文的例子,咱们增长一个输入框,实现雇员信息的检索功能(输入雇员的全名或名字的部份内容,显示信息结果)。在下篇文章里,我将继续介绍如何工程化的构建Vue项目和Vue相关的工具,敬请期待。