vue.js是一种最近很流行的轻量级MVVM框架。
那什么是MVVM架构呢?
MVVM主要分三部分:View,ViewModel,Model。
它们之间的关系是两两之间信息双向传递,当View中有信息改变时自动反映在ViewModel,反之也是如此。
这样的设计给我们后期修改以及维护带来了很大的便利。
前端技术近几年的发展可以说是很迅速了,同时对于前端的技术也是越来越高,在做复杂的项目时,我们需要有清晰合理的架构,使项目更易开发和维护。Vue.js的功能完全可以满足我们的需求,帮助我们快速开发原型,也可以混合别的库做更多的事情,比如混合jquery,jquery的DOM操作十分强大。但是Vue.js不能与Angular.js混合使用,会出现冲突!
接下来我们就开始学习vue.js的开发
我们知道实现Vue框架的核心是vue.js.它可以通过构造函数Vue来创建一个实例
var app=new Vue({
});
在实例化Vue时,我们需要传入一个JSON对象,它可以包括数据,模板,方法,回调函数等选项。
下面让我们来写第一个Vue的小例子吧
html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="first">
{{message}} //表达式
<p>{{student.name}}</p>
</div>
<script src="../vue.js"></script>
<script src="main.js"></script>
</body>
</html>
js代码:
var first=new Vue({
el:"#first", //获取到html中的div,进行绑定
data:{ //json,存放数据
message:"HelloWord",
student:{
name:"小米",
age:"18"
}
}
});
el属性与data属性是常用的,html中想要获取的数据都是从data中进行读取。
Vue的实例属性
Vue实例会代理其data对象里所有的属性,如果实例创建之后再添加或者修改属性,视图不会更新。有的人觉得这句话是有问题的,因为如下代码:
<p>{{username}}</p>
<p>{{sex}}</p>
var first = new Vue({
el: "#first",
data: {
username: "xiaoming"
}
});
此时视图显示的是xiaoming
当对代码进行修改
var first = new Vue({
el: "#first",
data: {
username: "xiaoming"
}
});
app.username = "TOM";
这时会发现视图显示的就变成了TOM!
可是我们上面不是刚刚说明了vue实例创建完成后再添加或者修改属性,视图不会发生改变吗?
重点就在于vue实例要创建完成!!!
vue对象的创建是十分复杂的,耗费时间,客户端不会等待vue对象以及里面的内容全部创建完再执行下面的代码,所以代码的执行是异步的,像ajax,浏览器在执行ajax时并不会停下来等待ajax的返回值,而是当响应返回回来时再执行回调函数。所以此时Vue对象还没有完全创建成功,还是可以修改里面的内容。
那我们怎么检测当Vue创建成功时是否能修改里面的属性呢?
Vue有一个回调函数ready,当对象创建完成后会执行这个回调函数,所以我们只需要测试以下代码:
var first = new Vue({
el: "#first",
data: {
username: "xiaoming"
},
ready: function () {
this.username = "mike"
}
});
此时我们会发现,视图上的文字并没有改变,这就证实了实例创建之后再添加或者修改属性,视图的确不会更新。
除了data属性,Vue实例暴露了一些有用的实例属性和方法,这些属性和方法都有前缀$
var first = new Vue({
el: "#first",
data: {
username: "xiaoming"
}
});
console.log(first.username);
console.log(first.$data.username);//$data属性是所有绑定数据的代理
console.log(first.$el==document.getElementById("first"));
计算属性
视图层的表达式是非常便利的输出手段,但是它们实际上只用于简单的运 算。在模板中放入太多的逻辑会让表达式过重且难以维护。例如:
<div id="exp">
{{ message.split('').reverse().join('') }}
</div>
在这种情况下,模板就不再清晰和简单了,所以对于任何复杂逻辑,我们应当使用计算属性。
计算属性就是在模板中调用函数输出结果
例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>工资:</p>
<input type="text" v-model="salary" placeholder="输入工资...">
//v-model是指令这里是获取文本框的输入内容与模型层建立连接
<p v-text="Tax"></p>
//v-text指令与{{Tax}}表达式结果相同
</div>
<script src="../vue.js"></script>
<script src="main.js"></script>
</body>
</html>
var app=new Vue({
el:"#app",
data:{
salary:0
},
computed:{
Tax:function(){ //定义一个计算函数
var base=3500;
var temp=this.salary-base;
var tax=0;
if(temp<=0){
tax=0;
}
else if(temp>0&&temp<=1500){
tax=temp*0.03-0;
}
else if(temp>1500&&temp<=4500){
tax=temp*0.10-105;
}
else if(temp>4500&&temp<=9000){
tax=temp*0.20-555;
}
else if(temp>9000&&temp<=35000){
tax=temp*0.25-1005;
}
else if(temp>35000&&temp<=55000){
tax=temp*0.30-2755;
}
else if(temp>55000&&temp<=80000){
tax=temp*0.35-5505;
}
else{
tax=temp*0.45-13505;
}
return Math.ceil(tax*100)/100; //返回计算结果
}
}
});
以上是一个计算个人所得税的小例子。
<p>{{Tax}}</p>
表达式的缺点,会在网页短时间显示表达式文字内容本身,当vue对象创建完成后才会显示计算属性的结果,而v-text="Tax"则没有这个缺点。
vue的方法调用
上面计算个人所得税的小例子用方法调用也可以实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p>工资:</p>
<input type="text" v-model="salary" placeholder="输入工资...">
<p>{{Tax()}}</p>
<p v-text="Tax()"></p>
</div>
<script src="../vue.js"></script>
<script src="main.js"></script>
</body>
</html>
var app=new Vue({
el:"#app",
data:{
salary:0
},
methods:{
Tax:function(){
var base=3500;
var temp=this.salary-base;
var tax=0;
if(temp<=0){
tax=0;
}
else if(temp>0&&temp<=1500){
tax=temp*0.03-0;
}
else if(temp>1500&&temp<=4500){
tax=temp*0.10-105;
}
else if(temp>4500&&temp<=9000){
tax=temp*0.20-555;
}
else if(temp>9000&&temp<=35000){
tax=temp*0.25-1005;
}
else if(temp>35000&&temp<=55000){
tax=temp*0.30-2755;
}
else if(temp>55000&&temp<=80000){
tax=temp*0.35-5505;
}
else{
tax=temp*0.45-13505;
}
return Math.ceil(tax*100)/100;
}
}
});
计算属性和方法调用的区别
虽然二者最后的结果相同,但是不同的是,计算属性是基于缓存的,计算属性只有在它的相关依赖发生改变时,才会重新求值;函数恰好相反,它是没有缓存的。
我们通过一个例子能更深刻的了解
计算属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<p><input type="button" value="添加" @click="add"></p>
<p v-for="one in list">{{now}}</p>
</div>
<script src="../vue.js"></script>
<script src="main.js"></script>
</body>
</html>
var app=new Vue({
el:"#app",
data:{
list:[]
},
methods:{
add:function(){
this.list.push("ok");
}
},
computed:{
now:function(){
return new Date().toLocaleString();
}
}
});
//输出一样的结果因为输出的都是缓存的数据,所以时间是不变的
方法调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="main.css">
</head>
<body>
<div id="app">
<p><input type="button" value="添加" @click="add"></p>
<p v-for="one in list">{{now()}}</p>
</div>
<script src="../vue.js"></script>
<script src="main2.js"></script>
</body>
</html>
var app=new Vue({
el:"#app",
data:{
list:[]
},
methods:{
add:function(){
this.list.push("ok");
},
now:function(){
return new Date().toLocaleString();
}
}
});
使用计算属性当点击按钮时输出的时间是不变的,但是方法调用的时间是在不断的更新的,这就说明了计算属性输出的值是缓存的,而函数相反,没有缓存值。