什么是Vue.js?
Vue.js,读音 /vjuː/,和view发音几乎一样,可见重心是在视图(view)层上的。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。
与react.js做比较
react.js相比vue.js拥有更好的他们的生态系统和丰富的自定义渲染器。
在渲染用户界面的时候,DOM 的操作成本是最高的,相同的是两者都会尽量减少 DOM 操作。而vue还会尽量减少除 DOM 操作以外的其他操作。所以在性能上vue更胜一筹。
在react中所有的html/css都是写在js里的,会导致不少问题。而vue是创建一个模版,把他们写在模版中,最终渲染出来。
与Angular做比较
Angular 是 Vue 早期开发的灵感来源,所以在一定程度上有些类似,并且vue对其进行了一定优化,在复杂性方面vue的api相对简单太多,可以很快上手。在性能方面vue也拥有一定的优势,然而Angular虽然笨重但是功能强大。
来自Vue的Hello world!
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
{{show}}
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
show:'"Hello world!" from Vue.js'
}
})
</script>
</html>
简单的实现了一个字符串的渲染,看起来很简单,其实vue在背后做了很多操作,现在数据和 DOM 已经被绑定在一起了,我们可以通过app.show来修改,你可以看到页面相应的进行了更新。
构造器
为什么new了一个Vue,其实每一个Vue.js应用都是通过构造函数Vue创建一个Vue的根实例也就是这里说的构造器。
在实例化Vue时,需要传入一个选项对象,它可以包含数据、模板、挂载元素、方法、生命周期钩子等选项。全部的选项可以在 API 文档中查看。
还可以通过extend自定义扩展构造器(后面会具体说一下这里):
var MyComponent = Vue.extend({
// 扩展选项
})
// 所有的 `MyComponent` 实例都将以预定义的扩展选项被创建
var myComponentInstance = new MyComponent()
一些v-指令
v-bind
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app-2">
<span v-bind:title="show">
{{message}}
</span>
</div>
</body>
<script>
var app = new Vue({
el: '#app-2',
data: {
show:'You loaded this page on ' + new Date(),
message: 'Hover your mouse over me for a few seconds to see my dynamically bound title!'
}
})
</script>
</html>
这个例子,我们可以看到除了绑定插入的文本内容,我们还可以采用这样的方式绑定 DOM 元素的属性。
v-bind被称为指令,在vue中v-开头就代表这是vue中提供的特殊属性。
同样app.show同样可以修改,页面也会进行相应更新。
v-if
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<span v-bind:title="show" v-if="val">
{{message}}
</span>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
val: false,
show:'You loaded this page on ' + new Date(),
message: 'Hover your mouse over me for a few seconds to see my dynamically bound title!'
}
})
</script>
</html>
v-if指令可以进行判断,绑定的值为true进行显示,绑定的值为false就不显示。
同样也可以在控制台修改app.val=true/false
这个指令最大的作用就是在用vue增删元素的时候,可以起到一次过滤效果。
v-for
v-for 指令可以绑定数据到模版来渲染一个列表
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<li v-for="item in todos">
{{ item.text }}
</li>
</ul>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
todos: [
{ text: '第一项' },
{ text: '第二项' },
{ text: '第三项' },
{ text: '第四项' },
{ text: '第五项' }
]
}
})
</script>
</html>
通过v-for循环一个列表出来,与数据进行绑定,这样可以大大减少html页面的代码量,转换成遍历模版来渲染出页面。同样可以对todo数组进行操作。
v-on
为了让用户和我们的应用互动起来,我们可以用v-on指令绑定一个监听事件用于调用我们 Vue 实例中定义的方法。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<p>{{message}}</p>
<button v-on:click="reverseMessage">操作数据</button>
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message:'Hello Vue.js!'
},
methods: {
reverseMessage: function(){
this.message = this.message.split('')
}
}
})
</script>
</html>
绑定了一个reverseMessage函数到button上。在这个过程中我们在没有接触 DOM 的情况下更新了页面的状态,所有的DOM操作都由Vue来处理,你写的代码只需要关注基本逻辑。
v-model
vue实现双向数据绑定,就可以从这个地方体现出来了。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<p>{{message}}</p>
<input type="text" v-model="message">
</div>
</body>
<script>
var app = new Vue({
el: '#app',
data: {
message:'Hello Vue.js!'
}
})
</script>
</html>
可以更改input里的值来逆向的更改message的值,从而映射到{{message}}中去。
构建组建
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Vue起步</title>
<script src="vue.js"></script>
</head>
<body>
<div id="app">
<ul>
<todo-item v-for="todo in todos" v-bind:item="todo"></todo-item>
</ul>
</div>
</body>
<script>
Vue.component('todo-item',{
props:['item'],
template: '<li>{{ item.text }}</li>'
})
var app = new Vue({
el: '#app',
data: {
todos: [
{ text: '第一项' },
{ text: '第二项' },
{ text: '第三项' },
{ text: '第四项' },
{ text: '第五项' }
]
}
})
</script>
</html>
通过我们构建的组件现在可以在不影响到父应用的基础上,进一步为我们的todo做更多复杂的模板和逻辑。
组件系统是 Vue.js 另一个重要概念,因为它提供了一种抽象,让我们可以用独立可复用的小组件来构建大型应用。如果我们考虑到这点,几乎任意类型的应用的界面都可以抽象为一个组件树:其中v-bind把数据传递出去,在component中用props接收bind传递过来的经过循环以后的数组。
当我们把一个大型项目分割成数个小的组件后我们的html代码应该是下面这个样子的,这样可以让我们整个开发过程更可控,也完成了解耦工作。
<div id="app">
<app-nav></app-nav>
<app-view>
<app-sidebar></app-sidebar>
<app-content></app-content>
</app-view>
</div>
属性与方法
在前面有提到说我们在控制台中可以通过app.show来修改data里面的方法show,这是为什么呢?原因是每个 Vue 实例都会代理其 data 对象里所有的属性。
var data = { a: 1 }
var vm = new Vue({
data: data
})
vm.a === data.a // -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3
ps:注意只有这些被代理的属性是响应的。如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。
除了 data 属性,Vue实例暴露了一些有用的实例属性与方法。这些属性与方法都有前缀 $,以便与代理的 data 属性区分。具体请查阅API文档中的实例属性一节。
MVC & MVVM模式
MVC = Module View Controller
MVC是一种在后端开发中广泛采用的架构模式,几乎所有的知名后端框架都是传统 MVC 的实现,由于其中的 一些小差异,也可以被叫做 MV*
MVC模式的意思是,软件可以分成三个部分。
- 视图(View):用户界面。
- 控制器(Controller):业务逻辑
- 模型(Model):数据保存
各部分之间的通信方式如下
- View 传送指令到 Controller
- Controller 完成业务逻辑后,要求 Model 改变状态
- Model 将新的数据发送到 View,用户得到反馈
所有通信都是单向的。
互动模式
接受用户指令时,MVC 可以分成两种方式。一种是通过 View 接受指令,传递给 Controller。
test
另一种是直接通过controller接受指令。
MVVM = Module View ViewModule
它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Angular 和 Ember 都采用这种模式。
vue核心关注的就是MVVM中的ViewModel