什么是Vue.js
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,我们的页面模板看起来是这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<!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:
1
2
|
http:
//cdn.jsdelivr.net/vue/1.0.7/vue.min.js
http:
//cdnjs.cloudflare.com/ajax/libs/vue/1.0.7/vue.min.js
|
HelloWorld
动手写第一个Vue.js 应用吧。app.html:
1
2
3
4
|
<div id=
"app"
>
<div>{{message}}</div>
<input type=
"text"
v-model=
"message"
>
</div>
|
app.js:
1
2
3
4
5
6
|
new
Vue({
el:
'#app'
,
data: {
message:
'hello vue.js.'
}
});
|
创建Vue实例
在使用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不会随着数据的改变而更新。同时还支持一些简单的表达式:
1
2
|
{{message +
'vue is awesome'
}}
{{ message.split(
''
).reverse().join(
''
) }}
|
常用的指令
v-model
v-model可用于一些表单元素,常见的input,checkbox,radio,select:
1
2
3
4
5
6
7
|
<select v-model=
"selected"
multiple>
<option selected>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected | json }}</span>
|
v-for
列表渲染在实际开发中非常常见,vue.js使用v-for这个指令就能完成,v-for取代了1.0以前版本中的v-repeat。在app.js中准备一些数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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中我们只要这样就能获取到数据了:
1
2
3
4
5
6
|
<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 }
v-on
vue.js通过v-on完成事件处理与绑定,比如为一个button绑定click事件,我们就可以这么写:
1
|
<button v-on:click=
"doSomething"
>doSomething</button>
|
也可以缩写:
1
|
<button
@click
=
"doSomething"
>doSomething</button>
|
我们需要为v-on传入事件参数,然后在vue的实例中声明doSomething这个方法就可以调用了:
1
2
3
4
5
6
7
8
|
new
Vue({
el:
'#app'
,
methods: {
doSomething: function () {
/...../
}
}
})
|
接着上面书的例子,我们用v-model绑定form:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<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方法:
1
2
3
4
5
6
7
8
9
|
methods: {
addBook: function() {
//计算书的id
this
.book.id =
this
.books.length +
1
;
this
.books.push(
this
.book);
//将input中的数据重置
this
.book =
''
;
}
}
|
我们再健全一下功能,增加一个删除按钮:
1
|
<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/v-show
顾名思义,v-if用于条件判断,和v-else是一对。用法也很简单,下面的代码是将id为偶数的操作按钮换个样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<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即可:
1
2
|
<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自定义:
1
2
3
|
Vue.filter(
'reverse'
, function (value) {
return
value.split(
''
).reverse().join(
''
)
})
|
过滤器支持接收参数,比较常用的是orderBy [param]和filterBy [param],现在我们为表格增加自定义排序的功能,为表头绑定click事件:
1
2
3
4
|
<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:
1
2
3
4
5
6
7
8
|
data: {
sortparam:
''
},
methods:{
sortBy: function(sortparam) {
this
.sortparam = sortparam;
}
}
|
添加过滤器:
1
|
<tr v-
for
=
"book in books | orderBy sortparam"
>
|
计算属性
计算属性可以帮助我们完成一些复杂的逻辑计算,比如我们需要添加一个书的总价,在vue实例中添加computed:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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-resource作为vue插件的形式存在,通过 XMLHttpRequest 或 JSONP 发起请求并处理响应。在开发中也非常常见,现在我们用vue-resource来请求books:
引入
和vue类似:
1
2
3
4
5
|
npm install vue-resource --save
如果你的项目遵循CommonJS:
var Vue = require(
'vue'
);
Vue.use(require(
'vue-resource'
));
|
也可以直接引入单文件或者CDN。
get
在vue中新增ready对象,当页面加载完成时就去请求:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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()得到:
1
|
[{
"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,想要启动一个服务器就太简单了:
1
2
3
4
|
npm install http-server -g
//在当前目录
http-server
//然后访问localhost:8080/app.html
|
post
post的语法也很简单:
this.$http.post(url,postdata,function callback)
在使用的时候遇到一个小坑,这个$http请求和jquery的ajax还是有点区别,这里的post的data默认不是以form data的形式,而是request payload。解决起来也很简单:在vue实例中添加headers字段:
1
2
3
|
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主页 ,所用的例子我也分享了,可以在 这里 查看并运行结果。