Vue是一种遵循MVVM模型理念的框架。
一、基础
1.Vue实例
首先,通过 new Vue 创建一个根Vue实例,并且当实例被创建时,可以将 data 中的属性加入到Vue的响应式系统中
(响应式系统:即当属性的值发生改变时,视图也会跟着响应,更新为新的值)
// 我们的数据对象
var data = { a: 1 }
// 该对象被加入到一个 Vue 实例中
var vm = new Vue({
data: data
})
// 获得这个实例上的属性
// 返回源数据中对应的字段
vm.a == data.a // => true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // => 2
// ……反之亦然
data.a = 3
vm.a // => 3 但是,只有当实例被创建时就存在于 data 中的属性才能被响应 如果通过 vm.b 添加一个新的属性,则不会触发响应,如果想要对后续增加的属性进行响应,则需要一些初始值:
data: {
newTodoText: '',
visitCount: 0,
hideCompletedTodos: false,
todos: [],
error: null
} 另一个重要知识点是生命周期钩子 生命周期钩子就是在各个时间点自动运行的函数,如下图所示:
2.模板语法
所有 Vue.js 的模板都是合法的 HTML,在底层的实现上,Vue 将模板编译成虚拟 DOM 渲染函数。结合响应系统,Vue 能够智能地计算出最少需要重新渲染多少组件,并把 DOM 操作次数减到最少。
A.插值
文本:{{ msg }}
原始HTML:为了输出真正的HTML 需要 v-html
Attribute:Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind
JavaScript 表达式:对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。但每个绑定只能包含单个表达式
<div v-bind:id="dynamicId"></div>若v-bind绑定的属性值为 null、undefined 或 false 则该属性不会被渲染
JavaScript 表达式:对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持。但每个绑定只能包含单个表达式
B.指令
就是指带有 v- 前缀的特殊 attribute,其参数为 JS表达式 当表达式的值发生改变时,响应的作用于DOM
参数:一些指令能够接收一个“参数”,在指令名称之后以冒号表示。如
<a v-bind:href="url">...</a>href 是参数 告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。
动态参数:可以用方括号括起来的 JavaScript 表达式作为一个指令的参数
<a v-bind:[attributeName]="url"> ... </a>attributeName 会被作为一个 JS表达式进行动态求值,将其值作为参数。
例如,如果你的 Vue 实例有一个 data 属性 attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href。
修饰符:修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()
修饰符:修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,.prevent 修饰符告诉 v-on 指令对于触发的事件调用 event.preventDefault()
C.缩写
v-bind ==== :
v-on ==== @
3.计算属性和侦听器
A.计算属性
对于复杂属性,可以使用计算属性。
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
}) 虽然计算属性很类似于方法,但是计算属性可以进行缓存。只有当相关响应式依赖发生改变时才重新求值。
计算属性默认只有 getter 不过也可以定义setter
// ...
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]
}
}
}
// ... B.侦听器
用以监听变量的改变 和计算属性类似 也含有缓存。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。 如:
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
} 当然,也可以使用Vue提供的 vm.$watch API: -
参数:
- {string | Function} expOrFn:监听对象
- {Function | Object} callback:回调函数
- {Object} [options]:可设定属性
- {boolean} deep: 为true时 可进行深度监听
- {boolean} immediate:为true时 将立即以表达式的当前值触发回调
-
返回值:{Function} unwatch
-
用法:
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' } }) vm.$watch('firstName', function (val) { this.fullName = val + ' ' + this.lastName }) vm.$watch('lastName', function (val) { this.fullName = this.firstName + ' ' + val
4.Class 与 Style 绑定
样式绑定可以通过将 v-bind 用于 class 和 style 来进行,并且表达式结果的类型除了字符串之外,还可以是对象或数组。
A.HTML Class
对象语法:
通过给 v-bind:class 一个对象,以动态地切换 class 并在<style>语法里写相应class的样式。
也可以与计算属性结合使用:
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
} 数组语法: 也可以把一个数组传给 v-bind:class,以应用一个 class 列表,并且可以在数组中应用对象
<div v-bind:class="[{ active: isActive }, errorClass]"></div> 用在组件上:当在一个自定义组件上使用 class 属性时,这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。
//声明一个组件
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
//使用时添加class
<my-component class="baz boo"></my-component>
//HTML渲染为
<p class="foo bar baz boo">Hi</p> B.Style绑定
对象语法: 可以直接绑定对象
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div> 也可以绑定到一个样式上 <div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
} 数组语法:<div v-bind:style="[baseStyles, overridingStyles]"></div>数组里的每一个对象都是对象
5.条件渲染
A.v-if
v-if 是一个指令,必须将它添加到一个元素上
如:
<h1 v-if="awesome">Vue is awesome!</h1>若想切换多个元素 则 利用 <template> 进行包裹 并且<template>不会渲染到页面上
<template v-if="ok"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template>v-else,v-else-if 必须紧跟在带 v-if 或者 v-else-if 的元素之后
但由于Vue会复用已有元素,而不是从头开始渲染,为了表示“两个同名称的元素完全独立,需要重新渲染”就添加 key 值
如:
<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>
B.v-show
和v-if类似 区别:1.v-show哪怕是false 该标签的dom也在页面上存在 2.v-show 不支持 <template> 元素
6.列表渲染 V-FOR
A.v-for 循环数组
v-for 指令需要使用 item in/of items 形式的特殊语法
并且有第二个可选参数,为当前项的索引 (item, index) in items
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
var example2 = new Vue({
el: '#example-2',
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
}) B.v-for循环对象
一共可以提供三个参数作为索引:
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
new Vue({
el: '#v-for-object',
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
}) C.数组更新检测
找到一些方法,既又能改变数组,又能更新页面
变异方法:
使用这七种变异方法,可以实现页面更新效果:
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
通过改变引用,用新数组替代旧数组来实现效果:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
}) Set方法: 通过使用全局方法Vue.set也可以实现响应更新:
// Vue.set Vue.set(vm.items, indexOfItem, newValue)也可以使用实例方法vm.$set
m.$set(vm.items, indexOfItem, newValue)
D.对象更新检测
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。
但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性
var vm = new Vue({
data: {
userProfile: {
name: 'Anika'
}
}
})
//全局方法:
Vue.set(vm.userProfile, 'age', 27)
//实例方法:
vm.$set(vm.userProfile, 'age', 27) E.显示过滤/排序后的结果
可以创建一个计算属性,来返回过滤或排序后的数组:
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
} F.v-for其他使用
在整数上使用:把模板重复对应次数
当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
可是实现为部分节点进行渲染,如:
在组件上使用:
在组件上使用v-for,必须设定key值,但是数据不会被自动传到组件里,需要使用prop
<div>
<span v-for="n in 10">{{ n }} </span>
</div> 在<template>上使用:可以循环渲染一段包含多个元素的内容 <ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul> 与v-if一同使用:当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。
可是实现为部分节点进行渲染,如:
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li> 上面的代码将只渲染未完成的 todo。在组件上使用:
在组件上使用v-for,必须设定key值,但是数据不会被自动传到组件里,需要使用prop
//定义组件
Vue.component('todo-item', {
template: '\
<li>\
{{ title }}\
<button v-on:click="$emit(\'remove\')">Remove</button>\
</li>\
',
props: ['title']
})
//组件实例
<ul>
<li
is="todo-item"
v-for="(todo, index) in todos"
v-bind:key="todo.id"
v-bind:title="todo.title"
v-on:remove="todos.splice(index, 1)"
></li>
</ul> 
京公网安备 11010502036488号