vue.js Study Notes

概述

本篇为vue.js的简单入门。
vue.js是时下热门的javascript MVVM(Model-View-ViewModel)库,简单好用。

参考链接

Vue.js——60分钟快速入门
官方中文教程

HelloWorld入门示例

废话不多说,先来个Hello World。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue.js Learning</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
{{message}}
</div>
</body>
<script>
new Vue({
el: '#app',
data: {message: "Hello World!"}
})
</script>
</html>

代码说明

1
2
3
4
new Vue({
el: '#app',
data: {message: "Hello World!"}
})

这段代码中包含了我们所需要的信息,如下表所示:

el <div id="app"> </div>
data {message:”Hello World!”}
  • el 对应html中的标签元素,即View
  • data 对应的data,即我们需要操作的Model

若将上述app标签中的代码改成如下

1
2
3
4
<div id="app">
<p>{{message}}</p>
<input type="text" v-model="message"/>
</div>

如此就实现了View和Model的双向绑定,将message绑定到文本框,当更改文本框的值时,<p></p>中的内容也会被更新。

Vue.js常用指令

指令 说明
v-if 判断为true,则将后面元素渲染到html中,false则不
v-show 类似v-if,true,false都渲染,但是修改css属性
v-else 必须跟在v-if或v-show后面,若在v-if后面则根据if正确与否再决定是否渲染,v-show后则都渲染
v-for v-for=”item in items” 大概就这样了
v-bind 将元素与Vue实例绑定,可用于修改标签中属性的值,如id
v-on 实现事件监听功能,调用对应的函数

表格创建的例子

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<!DOCTYPE html>
<html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>xiaodemo</title>
<script src="https://unpkg.com/vue"></script>
</head>
<body>
<div id="app">
<fieldset>
<legend>
Create New Person
</legend>
<div class="form-group">
<label>Name:</label>
<input type="text" v-model="newPerson.name"/>
</div>
<div class="form-group">
<label>Age:</label>
<input type="text" v-model="newPerson.age"/>
</div>
<div class="form-group">
<label>Gender:</label>
<select v-model="newPerson.gender">
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
<div class="form-group">
<button v-on:click="createPerson">Create</button>
</div>
</fieldset>
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr v-for="person in people">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
<td>{{person.gender}}</td>
<td :class="'text-center'">
<button @click="deletePerson($index)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
</body>
<script>
var vm = new Vue({
el: "#app",
data: {
newPerson: {
name: '',
age: 0,
gender: 'Male'
},
people: [{
name: 'Jack',
age: 30,
gender: 'Male'
}, {
name: 'Tracy',
age: 22,
gender: 'Female'
}]
},
methods: {
createPerson: function () {
this.people.push(this.newPerson);
this.newPerson = {name: '', age: 0, gender: 'Male'}
},
deletePerson: function (index) {
this.people.splice(index, 1);
}
}
})
</script>
</html>
Create New Person
Name Age Gender Delete

不造为啥数据不显示 奇了怪了 算了 不管了


更新事件:2017-07-30

分页的例子

