构造器
实例化 vue 时,需要传入一个选项对象,包括 数据
、模板
、挂件元素
、方法和生命周期钩子
属性与方法
- 每个 vue 实例都会代理其
data
对象里所有的属性 - 实例中会有一些实例的属性和方法,这些属性和方法都有前缀
$
(便于与代理data
属性区分)
生命周期视图
https://cn.vuejs.org/images/lifecycle.png
实例生命周期
name | description |
---|---|
created 钩子 | 在实例被创建后被调用 |
mounted | 当编译好的 HTML 被挂载到对应的位置,这个操作完成后触发 |
updated | 当data 中的数据改变,并且虚拟 DOM 重新渲染完成后触发 |
destroyed | |
注意 | 钩子的this 指向调用它的实例 |
插值
1. 文本
- 双大括号
{{ }}
v-text
2. 纯 HTML
v-html
3. 属性
-
v-bind
(双括号不能在属性中使用,因此需使用v-bind
)
4. 使用 JavaScript 表达式
指令
例举一些指令
v-bind
v-on
修饰符 | 描述 |
---|---|
.stop |
阻止单击事件冒泡<a v-on:click.stop="doThis"></a>
|
.prevent |
提交事件不再重载页面 |
.capture |
添加事件侦听器时使用时间捕获模式 |
.self |
只当事件在该元素本身(而不是子元素)触发时触发回调 |
... | 等等 |
v-if
<div id="app">
<template v-if="ok==='username'">
用户名: <input type="text" placeholder="请输入用户名" key="name-input">
</template>
<template v-else>
密码: <input type="text" placeholder="请输入密码" key="psd-input">
</template>
<button @click="toggle">点击切换类型</button>
</div>
new Vue({
el: "#app",
data: {
ok:'username'
},
methods: {
toggle: function(todo){
if(this.ok==='username'){
this.ok = 'psd'
}else{
this.ok = 'username';
}
}
}
})
https://jsfiddle.net/18613326395/zrkL9wj3/
v-for
<ul>
<li v-for="item in items">{{item}}</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
items:['a','b','c']
},
methods: {
toggle: function(todo){
todo.done = !todo.done
}
}
})
https://jsfiddle.net/18613326395/s3fu7tmk/
过滤器
用于将文本转化成你想要的格式
filters
<div id="app">
<p>{{message | changeChar}}</p>
<button @click="changeFirstChar">改变</button>
</div>
new Vue({
el: "#app",
data: {
message:'nihao'
},
methods: {
changeFirstChar: function(todo){
this.message = 'good evening'
}
},
filters:{
changeChar(value){
if(!value){
return '';
}else{
return value.charAt(0).toUpperCase()+value.substring(1)
}
}
}
})
https://jsfiddle.net/18613326395/z81xsma3/1/
缩写
v-bind
<a v-bind:href="url"></a>
---
<a :href="url"></a>
v-on
<button v-on:click="doSomeThing"></button>
---
<button @click="doSomeThing"></button>
计算属性
计算属性(减少模板{{}}
的复杂度)
computed
<div id="app">
{{fullName}}
</div>
new Vue({
el: "#app",
data: {
firstName:'Ji',
lastName:'RenGu'
},
computed:{
fullName(){
return this.firstName+'----'+this.lastName;
}
}
})
计算(computed
) vs 方法(methods
)
计算属性computed
具有缓存,而methods
无缓存
计算(computed
) vs 侦听器(watch
)
watch
方法--观察Vue实例上的数据变动,只要指定的数据改变就会执行预定的函数
watch
<div id="app">
{{msg}} <br>
改变了吗? {{isChange}}
<button @click="change">改变</button>
</div>
new Vue({
el: "#app",
data: {
msg:'欲穷千里目',
isChange:'No'
},
watch:{
//只要msg改变,这个方法就会执行
msg(val,oldVal){
this.isChange = 'Yes'
}
},
methods:{//不得不说ES6写起来真爽
change(){
this.msg = '更上一层楼'
}
}
})
计算属性的两种方法:
get
和set
,顾名思义,一个是获得,一个是设置,常规上来讲,计算属性中都是有get
和set
方法,默认是只有getter
方法,如果需要的话,可以写一个setter
方法,看下面例子
<div id="app">
此时的onpiece: {{onepiece}} <br>
此时的msg: {{msg}} <br><br>
<button @click="setName">设置name</button>
</div>
new Vue({
el: "#app",
data: {
name:'Kobe',
msg:''
},
methods:{
setName(){
this.onepiece = 'JorDan'
}
},
computed:{
onepiece:{
get(){
return this.name +'Bryant'
},
set(newVal){
//当你给 onepiece 设置值的时候 set 就就会调用
this.msg = newVal+'is the greatest basketball player'
}
}
}
})
class 与 style 绑定
绑定HTML class
-
对象语法
- 基本
- 在对象中传入多个 class 属性(其会与原有 class 共存)
- 直接传入对象
- 与计算属性一起使用(绑定返回对象的计算属性)
-
数组语法
- 简单例子
- 三元表达式
- 当有多个条件 class 时,可以在数组语法中使用对象语法
-
用在组件上
简单例子
绑定HTML class例子
绑定class的几种方式
.classC{
color:red;
}
.classD{
font-weight:bold;
}
.classE{
font-size:20px;
}
.classF{
color:blue;
}
.classM{
display:block;
}
.classN{
display:none;
}
<div id="app">
<h2>class属性绑定</h2>
-------------------绑定变量-------------------------
<div :class="{classA:a,classB:b}">
绑定变量
</div>
-------------------绑定对象-------------------------
<div :class="styleObj">
绑定对象
</div>
-------------------绑定数组-------------------------
<div :class="arrClass">
绑定数组
</div>
-------------------绑定三元运算符------------------
<div :class="m==true?'classM':'classN'">
绑定变量
</div>
<button @click="toggle">toggle</button>
</div>
new Vue({
el: "#app",
data: {
a:true,
b:false,
styleObj:{
classC:true,
classD:true
},
m:true,
arrClass:['classE','classF']
},
methods:{
toggle(){
this.m=!this.m;
}
}
})
绑定内联样式
-
对象语法
内联式对象语法
样式对象式对象语法(更推荐) - 数组语法
-
自动添加前缀
v-bind:style
当需要特定的前缀时如transform
,vue.js会自动添加 -
多重值
从vue2.3+后,可以为一个属性添加多个值的数组,常用于含有多个前缀的情况
条件渲染
v-if(v-else)是真正的渲染
-
template
元素与v-if
-
v-else
(需要紧跟在v-if后边) -
v-else-if
(vue2.1.0新增) - 用
key
管理可复用的元素
例子:用户名和邮箱登录界面 如果有key
就不会复用,把key
去试一下,然后再次输入看一下效果
<div id="app">
<template v-if="ok==='username'">
用户名: <input type="text" placeholder="请输入用户名" key="name-input">
</template>
<template v-else>
密码: <input type="text" placeholder="请输入密码" key="psd-input">
</template>
<button @click="toggle">点击切换类型</button>
</div>
new Vue({
el: "#app",
data: {
ok:'username'
},
methods: {
toggle: function(todo){
if(this.ok==='username'){
this.ok = 'psd'
}else{
this.ok = 'username';
}
}
}
})
v-show(其只是简单的切换display属性)
-
v-show
不支持template
语法 -
v-show
不支持v-else
v-if vs v-show
-
v-if
1.当条件不成立时不会渲染
2.切换开销较大,适合不太可能变化的场景 -
v-show
1.无论成不成立都会渲染
2.首次渲染开销较大,但切换开销小,因此适合经常变化的场景
列表渲染
v-for
-
基本用法
i. 简单例子
ii. 带有index参数
iii.使用of 替代 in -
template v-for
i. 简单例子 -
对象迭代 v-for
i. 基础用法
ii. 带其他参数用法 -
整数迭代 v-for
例子 -
组件和v-for
i. 包含所有类型的例子
//遍历数组:
<ul>
<li v-for="item in items">{{item}}</li>
<ul>
//遍历数组对象:
<ul>
<li v-for="(item, index) in pers">
{{index}} 名字:{{item.name}},年龄:{{item.age}}
</li>
<ul>
//遍历对象:
<ul>
<li v-for="(value, key) in obj">
key: {{key}}
value: {{value}}
</li>
<ul>
data: {
items: ['banana', 'apple', 'orange'],
pers: [{
name: 'Kobe',
age: '40'
},
{
name: 'James',
age: '38'
}],
obj: {
1: 'one',
2: 'two'
}
}
key
作用:用v-for更新已渲染过的列表时,它默认采用的是“就地复用”的原则,也就是如果数据项顺序发生了改变,vue将不是移动DOM元素来匹配数据项的顺序,而是简单复用此处的元素。如果想跟踪每个节点的身份,从而重用或重新排列现有元素,可使用key。(key还可用在v-if中,详见v-if中的邮箱名和用户名切换的例子)
还是不懂,看下面的例子
<div id="app">
KEY: <input type="text" v-model="id">
VALUE: <input type="text" v-model="name">
<button @click="add">添加</button>
<ul>
<li v-for='item in list' :key="item.id"> //---
<input type="checkbox">
{{item.id}}---{{item.name}}
</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
list:[
{id:1, name:'李斯'},
{id:2, name:'嬴政'},
{id:3, name:'赵高'},
{id:4, name:'韩非'},
{id:5, name:'荀子'},
]
},
methods: {
add: function(){
this.list.unshift({id:this.id, name:this.name})
}
}
})
试着把 key 先去掉,然后勾选一条,点击添加;再加上 key 重复下操作。就会发现微妙的地方
数组更新检测
-
变异方法(会改变原有数组)
push()
pop()
shift()
splice()
sort()
reverse() -
重塑数据
filter()
concat()
slice() -
注意事项
利用索引直接设置一个项时,vue不能检测变动,如:vm.items[indexOfItem] = newValue
那如果设置某一项的该怎么设置呢?
-1.Vue.set(example1.items, indexOfItem, newValue)
-2.example1.items.splice(indexOfItem, 1, newValue)
<div id="app">
<button @click="setZF">设置第二项为张飞</button>
<button @click="setGY">设置第三项为关羽</button>
<ul>
<li v-for="item in list">
<input type="checkbox">{{item.id}}---{{item.name}}
</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
id: '',
name: '',
list:[
{id:1, name:'李斯'},
{id:2, name:'嬴政'},
{id:3, name:'赵高'},
{id:4, name:'韩非'},
{id:5, name:'荀子'},
]
},
methods: {
setZF: function(){
Vue.set(this.list,1,{id:2,name:'张飞'})
},
setGY: function(){
this.list.splice(2,1,{id:3,name:'关羽'})
}
}
})
注意:
- 修改数组长度时,vue 不能检测变动,如 `vm.items.length = newLength
- 只能用`example1.items.splice(newLength)
对于显示过滤 / 排序结果的两种方法
过滤数组--计算属性 (computed
)
<div id="app">
{{specialNum}}
</div>
new Vue({
el: "#app",
data: {
nums: [1,2,3,4,5,6,7,8,9]
},
computed: {
specialNum() {
return this.nums.filter((item, index) => {return item%3 == 0})
}
}
})
过滤数组--方法 (method
)
<div id="app">
<ul> //在 v-for 循环中,直接嵌入方法
<li v-for="item in fil(numbers)">{{item}}</li>
</ul>
</div>
new Vue({
el: "#app",
data: {
numbers:[1,2,3,4,5,6,7,8,9]
},
methods:{
fil(nums){
return nums.filter((item,index)=>{
return item%3==0;
})
}
}
})
事件处理器
用v-on
来绑定事件,两个简单的例子
<div id="app">
<button @click="num+=1">增加1</button>
{{num}}
</div>
new Vue({
el: "#app",
data: {
num: 0
},
})
<div id="app">
<button @click="sayHello">点击sayHello</button>
</div>
new Vue({
el: "#app",
methods: {
sayHello: function(){
alert('sayHello')
}
}
})
内联处理器方法
访问原生DOM事件的例子,如果click事件不传参数,就默认把原生DOM传递进去
<div id="app"> <!-- 没有传参数,就是原生的!!! -->
<button @click="showBtnname">显示按钮的名字</button> <br>
{{msg}}
</div>
new Vue({
el: "#app",
data: {
msg:''
},
methods: {
showBtnname: function(e){
this.msg = e.target.innerText;
}
}
})
未访问原生DOM事件的例子,如果传了参数.那么方法中接受的第一个参数就是该参数,在vue中所有的事件绑定都是这样的