Vue2入门
本文介绍Vue的相关概念,使用方式。目的是使读者对React有一个大致的了解,以便于能够更加深入的学习、快速上手Vue。学习Vue应该掌握好几个概念,Vue实例、数据绑定、模板语法、组件。
- Vue实例
- 响应式数据
- 计算属性
- 方法
- 生命周期
- 数据绑定
- 绑定到属性
- class与style绑定
- 表单输入绑定
- 事件绑定
- 绑定到内容
- 双向绑定
- 绑定到属性
- 模板语法
- 插值
- 指令
- 缩写
- 条件渲染
- 列表渲染
- 组件
- 组件注册
- 组件通信
- 动态组件
- 分发内容
Vue实例
每个 Vue 应用都是通过 Vue 函数创建一个新的 Vue 实例开始的
Vue对象通过data方式传入响应式数据,这些数据与vue实例中的数据同步改变。vue实例暴露的接口都以$开头1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data,
// 生命周期函数
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
vm.$data === data // => true
vm.$el === document.getElementById('example') // => true
// $watch 是一个实例方法
vm.$watch('a', function (newValue, oldValue) {
// 这个回调将在 `vm.a` 改变后调用
})
不要在选项属性或回调上使用箭头函数,比如 created: () => console.log(this.a) 或 vm.$watch(‘a’, newValue => this.myMethod())。因为箭头函数是和父级上下文绑定在一起的,this 不会是如你做预期的 Vue 实例,且 this.a 或 this.myMethod 也会是未定义的。
响应式数据
响应式属性添加1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
//法一
Vue.set(vm.userProfile, 'age', 27)
//法二
this.$set(this.userProfile, 'age', 27)
//赋予多个属性
this.userProfile = Object.assign({}, this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
被观察属性
使用watch当属性变动时,进行更新
1 | <div id="demo">{{ fullName }}</div> |
1 | // 每当firstName和lastName发生变化就进行更新 |
计算属性
当计算属性依赖的属性发生改变时才会自动更新,基于依赖进行缓存。
1 | <div id="example"> |
1 | var vm = new Vue({ |
方法
方法没有缓存,每次访问都进行计算1
<p>Reversed message: "{{ reversedMessage() }}"</p>
1 | // in component |
生命周期
生命周期图示
数据绑定
绑定到属性
Class与Style绑定
对象绑定class
active、’text-danger’:hasError表示当hasError为真时则启用对应名称的class1
2
3<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
1 | data: { |
使用对象进行绑定1
<div v-bind:class="classObject"></div>
1 | data: { |
数组绑定class
1 | <div v-bind:class="[activeClass, errorClass,{ active: isActive }]"></div> |
1 | data: { |
class绑定用在组件上,则是与html的class相互叠加的方式。
对象绑定style
使用data中的属性1
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
1 | data: { |
直接绑定一个对象1
<div v-bind:style="styleObject"></div>
1 | data: { |
数组绑定style
1 | <div v-bind:style="[baseStyles, overridingStyles]"></div> |
事件绑定
监听事件
绑定方式1
2
3
4
5
6
7
8
9<div id="example-1">
<!-- 字面量方式(此处使用了修饰符,修饰符可串联) -->
<button v-on:click.stop.prevent="counter += 1">增加 1</button>
<!-- 方法方式 -->
<button v-on:click="greet">问候</button>
<!-- 内联处理器,$event传入事件到方法 -->
<button v-on:click="warn('Form cannot be submitted yet.', $event)">
<p>这个按钮被点击了 {{ counter }} 次。</p>
</div>
1 | var example1 = new Vue({ |
修饰符
- 事件修饰符:.stop(阻止冒泡),.prevent(阻止默认事件),.capture(监听器加在捕获模式上),.self(只有事件在该元素本身时触发回调),.once(只触发一次事件)
- 键值修饰符:.enter,.tab,.delete (捕获“删除”和“退格”键),.esc,.space,.up,.down,.left,.right;.ctrl,.alt,.shift,.meta
- 鼠标按钮修饰符:.left,.right,.middle
自定义键值修饰符别名:1
2// 可以使用 v-on:keyup.f1
Vue.config.keyCodes.f1 = 112
表单输入绑定
使用v-model对表单进行双向绑定,绑定的数据为表单的值value,复选框和多选列表可以绑定到数组上。
1 | <!-- 当选中时,`picked` 为字符串 "a" --> |
修改绑定的值到响应元素上1
2
3
4
5
6<input
type="checkbox"
v-model="toggle"
v-bind:true-value="a"
v-bind:false-value="b"
>
1 | // 当选中时 |
修饰符:.lazy(同步事件由input改为change),.number(将用户的输入结果转换为number类型,转换结果为NaN则返回原值),.trim(自动过滤用户输入首位空格)
绑定到内容
使用模板的插值语法进行数据的绑定
1 | <!-- 数据绑定 --> |
双向绑定
使用v-model在表单元素上进行双向绑定。
模板语法
插值
1 | <!-- 数据绑定 --> |
使用v-bind命令让mustache语法作用在HTML上
1 | <div v-bind:id="dynamicId"></div> |
绑定使用的js表达式只能包含单个表达式
1 | <!-- 这是语句,不是表达式 --> |
指令
指令 (Directives) 是带有 v- 前缀的特殊属性。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。
1 | <p v-if="seen">现在你看到我了</p> |
缩写
v-bind缩写
1 | <!-- 完整语法 --> |
v-on缩写1
2
3
4<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
条件渲染
条件渲染的使用形式如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
v-if用于切换显示单个元素时,加在元素上就好了,切换多个元素时需要用template包裹多个元素。如果没有使用key进行区分元素将会被复用。
v-show不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
列表渲染
使用数组
使用v-for将数组对应为一组元素,可以使用of代替in
1 | <ul id="example-1"> |
1 | var example1 = new Vue({ |
使用对象
1 | <ul id="v-for-object" class="demo"> |
1 | new Vue({ |
template
类似于 v-if,你也可以利用带有 v-for 的 <template>
渲染多个元素。1
2
3
4
5
6<ul>
<template v-for="item in items" v-if="!item.isComplete">
<li>{{ item.msg }}</li>
<li class="divider"></li>
</template>
</ul>
key值
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。理想的 key 值是每项都有的且唯一的 id。你需要用 v-bind 来绑定动态值
1 | <div v-for="item in items" :key="item.id"> |
更新检测
当数组结构发生改变时,就会自动更新。(如:unshift、push()、pop()、shift()、unshift()、splice()、sort()、reverse())
以下两种方法不会触发自动更新:
- vm.items[indexOfItem] = newValue(触发更新Vue.set(example1.items, indexOfItem, newValue)、example1.items.splice(indexOfItem, 1, newValue))
- vm.items.length = newLength (触发更新example1.items.splice(newLength)
)
组件
组件可以扩展 HTML 元素,封装可重用的代码。
组件注册
1 | //全局注册 |
使用DOM模板
由于浏览器的解析机制,使用DOM作为模板时,添加自定义属性应该使用is属性
1 | <table> |
组件间的class与style使用并集的方式获取。
组件data为函数
所有组件共用一个data
1 | var data = { counter: 0 } |
每个组件使用不同的data对象1
2
3
4
5data: function () {
return {
counter: 0
}
}
通信方式
父组件使用Props的方式与子组件通信,子组件通过事件的方式与父组件通信。
Props
父组件向子组件传递消息
模板之间使用-隔开,props中使用驼峰命名法1
<child v-bind:my-message="parentMsg"></child>
1 | Vue.component('child', { |
Prop验证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
31Vue.component('example', {
props: {
// 基础类型检测 (`null` 意思是任何类型都可以)
propA: Number,
// 多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数字,有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
自定义事件
自定义事件是子组件向父组件传递消息的方式。
1 | <div id="counter-event-example"> |
1 | Vue.component('button-counter', { |
给组件绑定原生事件需要添加修饰符.native
使用插槽分发内容
父组件与子组件中的内容使用插槽来混合
具名插槽
子组件模板1
2
3
4
5
6
7
8
9
10
11<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父组件模板1
2
3
4
5
6<app-layout>
<h1 slot="header">这里可能是一个页面标题</h1>
<p>主要内容的一个段落。</p>
<p>另一个主要段落。</p>
<p slot="footer">这里有一些联系信息</p>
</app-layout>
渲染结果1
2
3
4
5
6
7
8
9
10
11
12<div class="container">
<header>
<h1>这里可能是一个页面标题</h1>
</header>
<main>
<p>主要内容的一个段落。</p>
<p>另一个主要段落。</p>
</main>
<footer>
<p>这里有一些联系信息</p>
</footer>
</div>
作用域插槽
作用域插槽是一种特殊类型的插槽,用作使用一个 (能够传递数据到) 可重用模板替换已渲染元素。
1 | <div class="child"> |
在父级中,具有特殊属性 scope 的 元素必须存在,表示它是作用域插槽的模板。scope 的值对应一个临时变量名
1 | <div class="parent"> |
动态组件
通过使用保留的
1 | <component v-bind:is="currentView"> |
1 | var vm = new Vue({ |
也可以直接绑定到组件对象上1
2
3
4
5
6
7
8
9var Home = {
template: '<p>Welcome home!</p>'
}
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})
使用keep-alive标签,可以把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染。
1 | <keep-alive> |
参考文献:
Vue2.x官方文档