代码:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
<!DOCTYPE html>
<!--声明不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。-->
<!--<!DOCTYPE html>表示html5版本-->
<html>
<head>
<!--<head> 标签用于定义文档的头部,它是所有头部元素的容器。-->
<!--<head> 中的元素可以引用脚本、指示浏览器在哪里找到样式表、提供元信息等等。-->
<!--文档的头部描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等。-->
<!--绝大多数文档头部包含的数据都不会真正作为内容显示给读者。-->
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<meta charset="utf-8">
<!--<meta> 元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词。-->
<!--<meta> 标签位于文档的头部,不包含任何内容。<meta> 标签的属性定义了与文档相关联的名称/值对。-->
<title></title>
<!--<title> 定义文档的标题,它是 head 部分中唯一必需的元素。-->
<meta name="keywords" content=""/>
<meta name="description" content=""/>
<script type="text/javascript" src="https://unpkg.com/vue"></script>
<!--定义和用法-->
<!--<script> 标签用于定义客户端脚本,比如 JavaScript。-->
<!--script 元素既可以包含脚本语句,也可以通过 src 属性指向外部脚本文件。-->
<!--必需的 type 属性规定脚本的 MIME(Multipurpose Internet Mail Extensions) 类型。-->
<!--JavaScript 的常见应用时图像操作、表单验证以及动态内容更新。-->
<style>
/*<style> 标签用于为 HTML 文档定义样式信息。*/
/*在 style 中,您可以规定在浏览器中如何呈现 HTML 文档。*/
/*type 属性是必需的,定义 style 元素的内容。唯一可能的值是 "text/css"。*/
/*style 元素位于 head 部分中。*/
.page-bar {
margin: 40px;
}
ul, li {
margin: 0px;
padding: 0px;
}
li {
list-style: none
}
.page-bar li:first-child > a {
margin-left: 0px
}
.page-bar a {
border: 1px solid #ddd;
text-decoration: none;
position: relative;
float: left;
padding: 6px 12px;
margin-left: -1px;
line-height: 1.42857143;
color: #337ab7;
cursor: pointer
}
.page-bar a:hover {
background-color: #eee;
}
.page-bar a.banclick {
cursor: not-allowed;
}
.page-bar .active a {
color: #fff;
cursor: default;
background-color: #337ab7;
border-color: #337ab7;
}
.page-bar i {
font-style: normal;
color: #d44950;
margin: 0px 4px;
font-size: 12px;
}
</style>
</head>
<body>
<!--body 元素定义文档的主体。-->
<!--body 元素包含文档的所有内容(比如文本、超链接、图像、表格和列表等等。)-->
<div class="page-bar">
<!--定义和用法-->
<!--<div> 可定义文档中的分区或节(division/section)。-->
<!--<div> 标签可以把文档分割为独立的、不同的部分。它可以用作严格的组织工具,并且不使用任何格式与其关联。-->
<!--如果用 id 或 class 来标记 <div>,那么该标签的作用会变得更加有效。-->
<!--用法-->
<!--<div> 是一个块级元素。这意味着它的内容自动地开始一个新行。实际上,换行是 <div> 固有的唯一格式表现。可以通过 <div> 的 class 或 id 应用额外的样式。-->
<!--不必为每一个 <div> 都加上类或 id,虽然这样做也有一定的好处。-->
<!--可以对同一个 <div> 元素应用 class 或 id 属性,但是更常见的情况是只应用其中一种。这两者的主要差异是,class 用于元素组(类似的元素,或者可以理解为某一类元素),而 id 用于标识单独的唯一的元素。-->
<ul>
<!--<ul> 标签定义无序列表。-->
<li v-if="cur>1"><a @click="cur--,pageClick()">上一页</a></li>
<!--定义和用法-->
<!--<li> 标签定义列表项目。-->
<!--<li> 标签可用在有序列表 (<ol>) 和无序列表 (<ul>) 中。-->
<li v-if="cur==1"><a class="banclick">上一页</a></li>
<!--定义和用法-->
<!--<a> 标签定义超链接,用于从一张页面链接到另一张页面。-->
<!--<a> 元素最重要的属性是 href 属性,它指示链接的目标。-->
<li v-for="index in indexs" :class="{ 'active': cur == index}">
<a @click="btnClick(index)">{{ index }}</a>
</li>
<li v-if="cur!=all"><a @click="cur++,pageClick()">下一页</a></li>
<li v-if="cur == all"><a class="banclick">下一页</a></li>
<li><a>共<i>{{all}}</i>页</a></li>
</ul>
</div>
<script type="text/javascript">
var pageBar = new Vue({
el: '.page-bar',
data: {
all: 8, //总页数
cur: 1//当前页码
},
// watch: {
// cur: function (oldValue, newValue) {
// console.log(arguments);
// }
// },
// 使用computed后,这里的watch就显得多余了
methods: {
btnClick: function (data) {//页码点击事件
if (data != this.cur) {
this.cur = data
}
}
// pageClick: function () {
// console.log('现在在' + this.cur + '页');
// }
// 点击下一页页码的改变是随着cur数值的改变而改变,因此这里的点击事件可以填充额外的函数
},
computed: {
indexs: function () {
var left = 1;
var right = this.all;
var ar = [];
if (this.all >= 5) {
if (this.cur > 3 && this.cur < this.all - 2) {
left = this.cur - 2;
right = this.cur + 2
} else {
if (this.cur <= 3) {
left = 1;
right = 5
} else {
right = this.all;
left = this.all - 4
}
}
}
while (left <= right) {
ar.push(left);
left++
}
return ar
}
}
})
</script>
</body>
</html>

代码注释中包括了对html标签的说明。
下面为vue.js中computed和methods以及watcher的区别做下简要介绍。

computed

直接先看个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
HTML:
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
JS:
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})

结果:
Original message: “Hello”
Computed reversed message: “olleH”
这里我们声明了一个计算属性 reversedMessage 。我们提供的函数将用作属性 vm.reversedMessage 的 getter 。

你可以打开浏览器的控制台,自行修改例子中的 vm 。 vm.reversedMessage 的值始终取决于 vm.message 的值。

你可以像绑定普通属性一样在模板中绑定计算属性。 Vue 知道 vm.reversedMessage 依赖于 vm.message ,因此当 vm.message 发生改变时,所有依赖于 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 是没有副作用,这使得它易于测试和推理。

Computed vs Methods

我们可以将同一函数定义为一个 method 而不是一个计算属性。对于最终的结果,两种方式确实是相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A ,它需要遍历一个极大的数组和做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用 method 替代。

Computed vs Watched

Vue 确实提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:watch 属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的想法是使用 computed 属性而不是命令式的 watch 回调。

O__O “… 以上的话,就当做我已经理解了。

Watchers

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的 watcher 。这是为什么 Vue 提供一个更通用的方法通过 watch 选项,来响应数据的变化。当你想要在数据变化响应时,执行异步操作或开销较大的操作,这是很有用的。

使用 watch 选项允许我们执行异步操作(访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这是计算属性无法做到的。

参考链接

以上分析参考自官方对计算属性的介绍
vuejs2.0实现一个简单的分页

THE END

thank you!~