初识Vue
什么是Vue
以下引自Vue官方文档
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。
与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。
Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。
另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。
Vue.js是当下很火的一个 JavaScript MVVM库,它是以数据驱动和组件化的思想构建的。
相比于Angular.js,Vue.js提供了**更加简洁、更易于理解的API,**使得我们能够快速地上手并使用Vue.js。
如果你之前已经习惯了用 jQuery操作 DOM,学习 Vue.js时请先抛开手动操作 DOM的思维,因为 Vue.js是数据驱动的,你无需手动操作 DOM。它通过一些特殊的 HTML语法,将 DOM和数据绑定起来。一旦你创建了绑定,DOM将和数据保持同步,每当变更了数据,DOM也会相应地更新。
当然了,在使用 Vue.js时,你也可以结合其他库一起使用,比如 jQuery。
什么是MVVM
MVVM(Model–View–ViewModel)是一种软件架构模式。
2005年由微软的WPF和Silverlight的架构师 John Gossman 提出,是MVP模式与WPF结合发展演变过来的一种架构模式。MVVM实质上还是MVC架构范围,是一个精心优化的MVC架构,所以与MVC架构是兼容的。
关于MVC,不懂的朋友可以看这里
为什么需要MVVM架构模式
随着H5 的不断发展,人们更希望使用 H5开发的应用能和Native媲美,或者接近于原生 App的体验效果,于是前端应用的复杂程度已不同往日,今非昔比。这时前端开发就暴露出了三个痛点问题:
-
开发者在代码中大量调用相同的 DOM API, 处理繁琐 ,操作冗余,使得代码难以维护。
-
大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
-
当 Model 频繁发生变化,开发者需要主动更新到 View ,当用户的操作导致 View 发生变化,开发者同样需要将变化的数据同步到Model 中,这样的工作不仅繁琐,而且很难维护复杂多变的数据状态。
其实,早期 jQuery 的出现就是为了前端能更简洁的操作DOM 而设计的,但它只解决了第一个问题,另外两个问题始终伴随着前端一直存在。
MVVM首先将 View层和 Controller层进行了合并,统称为 View层,因为 View层和 Controller层往往是一起出现的。然后引入了一个新的模块:ViewModel层,ViewModel层承载的内容就是之前在 Controller层中视图展现逻辑。MVVM的图示如下:
什么是视图展现逻辑呢?
在一款应用中,数据的来源可能是服务端返回、数据库获取和用户输入,然后存储在Model中。
但是这样的数据是一种 “未经格式化的” 原始数据,还不能直接显示到屏幕上。
比如Model中可能有姓、名、昵称等属性,在某些界面中需要显示成 “姓名” 的样式,某些界面中显示成 “名姓” 的样式,某些界面中显示 “昵称” 的样式。
视图展现逻辑就是把这些原始数据经过业务需求处理成展现到屏幕上的数据。
可以把一个应用看成是播出一个新闻节目,Model层就是一大堆繁杂的稿件,View层就是主持人实际播报的新闻,而ViewModel层就是幕后的编辑处理团队,负责从凌乱的稿件中抽出需要的信息,整理成播报时用的稿件。这样主持人拿着整理好的稿件,就能轻松的播报新闻了。
以上部分引自该博客
从上述介绍中,不难看出该架构模式的核心在 ViewModel
Vue和MVVM
MVVM的核心之处在于数据和模型的双向绑定
该模式通过 ViewModel实现数据和视图快速同步的目的。
在MVVM中我们常说的 模型(也就是Model)通常指的是 JavaScript,而视图(View)则是DOM。视图模型(ViewModel)则是连接二者的一个中间件,Vue.js就是扮演的这样一个角色(非唯一)。
MVVM架构模式中,是不允许 数据和 视图直接通信的,只能通过 ViewMoedel来通信。
ViewModel中定义了一个 Observer 观察者,这样它就能够观察到数据和视图的变化,并使二者的内容能够同步。
那 Vue.js的作用也就是监听 DOM及让它与模型中的数据保持同步。
Vue实现 HelloWorld
获取Vue
和多数 JavaScript库一样,我们可以从官网直接下载其文件并添加到项目中。也可以使用在线的 CDN
当然这些东西也比较简单,对获取 Vue有所疑惑 花三分钟看看Vue官网应该能有所帮助。
CDN
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
引入 Vue.js后,我们要做的事情无非两件,创建视图和模型、使用Vue将二者绑定。
<body>
<!--创建视图-->
<div id="view">
<!--从 Vue对象中取得模型中的数据-->
{{message}}
</div>
<!--引入 Vue.js-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
// 创建一个 Vue对象,使其连接视图和模型
var vm = new Vue({
// 选中DOM元素(绑定 View)
el: "#view",
// 创建模型
data: {
//添加数据
message: "Hello Vue!"
}
});
</script>
</body>
在这个示例中,选项对象的el属性指向View,el: "#view"
表示该 Vue实例将挂载到<div id="view">...</div>
这个元素。
data属性指向Model,我们可以在 data中以键值对的形式添加数据。 Vue.js有多种数据绑定的语法,最基础的形式是文本插值,使用一对大括号语法。
在运行时{{ message }}
会被数据对象的 message属性替换。
网页中的效果
前面也说过了,Vue对象起的是一个中间件的效果,负责将 DOM元素和数据进行绑定。
那我们应该可以在控制台中使用 Vue对象来操作模型中的数据,使视图层发生变化。
确实能够通过操作模型中的数据,来使视图层展示的数据进行刷新(在不刷新网页的情况下)。
除了在控制台中操作 Vue对象中的数据,我们还可以使用v-model
指令在表单元素上创建双向数据绑定。
<div id="view">
<!--从Vue对象中取得数据-->
<h1>{{message}}</h1>
<!--使用 v-model指令将 message绑定到文本框-->
<input type="text" v-model="message"/>
</div>
可以预见的,当更改文本框的值时,<h1>{{ message }}</h1>
中的内容也会被更新。
这就是所谓的双向绑定
Vue常用指令
在上文中我们有使用一个 v-model
指令,在Vue中指令都以 v-为前缀 以表示他们是Vue提供的特殊特性。
它们会在渲染的 DOM上应用特殊的响应式行为,我们可以将指令看作特殊的HTML特性(attribute)。
Vue.js提供了一些常用的内置指令,我们一个一个介绍
v-bind
v-bind指令可以在其名称后面带一个参数,中间放一个冒号隔开。
这个参数通常是HTML元素的特性(attribute),例如:v-bind:title
<body>
<div id="view">
<!--使用 v-bind:title指令,将元素的title特性 与Vue实例中的 message属性绑定-->
<h1 v-bind:title="message">鼠标悬停在此可以查看当前日期</h1>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#view",
data: {
// 获取当前时间
message: new Date()
}
});
</script>
</body>
如上,我们将 h1标签中的 title特性与 Vue实例中的 message进行了绑定。
测试:
v-if、v-esle
这两个指令没什么好讲,无非是做一些判断。也不是什么新东西,仅做示范
<body>
<div id="view">
<!--
使用 v-if指令来进行布尔值的判断
只写ok意为:如果 ok的布尔值为 true,输出当前p标签中的内容
------------
在下方追加一个 v-else,意为如果 ok的布尔值不为 true
输出该 p标签中的内容。
-->
<p v-if="ok">当前布尔值为:true</p>
<p v-else>当前布尔值为:false</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#view",
data:{
// 将 ok属性的值设置为 true
ok: true
}
});
</script>
</body>
测试:
可以看到,如果我们按上面这种写法,不为 v-if指令中的属性 指定一个确定的布尔值,当该属性的值不为布尔值时。仍然会输出 v-if指令 p标签中的内容,而不是 v-else指令 p标签中的内容。
我们尝试为 v-if指令中的属性 指定一个确定的布尔值
当然了,为了细化 我们也可以使用 v-else-if
,让它再多一层判断。
<p v-if="ok===true">当前布尔值为:true</p>
<p v-else-if="ok===false">当前布尔值为:false</p>
<p v-else>当前布尔值为:其他</p>
除了布尔值,指定一些固定的值。感兴趣可以自己测试
v-show
v-show
也是条件渲染指令,和v-if指令不同的是,使用v-show
指令的元素始终会被渲染到HTML,它只是简单地为元素设置 CSS property display
。
<body>
<div id="view">
<!--
使用v-show来进行判断,如果 age满足条件 则无事发生
如果 age不满足条件,该元素会被设置了style="display:none"
同 v-if,我们也可以将下列 v-show缩写为: v-show="age>=20",也就是省略 ===true 的写法
但 v-show后面不能跟 v-else
-->
<p v-show="age>=20===true">age:{{age}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#view",
data: {
// 定义一个age属性 值为20
age: 20
}
});
</script>
</body>
测试:
v-if与 v-show
v-if
是 “真正” 的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if
也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。相比之下,
v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。一般来说,
v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show
较好;如果在运行时条件很少改变,则使用v-if
较好。
v-for
我们可以用 v-for
指令基于一个数组来渲染一个列表。
v-for
指令需要使用 item in items
形式的特殊语法,其中 items
是源数据数组,而 item
则是被迭代的数组元素的别名。
<body>
<div id="view">
<!--使用 v-for指令,遍历数组-->
<p v-for="item in person">
<!--拿到数组属性为 li的对象-->
{{item.li}}
</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#view",
data: {
// 定义一个数组,数组中存在两组对象,属性名分别为 ‘li’和 ‘wang’
person:[
{"li":"李四"},
{"li":"李茗"},
{"li":"李曦"},
{"wang":"王二"},
{"wang":"王沁"},
{"wang":"王云"}
]
}
});
</script>
</body>
v-for
还支持一个可选的第二个参数,即当前项的索引。
<p v-for="(item,index) in person">
{{item}}-->{{index}}
</p>
感兴趣可以自己写着测试一下
v-on
v-on
指令用于监听DOM事件,它的用语法和v-bind是类似的
我们直接看示例
<body>
<div id="view">
<p>{{x}}s</p>
<!--为该按钮绑定一个点击事件,点击后 x = x + 1-->
<button v-on:click="x+=1">点我 +1s</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var vm = new Vue({
el: "#view",
data: {
// 定义一个 x
x: 0
}
});
</script>
</body>
测试:
子弹滞销帮帮我们
放松一下眼睛
夹带私货(不是