注:新版本中没有$index、$key了。
vue.js没有Angular强大,非常经量级.
MVVM,数据双向绑定。
官网:https://cn.vuejs.org
附:AngluaJs,vue.js,react.js这三个都比较相似。
vue两大模块:数据绑定、组件系统.
组件系统:可以自定义html元素.
var user = {
UserName: '张三',
Sex: 0
};
var app=new Vue({
el: '#app',
data:user,
});
console.log(app.$el === document.getElementById('app'));//打印结果为true.
user.UserName='李四' 或者 app.UserName='李四' 都是一样的。
app.其实是访问data.
{{* }}:加个*号,只更新一次,以后model的值发生变化,不再更新视图。
<div v-html="testHTML"></div>:插入html
支持javascript表达式,例如:
{{number+1}}、{{ok?'YES':'NO'}},{{message.splite('').reverse().join('')}}
过滤器:{{表达式 | 过滤器1 | 过滤器2 | 过滤器3 | ....}}
例如:{{name | uppercase}} : 把name的值变为大写再插入.
uppercase是内置的过滤器,也可以创建自己的过滤器。
过滤器也可以传入叁数:例如:{{message | filterA 'arg1' arg2}}
指令:v- 开头
<p v-if='show'></p>
指令参数:有些指令可以在其名称后面带一个参数,用冒号隔开。
例如:<a v-bind:href='url'></a> <a v-on:click='doSomethine'></a>
指令修饰符:以.号开始的特殊后缀,用于表示指令应当以特殊方法绑定。
例如:<a v-bind:href.literal='/a/b/c'></a>
.leteral表示/a/b/c原样输出,而不是a除以b再除以c.
指令缩写:v-bind和v-on这两个指令可以缩写(只有这两个指令可以缩写).
v-bind这样缩写:
<a :href='url'></a>
v-on这样缩写:
<a @click='doSomething'></a>
计算属性:
<div>{{SexName}}</div>
var app=new Vue({
el: '#app',
data: {Sex:0},
computed: { SexName: function () { if (this.Sex == 0) { return '女' } else {return '男' }; } }
});
data并没有SexName,而是在cumputed中,这就是计算属性。
Sex变化,SexName也会自动跟着变化,并更新视图。
SexName就是一个getter.
$watch:观察数据变动。
app.$watch('Sex',function(val){
if (val == 0) { this._sexName='女' } else {this._sexName='男' }
});
计算setter
var user = {
Sex: 0
};
var app;
$(function () {
app=new Vue({
el: '#app',
data: user,
computed: {
SexName: {
get: function () { if (this.Sex == 0) { return '女' } else { return '男' }; },
set: function (val) { if (val == "女") { this.Sex = 0 } else {this.Sex=1 } }
}
}
});
});
app.SexName = '女';//界面会更新.
user.SexName = '女';//界面不会更新.原因:在执行该句之前,user并没有定义SexName.
表达式结果可以是对象或数组。
class对象语法:
<div class='static' v-bind:class="{'class-a':isA,'class-b':isB}"></div>
data:{
isA:true,
isB:false
}
<div v-bind:class="classObject"></div>
data:{
classObject:{
'class-a':true,
'class-b':false
}
}
class数组语法:
<div v-bind:class="[classA,classB]"></div>
data:{
classA:'class-a',
classB:'class-b'
}
<div v-bind:class="[classA,isB?classB:'']"></div>
<div v-bind:class="[classA,{classB:isB,classC:isC}]"></div>
style对象语法:
<div v-bind:style="{color:activeColor,fontSize:fontSize+'px',}"></div>
css属性名可以用驼峰式或短横线分隔命令.
data:{
activeColor:'red',
fontSize:30
}
<div v-bind:style="styleObject"></div>
data:{
styleObject:{
color:'red',
fontSize:'13px'
}
}
style数组语法:
<div v-bind:style="[styleObjectA,styleObjectA]"></div>
data:{
styleObjectA:{
color:'red',
fontSize:'13px'
},
styleObjectB:{
textDecoration:'underline',
background:'blue'
}
}
自动添加前缀:例如:transform.
data:{
styleObject:{
transform:'rotate(45deg)'
}
}
v-if:假则移除元素
template v-if
<template v-if='display'>
<h1>Title</h1>
<p>aaaaaaa</p>
<p>bbbbbbb</p
</template>
template标签起包裹作用,生成的是template标签裹的html.0
v-show:假则隐藏元素,但不移除元素.不支持<template>
v-else : 给v-if或v-show添加一个else块:
<div v-if="Math.random()>0.5">AAA</div>
<div v-else>BBB</div>
v-else元素必须立即跟在v-if或v-show元素的后面,否则不能被识别.
v-for:
<ul>
<li v-for='item in items'>{{item.msg}}</li>
</ul>
在v-for块内能访问父组件作用域名的属性.
<ul>
<li v-for='(item,index) in items'>{{parentMsg}}-{{index}}-{{item.msg}}</li>
</ul>
data:{
parentMsg:'parent',
items:{
{msg:'aaa'},
{msg:'bbb'}
}
}
template v-for
数组变动检测:
1)变异方法:
push()/pop()
shift()/unshift()
splice()
sort()/reverse()
2)替换数组:
demo.items=getItems(param);//getItems(param)动态返回一个数组
filter()/concat()/slice()
3)track-by(视频中说这个是老版本的)
lls:新版本:<div v-for="item in items" v-bind:key="item.id">
问题:
用全新对象替换数组,使用v-bind:key给vue.js提示,已尽可能地复用已有实例。这样可以提升性能。
(虽然是一个全新的数组,但两个数组中某些元素是一样的)
items:[{id:1,...},{id:2,...}]
如果新数组的某个素素的id与旧数据中某个元素的id相同,视为同一个元素.
由于javascript的限制,vue.js不能检到下面数组变化:
1、直接用索引设置元素,如:app.items[0]={}
vue.js解决办法:为数组添加了一个$set()方法:
app.items.$set(0,{userName:'abc'});
2、修必数据的长度,如:app.items.length=0;
vue.js解决办法:用一个空数组替换items.
vue.js还为数组添加了$remove()方法(),内部自动调用splice()
app.items.$remove(item);
v-for遍历对象:
<li v-for='(value,key,index) in user'>{{key}}={{value}}</li>
值域v-for: 接收一个整数,此时它将重复模版数次。
<li v-for="n in 10">{{n}}</li> //渲染10个li,n从1到10.(老版本n从0到9)
显示过滤/排序结果:
想要显示过滤/排序过的数组,同时不实际修改或重置原始数据,有两个方法:
1、创建一个计算属性,返回过滤/排序过的数组。
2、使用内置的过滤器filterBy和orderBy.
计算属性有更好的控制力,也更灵活,因为它是全功能javascript.但是通常过滤器更方便。
过滤器:https://cn.vuejs.org/v2/guide/filters.html
{{ message | capitalize }}
你可以在一个组件的选项中定义本地的过滤器:
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
或者在创建 Vue 实例之前全局定义过滤器:
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
// ...
})
lls:文档中说:orderBy过滤器老版本已经不再使用了,直接使用计算属性。
<p v-for="user in orderedUsers">{{ user.name }}</p>
computed: {
orderedUsers: function () {
return _.orderBy(this.users, 'name');//lls : this就是Vue()构造函数中传入的那个data
}
}
// _.orderBy()使用的是Lodash类库。
lls:filterBy也使用计算属性
替换老版本的 filterBy 过滤器:(摘自官方文档)
<p v-for="user in filteredUsers">{{ user.name }}</p>
computed: {
filteredUsers: function () {
var self = this;//lls : this就是Vue()构造函数中传入的那个data
return self.users.filter(function (user) {
return user.name.indexOf(self.searchQuery) !== -1
})
}
}
vue.js没有Angular强大,非常经量级.
MVVM,数据双向绑定。
官网:https://cn.vuejs.org
附:AngluaJs,vue.js,react.js这三个都比较相似。
vue两大模块:数据绑定、组件系统.
组件系统:可以自定义html元素.
var user = {
UserName: '张三',
Sex: 0
};
var app=new Vue({
el: '#app',
data:user,
});
console.log(app.$el === document.getElementById('app'));//打印结果为true.
user.UserName='李四' 或者 app.UserName='李四' 都是一样的。
app.其实是访问data.
{{* }}:加个*号,只更新一次,以后model的值发生变化,不再更新视图。
<div v-html="testHTML"></div>:插入html
支持javascript表达式,例如:
{{number+1}}、{{ok?'YES':'NO'}},{{message.splite('').reverse().join('')}}
过滤器:{{表达式 | 过滤器1 | 过滤器2 | 过滤器3 | ....}}
例如:{{name | uppercase}} : 把name的值变为大写再插入.
uppercase是内置的过滤器,也可以创建自己的过滤器。
过滤器也可以传入叁数:例如:{{message | filterA 'arg1' arg2}}
指令:v- 开头
<p v-if='show'></p>
指令参数:有些指令可以在其名称后面带一个参数,用冒号隔开。
例如:<a v-bind:href='url'></a> <a v-on:click='doSomethine'></a>
指令修饰符:以.号开始的特殊后缀,用于表示指令应当以特殊方法绑定。
例如:<a v-bind:href.literal='/a/b/c'></a>
.leteral表示/a/b/c原样输出,而不是a除以b再除以c.
指令缩写:v-bind和v-on这两个指令可以缩写(只有这两个指令可以缩写).
v-bind这样缩写:
<a :href='url'></a>
v-on这样缩写:
<a @click='doSomething'></a>
计算属性:
<div>{{SexName}}</div>
var app=new Vue({
el: '#app',
data: {Sex:0},
computed: { SexName: function () { if (this.Sex == 0) { return '女' } else {return '男' }; } }
});
data并没有SexName,而是在cumputed中,这就是计算属性。
Sex变化,SexName也会自动跟着变化,并更新视图。
SexName就是一个getter.
$watch:观察数据变动。
app.$watch('Sex',function(val){
if (val == 0) { this._sexName='女' } else {this._sexName='男' }
});
计算setter
var user = {
Sex: 0
};
var app;
$(function () {
app=new Vue({
el: '#app',
data: user,
computed: {
SexName: {
get: function () { if (this.Sex == 0) { return '女' } else { return '男' }; },
set: function (val) { if (val == "女") { this.Sex = 0 } else {this.Sex=1 } }
}
}
});
});
app.SexName = '女';//界面会更新.
user.SexName = '女';//界面不会更新.原因:在执行该句之前,user并没有定义SexName.
表达式结果可以是对象或数组。
class对象语法:
<div class='static' v-bind:class="{'class-a':isA,'class-b':isB}"></div>
data:{
isA:true,
isB:false
}
<div v-bind:class="classObject"></div>
data:{
classObject:{
'class-a':true,
'class-b':false
}
}
class数组语法:
<div v-bind:class="[classA,classB]"></div>
data:{
classA:'class-a',
classB:'class-b'
}
<div v-bind:class="[classA,isB?classB:'']"></div>
<div v-bind:class="[classA,{classB:isB,classC:isC}]"></div>
style对象语法:
<div v-bind:style="{color:activeColor,fontSize:fontSize+'px',}"></div>
css属性名可以用驼峰式或短横线分隔命令.
data:{
activeColor:'red',
fontSize:30
}
<div v-bind:style="styleObject"></div>
data:{
styleObject:{
color:'red',
fontSize:'13px'
}
}
style数组语法:
<div v-bind:style="[styleObjectA,styleObjectA]"></div>
data:{
styleObjectA:{
color:'red',
fontSize:'13px'
},
styleObjectB:{
textDecoration:'underline',
background:'blue'
}
}
自动添加前缀:例如:transform.
data:{
styleObject:{
transform:'rotate(45deg)'
}
}
v-if:假则移除元素
template v-if
<template v-if='display'>
<h1>Title</h1>
<p>aaaaaaa</p>
<p>bbbbbbb</p
</template>
template标签起包裹作用,生成的是template标签裹的html.0
v-show:假则隐藏元素,但不移除元素.不支持<template>
v-else : 给v-if或v-show添加一个else块:
<div v-if="Math.random()>0.5">AAA</div>
<div v-else>BBB</div>
v-else元素必须立即跟在v-if或v-show元素的后面,否则不能被识别.
v-for:
<ul>
<li v-for='item in items'>{{item.msg}}</li>
</ul>
在v-for块内能访问父组件作用域名的属性.
<ul>
<li v-for='(item,index) in items'>{{parentMsg}}-{{index}}-{{item.msg}}</li>
</ul>
data:{
parentMsg:'parent',
items:{
{msg:'aaa'},
{msg:'bbb'}
}
}
template v-for
数组变动检测:
1)变异方法:
push()/pop()
shift()/unshift()
splice()
sort()/reverse()
2)替换数组:
demo.items=getItems(param);//getItems(param)动态返回一个数组
filter()/concat()/slice()
3)track-by(视频中说这个是老版本的)
lls:新版本:<div v-for="item in items" v-bind:key="item.id">
问题:
用全新对象替换数组,使用v-bind:key给vue.js提示,已尽可能地复用已有实例。这样可以提升性能。
(虽然是一个全新的数组,但两个数组中某些元素是一样的)
items:[{id:1,...},{id:2,...}]
如果新数组的某个素素的id与旧数据中某个元素的id相同,视为同一个元素.
由于javascript的限制,vue.js不能检到下面数组变化:
1、直接用索引设置元素,如:app.items[0]={}
vue.js解决办法:为数组添加了一个$set()方法:
app.items.$set(0,{userName:'abc'});
2、修必数据的长度,如:app.items.length=0;
vue.js解决办法:用一个空数组替换items.
vue.js还为数组添加了$remove()方法(),内部自动调用splice()
app.items.$remove(item);
v-for遍历对象:
<li v-for='(value,key,index) in user'>{{key}}={{value}}</li>
值域v-for: 接收一个整数,此时它将重复模版数次。
<li v-for="n in 10">{{n}}</li> //渲染10个li,n从1到10.(老版本n从0到9)
显示过滤/排序结果:
想要显示过滤/排序过的数组,同时不实际修改或重置原始数据,有两个方法:
1、创建一个计算属性,返回过滤/排序过的数组。
2、使用内置的过滤器filterBy和orderBy.
计算属性有更好的控制力,也更灵活,因为它是全功能javascript.但是通常过滤器更方便。
过滤器:https://cn.vuejs.org/v2/guide/filters.html
{{ message | capitalize }}
你可以在一个组件的选项中定义本地的过滤器:
filters: {
capitalize: function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
或者在创建 Vue 实例之前全局定义过滤器:
Vue.filter('capitalize', function (value) {
if (!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
})
new Vue({
// ...
})
lls:文档中说:orderBy过滤器老版本已经不再使用了,直接使用计算属性。
<p v-for="user in orderedUsers">{{ user.name }}</p>
computed: {
orderedUsers: function () {
return _.orderBy(this.users, 'name');//lls : this就是Vue()构造函数中传入的那个data
}
}
// _.orderBy()使用的是Lodash类库。
lls:filterBy也使用计算属性
替换老版本的 filterBy 过滤器:(摘自官方文档)
<p v-for="user in filteredUsers">{{ user.name }}</p>
computed: {
filteredUsers: function () {
var self = this;//lls : this就是Vue()构造函数中传入的那个data
return self.users.filter(function (user) {
return user.name.indexOf(self.searchQuery) !== -1
})
}
}