vue.js官网教程学习笔记和学习摘要
起步
安装
一个简单的方法,直接把一个vue.js引入你的HTML页面中,就像引入一个jq框架一样,首先你要下载js文档,然后用script标签把它引进去,然后在</body>之前写一个<script>标签,将你的vue.js代码写进去
- step1:进入vue.js的官网:http://cn.vuejs.org/
- step2:点 "安装v1.026"
点“开发版本”,然后就把一个“vue.js”文件下载下来了。
-
step3:你的页面结构
HTML文件中:
记住:1.引入vue.js文件 2.在<script>标签中写vue.js代码
运行效果:
概述
响应的数据绑定
Vue.js 的核心是一个响应的数据绑定系统,它让数据与 DOM 保持同步非常简单。
Vue.js 拥抱数据驱动的视图概念。
组件系统
组件系统是 Vue.js 另一个重要概念,因为它提供了一种抽象,让我们可以用独立可复用的小组件来构建大型应用。
vue实例
构造器:
- 每个vue.js应用的起步都是通过构造函数Vue创建一个Vue的根实例
var vm = new Vue({
// 选项
})
- 实例化Vue时需要传入选项对象,例如数据(data)、模板(template)、挂在元素、方法(method)、生命周期钩子(例如:create)等选项。
eg:
var vm = new Vue({
data:{
message:'hello'
},
method:{
reverseMessage:function(){
xxx;
}
}
})
扩展vue构造器:预定义选项,创建可复用的组件构造器
var MyComponent = Vue.extend({
// 扩展选项
})// 所有的 `MyComponent` 实例都将以预定义的扩展选项被创建
var myComponentInstance = new MyComponent()
- 所有的 Vue.js 组件其实都是被扩展的 Vue 实例。
属性与方法
每个 Vue 实例都会代理其 data 对象里所有的属性:
var data = { a: 1 }
var vm = new Vue({
data: data//这里的data是被代理的属性
})
vm.a === data.a // -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3
实例属性与方法
前缀:$
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
// 这个回调将在 `vm.a` 改变后调用
}
实例生命周期
Vue 实例在创建时有一系列初始化步骤——例如,它需要建立数据观察,编译模板,创建必要的数据绑定。在每个过程如果有相应的生命周期钩子,将会调用
var vm = new Vue({
data: {
a: 1
},
created: function () {//在实例创建后调用这个函数
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// -> "a is: 1"
数据绑定语法
- 插值
文本插值:(Mustache语法:双大括号)
eg:
<span id="app">Message: {{ msg }}</span>
<script>
var vm = new Vue() {
el:'#app',//指定ID
data:{
msg:'hello'//替换ID为“app”的{{message}}
}
})
</script>
- HTML 特性
Mustache 标签也可以用在 HTML 特性 (Attributes) 内:
<div id="item-{{ id }}"></div>
绑定表达式
双大括号内的文本称为绑定表达式,绑定表达式由一个简单的JavaScript表达式和可选的一个或者多个过滤器构成。
- JavaScript表达式
eg:
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
tip:每个绑定只能包含单个表达式
<!-- 这是一个语句,不是一个表达式: -->
{{ var a = 1 }}
<!-- 流程控制也不可以,可改用三元表达式 -->
{{ if (ok) { return message } }}
- 过滤器(管道语法)
eg:
{{ message | capitalize }}//message的值通过过滤器capitalize,capitalize过滤器的作用是变换成大写,所以message的值通过过滤器capitalize的结果是返回大写化的值
tip:管道语法不是JavaScript语法,因此不能在表达式内使用过滤器,只能添加到表达式的后面。
过滤器可以串联:{{ message | filterA | filterB }
指令
前缀:“v-”
指令的值:“绑定表达式”(JavaScript表达式、过滤器)
指令的职责:表达式的值改变式把某些特殊行为应用到DOM上
eg:
<p v-if="greeting">Hello!</p>
这里,v-if是一个指令,指令的值是表达式“greeting”的值,如果值为真,就插入< p>元素,如果是假,就删除< p>元素。
- 参数
eg:
<a v-bind:href="url"></a>//v-bind 指令用于响应地更新 HTML 特性,href是参数,它告诉v-bind指令将元素的href特性跟表达式url的值绑定
<a v-on:click="doSomething">//v-on 指令,它用于监听 DOM 事件
- 修饰符
- 以半角句号 . 开始的特殊后缀
- 用于表示指令应当以特殊方式绑定
eg:
<a v-bind:href.literal="/a/b/c"></a>//.literal 修饰符告诉指令将它的值解析为一个字面字符串而不是一个表达式
- 缩写
v-bind的缩写
eg:
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
<!-- 完整语法 -->
<button v-bind:disabled="someDynamicCondition">Button</button>
<!-- 缩写 -->
<button :disabled="someDynamicCondition">Button</button>
v-on的缩写
eg:
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
计算属性
eg:
var vm = new Vue({
el: '#example',
data: {
a: 1
},
computed: {
// 一个计算属性的 getter
b: function () {
// `this` 指向 vm 实例
return this.a + 1//b的值是计算出来的,依赖于a的值
}
}
})
- $watch方法:监测数据的变化
eg:
<div id="demo">{{fullName}}</div>
<script>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar',
fullName: 'Foo Bar'
}
})
vm.$watch('firstName', function (val) {//监测‘firstName’值的变化,如果变化,就调用后面这个函数,将firstName的新值传给参数val
this.fullName = val + ' ' + this.lastName
})
vm.$watch('lastName', function (val) {//监测‘lastName’值的变化,如果变化,就调用后面这个函数,将lasttName的新值传给参数val
this.fullName = this.firstName + ' ' + val
})
</script>
- 优化:因为上面的命令式回调是重复的,最好是使用计算属性
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})
- 也可以使用计算属性设置值:计算属性默认只是 getter,不过也可以提供一个 setter
eg:
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会被调用,为firstName和lastName赋值,'John Doe' 传给参数newValue,var names = newValue.split(' ')将newValue以’ ‘为分隔符分隔为一个数组储存在names里面,所以names[0]的值为John,names[names.length - 1]即names[1]的值为Doe,然后getter被调用,为fullName计算值。
Class 与 Style 绑定
绑定 HTML Class
- 对象语法
可以传给 v-bind:class 一个对象,以动态地切换 class。
v-bind:class 指令可以与普通的 class 特性共存
eg:
<div class="static" v-bind:class="{ 'class-a': isA, 'class-b': isB }"></div>
data: {
isA: true,
isB: false
}
class-a是一个类名,class-b也是一个类名,通过data的isA和isB设置是否为元素绑定相应的类。渲染为:
<div class="static class-a"></div>
也可以直接绑定一个对象
<div v-bind:class="classObject"></div>
data: {
classObject: {
'class-a': true,
'class-b': false
}
}
- 数组语法
可以把一个数组传给 v-bind:class,以应用一个 class 列表:
eg:
<div v-bind:class="[classA, classB]">
data: {
classA: 'class-a',
classB: 'class-b'
}
渲染为:
<div class="class-a class-b"></div>
也可以:
<div v-bind:class="[classA, isB ? classB : '']">
始终添加classA类,如果isB为true,就添加classB类,如果isB为false,就不添加classB。
也可以:
eg:
<div v-bind:class="[classA, { classB: isB, classC: isC }]">
始终添加classA类,根据isB的值选择是否添加classB,根据IsC选择是否添加classC。
绑定内联样式
- 对象语法
v-bind:style 的对象语法:
eg:
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
直接绑定到一个样式对象通常更好:
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
- 数组语法
v-bind:style 的数组语法可以将多个样式对象应用到一个元素上:
<div v-bind:style="[styleObjectA, styleObjectB]">
条件渲染
- v-if
eg:
<h1 v-if="ok">Yes</h1>
如果v-if的属性值——“ok”表达式的值为真,则显示“yes”,否则不显示“yes”。
eg:
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
如果v-if的属性值——“ok”表达式的值为真,则显示“yes”,否则不显示v-else对应的语句“No”。
- template v-if
如果想用v-if同时显示或者隐藏多个元素,可以用<template>将多个元素包裹起来。把一个 <template> 元素当做包装元素,并在上面使用 v-if,最终的渲染结果不会包含它。
eg:
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
<strong>
tip:官网教程页没有详细说明v-if的用法,因此我在学习时使用v-if写的例子出现了问题:
首先,一开始我以为代码是这样写的:
然而,虽然“ok”值为false,但是仍然显示:
控制台报错:
这个报错是说:v-if不可以用于根元素。
应将代码更正为:
即可以用一个< div>将带有v-if的元素包裹起来,这时候控制台就不会报错了。
同样地,使用<template>包裹多个元素时,,也要用一个< div>将带有v-if的<template>包裹起来。
代码:
显示效果:
</strong>
- v-show
用法大体和v-if一样:
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="two"><h1 v-show="ok">haha</h1></div>
<script>
var vm2 = new Vue({
el:"#two",
data: {
ok:true
}
})
</script>
</body>
</html>
显示效果:
- v-show与v-if的区别
1.v-show 不支持 <template> 语法。
2.v-show 的元素会始终渲染并保持在 DOM 中。v-show 是简单的切换元素的 CSS 属性 display。
eg:
显示效果:
检查元素查看代码渲染结果:
可见,v-show情况下即使为false,元素也会被渲染并保持在DOM中,只是display值为none。
v-if的情况下:
显示效果:
检查元素查看代码渲染结果:
看,v-if情况下,当值为false时,元素不会被渲染出来。
tip: 在切换 v-if 块时,Vue.js 有一个局部编译/卸载过程,因为 v-if 之中的模板也可能包括数据绑定或子组件。v-if 是真实的条件渲染,因为它会确保条件块在切换当中合适地销毁与重建条件块内的事件监听器和子组件。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——在条件第一次变为真时才开始局部编译(编译会被缓存起来)。
相比之下,v-show 简单得多——元素始终被编译并保留,只是简单地基于 CSS 切换。
一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。
- v-else
可以用 v-else 指令给 v-if 或 v-show 添加一个 “else 块”:
eg:
<div v-if="Math.random() > 0.5">
Sorry
</div>
<div v-else>
Not sorry
</div>
tip:v-else 元素必须立即跟在 v-if 或 v-show 元素的后面——否则它不能被识别。
- 组件警告
将 v-show 用在组件上时,因为指令的优先级 v-else 会出现问题。因此不要这样做:
<custom-component v-show="condition"></custom-component>
<p v-else>这可能也是一个组件</p>
用另一个 v-show 替换 v-else:
<custom-component v-show="condition"></custom-component>
<p v-show="!condition">这可能也是一个组件</p>
这样就可以达到 v-if 的效果。
列表渲染
- v-for
可以使用 v-for 指令基于一个数组渲染一个列表。这个指令使用特殊的语法,形式为 item in items,items 是数据数组,item 是当前数组元素的别名:
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
items:[
{message:'haha'},
{message: 'hehe'}
]
}
})
</script>
</body>
</html>
items是一个数组,使用v-for将该数组中的每个数组元素渲染,然后显示每个数组元素的message。
在 v-for 块内我们能完全访问父组件作用域内的属性,另有一个特殊变量 $index,它是当前数组元素的索引:
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="item in items">
{{ parentMessage }} - {{ $index }} - {{ item.message }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
parentMessage: 'Parent',
items:[
{message:'haha'},
{message: 'hehe'}
]
}
})
</script>
</body>
</html>
运行结果:
另外,可以为索引指定一个别名:
上面代码中,“xuhao”是为索引值起的一个别名,注意上下一致。
tip:从 1.0.17 开始可以使用 of 分隔符,更接近 JavaScript 遍历器语法:
<div v-for="item of items"></div>
- template v-for
类似于 template v-if,也可以将 v-for 用在 <template> 标签上,以渲染一个包含多个元素的块。
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<template v-for="(xuhao,item) in items">
<li>
{{ parentMessage }} - {{ xuhao }} - {{ item.message }}
</li>
<li>yiyi</li>
</template>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
parentMessage: 'Parent',
items:[
{message:'haha'},
{message: 'hehe'}
]
}
})
</script>
</body>
</html>
因为v-for是在template上的,而每个template都有< li>yiyi</li>,所以会被多次渲染出来。
- 变异方法
push():增加数组元素;
pop():删除数组元素;
reverse():将该数组元素向前移动一位。
eg1:
看,代码中原本是“haha”在前,“hehe”在后,使用reverse()后,“hhe”移动到了前面。
eg2:
看,pop()之后只剩一个数组元素。
eg3:
看,push()之后为数组动态地添加了一个新元素。
- 问题
因为 JavaScript 的限制,Vue.js 不能检测到下面数组变化:
直接用索引设置元素,如 vm.items[0] = {};
修改数据的长度,如 vm.items.length = 0。
vue.js用索引设置数组元素:$set(索引值,新元素)
- 对象v-for
可以使用 v-for 遍历对象。作用域内还可以访问另外一个特殊变量 $key。
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="value in object">
{{ $key }} : {{ value }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
object: {
FirstName: 'Frank',
LastName: 'Jane',
age: 20
}
}
})
</script>
</body>
</html>
也可以给对象的键提供一个别名:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<ul id="three">
<li v-for="(key,value) in object">
{{ key }} : {{ value }}
</li>
</ul>
<script>
var vm3 = new Vue ({
el:"#three",
data: {
object: {
FirstName: 'Frank',
LastName: 'Jane',
age: 20
}
}
})
</script>
</body>
</html>
方法与事件处理器
方法处理器
- v-on监听DOM事件
eg:
<!DOCTYPE html>
<html>
<head>
<title>try</title>
<script type="text/javascript" src="vue.js"></script>
</head>
<body>
<div id="four">
<button v-on:click="greet">greet</button>//为button绑定一个单击事件处理器,当被点击时执行greet方法
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
greet: function (event) {
alert('hello ' + this.name + '!')
alert(event.target.tagName)
}
}
})
vm3.greet();//页面加载后执行此函数,因为没有调用它的元素,所以不会执行alert(event.target.tagName)这一句
</script>
</body>
</html>
运行结果:
点击按钮:
内联语句处理器
eg:
<div id="four">
<button v-on:click="greet('hi')">greet</button>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
greet: function (msg) {
alert(msg)
}
}
})
</script>
点击按钮:
有时也需要在内联语句处理器中访问原生 DOM 事件。可以用特殊变量 $event 把它传入方法:
eg:
<div id="four">
<button v-on:click="greet('hi',$event)">greet</button>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
greet: function (msg,event) {
alert(event)
}
}
})
</script>
事件修饰符
Vue.js 为 v-on 提供两个 事件修饰符:.prevent 与 .stop
<a v-on:click.stop="doThis"></a>
<form v-on:submit.prevent="onSubmit"></form>
eg1:
<div id="four">
<button v-on:click="doThis"><a v-on:click="doThis">greet</a></button>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
name:'vue.js'
},
methods: {
doThis: function (event) {
alert('haha')
}
}
})
</script>
上例会冒泡,点击的时候会出现两次弹窗,因为冒泡,< a>和< button>都触发了click。
eg2:
上例不会冒泡,点击的时候只出现一次弹窗。
eg3:
由于submit按钮的默认行为,点击submit后会重载页面,因此会发现,在此例中,点击submit后,首先出现了弹窗,然后整个页面被刷新。
eg4:
添加了事件修饰符,.prevent,避免了点击提交按钮的时候页面被重载。
按键修饰符
监听键盘事件时,vue.js允许为v-on添加按键修饰符,并为最常用的按键提供了别名:
- 全部的按键别名:
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
eg:
按下tab键时,执行submit方法,出现弹窗。
表单控件绑定
基础用法
- Text
eg:
<div id="four">
<span>Message is: {{ message }}</span>
<br>
<input type="text" v-model="message" placeholder="edit me" />
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
注意:一定要将“Message is”和input输入框包裹在一起,上例中将它们用一个div包裹在一起,并且id要写在包裹它们的标签上,即div标签上。
实现双向数据绑定,同步显示。
- Multiline text
eg:
<div id="four">
<span>Message is: </span>
<p>{{ message }}</p>
<br>
<textarea v-model="message" placeholder="edit me"></textarea>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
- checkbox
单个勾选框
eg:
<div id="four">
<input type="checkbox" id="check" v-model="checked">
<label for="check">{{ checked }}</label>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
会根据勾选状态改变勾选框的label值。
多个勾选框,选中的同时显示选中的value值:
eg:
<div id="four">
<input type="checkbox" id="jack" v-model="checkedName" value="jack">
<label for="jack">jack</label>
<input type="checkbox" id="jane" v-model="checkedName" value="jane">
<label for="jane">jane</label>
<input type="checkbox" id="jim" v-model="checkedName" value="jim">
<label for="jim">jim</label>
<br>
<span>check: {{ checkedName }} </span>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
checkedName:[]
},
})
</script>
- radio
eg:
<div id="four">
<input type="radio" id="one" value="one" v-model="message">
<label for="one">one</label>
<input type="radio" id="two" value="two" v-model="message">
<label for="two">two</label>
<br>
<span>picked: {{ message }}</span>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
message:''
},
})
</script>
- select
eg:
<div id="four">
<select v-model="select">
<option selected="selected">A</option>
<option>B</option>
<option>C</option>
</select>
<span>selected: {{ select }}</span>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
select:''
},
})
</script>
eg2:
动态选项,用v-for渲染:
eg:
<div id="four">
<select v-model="select">
<option v-for="option in options" v-bind:value="option.value">//v-bind:value为option设置value值
{{ option.text }}//option.text为option设置标签文本
</option>
</select>
<br>
<span>selected: {{ select }}</span>//select和v-model对应,v-model指示的是option的value值
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
options:[
{ text:'one', value:'a'},
{ text:'two', value:'b'},
{ text:'three', value:'c'}
]
},
})
</script>
- 绑定value值
绑定 value 到 Vue 实例的一个动态属性上,这时可以用 v-bind 实现,并且这个属性的值可以不是字符串。
eg:
<div id="four">
<input type="checkbox" id="check" v-model="checked" v-bind:true-value="yes" v-bind:false-value="no">
<label for="check">{{ checked }}</label>
</div>
<script>
var vm3 = new Vue ({
el:"#four",
data: {
checked:'',
yes:'yes',
no:'no'
},
})
</script>
这样,当单选框被勾选时,value值为vue实例中的yes属性值,当单选框不被勾选时,value值为vue实例中的no属性值。
- 参数特性
lazy:
在默认情况下,v-model 在input 事件中同步输入框值与数据,可以添加一个特性 lazy,从而改到在 change 事件中同步:
number:
如果想自动将用户的输入转为 Number 类型(如果原值的转换结果为 NaN 则返回原值),可以添加一个特性 number:
debounce:
debounce 设置一个最小的延时,在每次敲击之后延时同步输入框的值与数据。如果每次更新都要进行高耗操作(例如在输入提示中 Ajax 请求),它较为有用。
注意 debounce 参数不会延迟 input 事件:它延迟“写入”底层数据。因此在使用 debounce 时应当用 vm.$watch() 响应数据的变化。若想延迟 DOM 事件,应当使用 debounce 过滤器。