vue1.0学习总结
前言
使用vue已经有三、四个月了,但是只是学着使用了一些基本方法。因为现在的前端框架越来越多(Angular,React...),但是我相信万变不离其宗,很多用法框架之间还是想通的,所以借总结的vue的机会深入了解vue到每个细节,以后能更加熟练地使用vue,有机会也能在别的框架中体会相通的思想。
一、基本&&重点介绍
- 兼容性:vue不支持IE8及以下版本,因为IE8不支持vue所使用的ECMAScript5语法
- 数据驱动视图:不需要操作DOM
- 支持双向绑定:但是默认为数据从父组件到子组件的单向绑定
- 组件化:每一个用vue搭建起来的项目,其实都是一个组件树
二、数据绑定语法
- 模板
- Mustache 语法
- 写法: {{}} 插文本 {{{}}}插html
- 可以插在属性里 eg.<div id="item-{{ id }}"></div>
- 指令
- 以v-为前缀,后面可以带一个参数以:连接,此外还可以带一个修饰符以.连接 eg. v-bind:href="xxx",v-on:click="onClick"
- 缩写: v-bind:href ---> :href="xxx" v-on:click ---> @click="xxx"
三、计算属性
- 计算属性会有一个响应依赖,并且它会持续追踪它的响应依赖,如果响应依赖没有变化,则会返回缓存结果。只有响应依赖变化的时候才会触发视图更新。
- 计算属性默认只是 getter,不过在需要时你也可以提供一个 setter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// ...
computed: {
fullName: {
// getter
get:
function
() {
return
this
.firstName +
' '
+
this
.lastName
},
// setter
set:
function
(newValue) {
var
names = newValue.split(
' '
)
this
.firstName = names[0]
this
.lastName = names[names.length - 1]
}
}
}
// ...
|
现在在调用 vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和 vm.lastName
也会有相应更新。
四、Class与Style的绑定
- class的绑定
- 可以通过变量的布尔值,来控制class最后的渲染结果
- eg. <div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB }"></div> ( 显示class-a或class-b是否加入到class里,取决于isA和isB的布尔值)
- style的绑定
1
2
3
4
5
6
7
|
<div v-bind:style=
"styleObject"
></div>
data: {
styleObject: {
color:
'red'
,
fontSize:
'13px'
}
}
|
五、条件渲染
- v-if: 支持使用<template></template>作为包装元素,不用直接操控元素,且最终渲染结果不会包括它(<template></template>)
- v-show: 相当于控制display,不支持<template></template>
注意:v-show直接用在组件上时,v-else会出现问题,可以用v-show代替v-else
1
2
|
<custom-component v-show=
"condition"
></custom-component>
<p v-show=
"!condition"
>这可能也是一个组件</p>
|
- v-if 和 v-show的区别:
v-if
有更高的切换消耗而v-show
有更高的初始渲染消耗。因为v-if里有数据和子组件,故操作时会不断销毁和重建,成本较高。但是v-show里的元素会被始终编译和保留
六、列表渲染
v-for
- 遍历数组
- 块内特殊变量: $index (数组索引)
- <template></template>包装元素:适用
- track-by: 指定数组以指定的某种顺序来渲染视图 eg.track-by="$index"
1
2
3
4
5
6
7
8
9
10
11
|
基本写法一:
<ul id=
"example-2"
>
<li v-
for
=
"item in items"
>
{{ parentMessage }} - {{ $index }} - {{ item.message }}
</li>
</ul>
基本写法二:
<div v-
for
=
"(index, item) in items"
>
{{ index }} {{ item.message }}
</div>
|
- 遍历对象
- 块内特殊变量:$key(对象中的key)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
new
Vue({
el:
'#repeat-object'
,
data: {
object: {
FirstName:
'John'
,
LastName:
'Doe'
,
Age: 30
}
}
})
基本写法一:
<ul id=
"repeat-object"
class
=
"demo"
>
<li v-
for
=
"value in object"
>
{{ $key }} : {{ value }}
</li>
</ul>
基本写法二:
<div v-
for
=
"(key, val) in object"
>
{{ key }} {{ val }}
</div>
|
数组变动检测
- 数组方法:可触发视图更新
eg. .push()、.pop()、.shift()、.unshift()、.splice()、.sort()、.reverse()
- 数组的限制:
1.不能之间用索引设置元素,eg. vm.items[0] = {}
; 解决办法:使用$set方法,如 example.items.$set(0,{aaa:'changed!'}),这样就可以触发新视图了
2.不能直接设置数组的长短, eg. vm.items.length = 0; 解决办法:直接赋给一个空数组
- 数组的特殊方法
1. $set(数组索引,要修改的值)
使用方法:如上第一点的使用方法
2.$remove(下标)
七、方法与事件处理器
- 事件中的特殊变量:$event
1
2
3
4
5
6
7
8
|
<button v-on:click=
"say('hello!', $event)"
>Submit</button>
<br>
// ...
methods: {
say:
function
(msg, event) {
// 现在我们可以访问原生事件对象
event.preventDefault()
}
}
|
- 事件修饰符: .prevent阻止默认事件 .stop阻止冒泡事件 .self只在事件发生在该元素本身(不为子元素)时触发回调 .capture添加事件监听器时
- 按键修饰符:enter 、tab、delete、esc、space、up、down、left、right
1
|
<input v-on:keyup.enter=
"submit"
>
|
八、表单控件绑定
表单控件的绑定,主要由v-model进行双向绑定
表单
- text/textarea: v-model 绑定的值就是text的值
- checkbox: v-model绑定的值默认为布尔值(也可以自定义),多个checkbox绑定同一个值,对应每个checkbox的值为其value值
- radio: v-model绑定的值为其value值,多个radio绑定同一个值,对应每个radio的值为其value值
- select: 单选时,v-model绑定的值为option中value;多选时,要在select上加multiple
参数特性
- lazy:在默认情况下,
v-model
在input
事件中同步输入框值与数据,可以添加一个特性lazy
,从而改到在change
事件中同步 - number:自动将用户输入的转成Number
- debounce:输入延迟
九、过渡
动画类处理方法,跳过
十、组件
前面提到vue的项目就是一个组件树,一个页面的所有可见的模块都可以细化成一个组件。
想要实现一个组件主要先从初始化根实例,定义组件和注册组件
1
2
3
4
5
6
7
8
9
10
|
// 定义
var
MyComponent = Vue.extend({
template:
'<div>A custom component!</div>'
})
// 注册
Vue.component(
'my-component'
, MyComponent)
// 创建根实例
new
Vue({
el:
'#example'
})
|
props
可以从父组件传给子组件的一些数据
- 绑定修饰符:.sync 和 .once
1
2
3
4
5
6
|
<!-- 默认为单向绑定 -->
<child :msg=
"parentMsg"
></child>
<!-- 双向绑定 -->
<child :msg.sync=
"parentMsg"
></child>
<!-- 单次绑定 -->
<child :msg.once=
"parentMsg"
></child>
|
- props中的type验证: Stirng、Number、Object、Function、Boolean、Array
父子组件通信
- 自定义事件
- $on() 监听事件,一般在ready时就要进行监听,不然类似$dispatch事件没办法传递数据
- $emit()
- $dispatch() 派发事件,子组件派发到父组件
- $broadcast():广播事件,父组件传递到子组件
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
|
<!-- 子组件模板 -->
<template id=
"child-template"
>
<input v-model=
"msg"
>
<button v-on:click=
"notify"
>Dispatch Event</button>
</template>
<!-- 父组件模板 -->
<div id=
"events-example"
>
<p>Messages: {{ messages | json }}</p>
<child></child>
</div>
// 注册子组件
// 将当前消息派发出去
Vue.component(
'child'
, {
template:
'#child-template'
,
data:
function
() {
return
{ msg:
'hello'
}
},
methods: {
notify:
function
() {
if
(
this
.msg.trim()) {
this
.$dispatch(
'child-msg'
,
this
.msg)
this
.msg =
''
}
}
}
})<br>
// 初始化父组件
// 将收到消息时将事件推入一个数组
var
parent =
new
Vue({
el:
'#events-example'
,
data: {
messages: []
},
// 在创建实例时 `events` 选项简单地调用 `$on`
events: {
'child-msg'
:
function
(msg) {
// 事件回调内的 `this` 自动绑定到注册它的实例上
this
.messages.push(msg)
}
}
})<br><br>
|
我们将这个示例分为几个步骤解读:
- 子组件的button元素绑定了click事件,该事件指向
notify
方法 - 子组件的
notify
方法在处理时,调用了$dispatch
,将事件派发到父组件的child-msg
事件,并给该该事件提供了一个msg参数 - 父组件的events选项中定义了
child-msg
事件,父组件接收到子组件的派发后,调用child-msg
事件。
- 用v-on绑定自定义事件
1
|
<child v-on:child-msg=
"handleIt"
></child>
|
当子组件触发了 "child-msg"
事件,父组件的 handleIt
方法将被调用。所有影响父组件状态的代码放到父组件的 handleIt
方法中;子组件只关注触发事件。