vue是法语中视图的意思,Vue.js是一个轻巧、高性能、可组件化的MVVM库,同时拥有非常容易上手的API。作者是尤雨溪,写下这篇文章时vue.js版本为 1.0.7
我推荐使用 sublime text
作为编辑器,关于这个编辑器可以看我这篇文章。在 package control
中安装
Vuejs Snippets
Vue Syntax Highlight
推荐使用npm管理,新建两个文件 app.html
, app.js
,为了美观使用bootstrap,我们的页面模板看起来是这样:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"> </head> <body> <div class="container"> <div class="col-md-6 col-md-offset-3"> <h1>Vue demo</h1> <div id="app"> ....... </div> </div> </div> </body> </html>
使用npm安装:
npm install vue
当然你也可以在github上clone最新的版本并作为单文件引入,或者使用CDN:
http://cdn.jsdelivr.net/vue/1.0.7/vue.min.js http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.7/vue.min.js
动手写第一个Vue.js 应用吧。app.html:
<div id="app"> <div>{{message}}</div> <input type="text" v-model="message"> </div>
app.js:
new Vue({ el:'#app', data: { message:'hello vue.js.' } });
在使用Vue.js之前,我们需要先像这样实例化一个Vue对象:
new Vue({ el:'#app' });
就像HelloWorld展示的那样,app.html是view层,app.js是model层,通过vue.js(使用 v-model
这个指令)完成中间的底层逻辑,实现绑定的效果。改变其中的任何一层,另外一层都会改变。
相信你也注意到了,通过 {{value}}
的形式就能取到value的值,并与value进行绑定。HelloWorld中改变input中的值时相应也改变了app.js中的message,从而 {{message}}
也得到改变。上面的代码改为这样:
{{*message}}
则message不会随着数据的改变而更新。同时还支持一些简单的表达式:
{{message + 'vue is awesome'}} {{ message.split('').reverse().join('') }}
v-model
可用于一些表单元素,常见的 input
, checkbox
, radio
, select
:
<select v-model="selected" multiple> <option selected>A</option> <option>B</option> <option>C</option> </select> <br> <span>Selected: {{ selected | json }}</span>
列表渲染在实际开发中非常常见,vue.js使用 v-for
这个指令就能完成, v-for
取代了1.0以前版本中的 v-repeat
。在app.js中准备一些数据:
new Vue({ el: '#app', data: { book: { id: 0, author: '', name: '', price: '' }, books: [{ id: 1, author: '曹雪芹', name: '红楼梦', price: 32.0 }, { id: 2, author: '施耐庵', name: '水浒传', price: 30.0 }, { id: '3', author: '罗贯中', name: '三国演义', price: 24.0 }, { id: 4, author: '吴承恩', name: '西游记', price: 20.0 }] } })
在data里我们设置了两个数据book和book[] books,在app.html中我们只要这样就能获取到数据了:
<tr v-for="book in books "> <td>{{book.id}}</td> <td>{{book.name}}</td> <td>{{book.author}}</td> <td>{{book.price}}</td> </tr>
如果你比较细心的话,在数据还未加载完时是会有闪烁的情况出现,解决方法也很简单,使用 v-cloak
,然后定义css:
[v-cloak] { display: none }
vue.js通过 v-on
完成事件处理与绑定,比如为一个button绑定click事件,我们就可以这么写:
<button v-on:click="doSomething">doSomething</button>
也可以缩写:
<button @click="doSomething">doSomething</button>
我们需要为v-on传入事件参数,然后在vue的实例中声明doSomething这个方法就可以调用了:
new Vue({ el: '#app', methods: { doSomething: function () { /...../ } } })
接着上面书的例子,我们用 v-model
绑定form:
<div id="add-book"> <legend>添加书籍</legend> <div class="form-group"> <label for="">书名</label> <input type="text" class="form-control" v-model="book.name"> </div> <div class="form-group"> <label for="">作者</label> <input type="text" class="form-control" v-model="book.author"> </div> <div class="form-group"> <label for="">价格</label> <input type="text" class="form-control" v-model="book.price"> </div> <button class="btn btn-primary btn-block" v-on:click="addBook()">添加</button> </div>
在app.js中增加我们的addBook方法:
methods: { addBook: function() { //计算书的id this.book.id = this.books.length + 1; this.books.push(this.book); //将input中的数据重置 this.book = ''; } }
我们再健全一下功能,增加一个删除按钮:
<button type="button" class="btn btn-danger" @click="delBook(book)">删除</button>
delBook方法:
delBook:function(book){ this.books.$remove(book); }
vue.js为数组扩展了 $remove
方法,查找并删除我们作为参数传递过去的book。
顾名思义, v-if
用于条件判断,和 v-else
是一对。用法也很简单,下面的代码是将id为偶数的操作按钮换个样式:
<template v-if="book.id%2==0"> <td class="text-right"> ...... <button type="button" class="btn btn-success" @click="delBook(book)">删除</button> ..... </td> </template> <template v-else> ..... <td class="text-right"> <button type="button" class="btn btn-danger" @click="delBook(book)">删除</button> </td> .... </template>
这里用到了 <template>
标签,用于包含多个元素,当元素只有一个时,直接在元素上用 v-if
即可:
<h1 v-if="ok">Yes</h1> <h1 v-else>No</h1>
v-show
作用与 v-if
类似,不同的是 v-show
的元素会始终渲染并保持在 DOM 中,且 v-show
不支持 <template>
标签。
与Linux中的管道类似,vue.js也使用的是 |
:
{{message | uppercase}}
这样就能输出message的大写了,过滤器也能串联在一起使用:
{{message | reverse | uppercase}}
这里reverse并不是内建的过滤器,我们可以用 Vue.filter
自定义:
Vue.filter('reverse', function (value) { return value.split('').reverse().join('') })
过滤器支持接收参数,比较常用的是 orderBy [param]
和 filterBy [param]
,现在我们为表格增加自定义排序的功能,为表头绑定click事件:
<th class="text-right" @click="sortBy('id')">序号</th> <th class="text-right" @click="sortBy('name')">书名</th> <th class="text-right" @click="sortBy('author')">作者</th> <th class="text-right" @click="sortBy('price')">价格</th>
想sortBy传递列的参数,定义sortBy和data:
data: { sortparam: '' }, methods:{ sortBy: function(sortparam) { this.sortparam = sortparam; } }
添加过滤器:
<tr v-for="book in books | orderBy sortparam">
计算属性可以帮助我们完成一些复杂的逻辑计算,比如我们需要添加一个书的总价,在vue实例中添加 computed
:
new Vue({ /.../ computed: { sum: function() { var result = 0; for (var i = 0; i < this.books.length; i++) { result = Number(this.books[i].price) + result; }; return result; } }, /.../ })
在app.html中使用插值表达式:
{{sum}}
vue-resource
作为vue插件的形式存在,通过 XMLHttpRequest 或 JSONP 发起请求并处理响应。在开发中也非常常见,现在我们用vue-resource来请求books:
和vue类似:
npm install vue-resource --save 如果你的项目遵循CommonJS: var Vue = require('vue'); Vue.use(require('vue-resource'));
也可以直接引入单文件或者CDN。
在vue中新增 ready
对象,当页面加载完成时就去请求:
new Vue({ el: '#app', ready: function() { this.$http.get('book.json', function(data) { this.$set('books', data); }).error(function(data, status, request) { console.log('fail' + status + "," + request); }) }, data: { .... books:'' }, .....
为了演示,这里将json格式的数据保存在book.json中,这段数据你可以直接使用JSON.stringify()得到:
[{"id":1,"author":"曹雪芹","name":"红楼梦","price":32},{"id":2,"author":"施耐庵","name":"水浒传","price":30},{"id":"3","author":"罗贯中","name":"三国演义","price":24},{"id":4,"author":"吴承恩","name":"西游记","price":20}]
接下来你需要将app.html中运行在一个服务器中,否则由于浏览器安全的限制,是无法直接读取的,如果你嫌麻烦可以用这个参数启动chrome。
./chrome.exe --allow-file-access-from-files
如果你使用了npm,想要启动一个服务器就太简单了:
npm install http-server -g //在当前目录 http-server //然后访问localhost:8080/app.html
post的语法也很简单:
this.$http.post(url,postdata,function callback)
在使用的时候遇到一个小坑,这个$http请求和jquery的ajax还是有点区别,这里的post的data默认不是以form data的形式,而是request payload。解决起来也很简单:在vue实例中添加headers字段:
http: { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }
后来翻了下 vue-resource
的源码,发现有更加简单的做法:
Vue.http.options.emulateJSON = true;
这里只简单介绍下,详细的文档请大家移步 这里 吧。
vue.js目前还有众多的插件,详情看 这里 。
这里简单介绍了下vue.js的基本用法,但只仅仅介绍了一小部分作为库使用的内容,想了解更多vue.js的内容,还是多多关注vue.js的 github主页 ,所用的例子我也分享了,可以在 这里 查看并运行结果。