本篇文章的目的是快速的入门 Vue.js,力求能够通过本篇文章了解 Vue.js 的基本用法,但是并不会覆盖 Vue.js 的方方面面,在读完本篇文章之后,便可阅读 Vue.js 的官方教程,进一步的了解 Vue 的进阶内容。
Vue 带来的开发思维的改变
假设有这么一个要求,要我们根据一个数组渲染出一个列表,对于下面的数组
const courses = ['语文', '数学', '英语'];
要求渲染出下面的 HTML 结构
<ul>
<li>语文</li>
<li>数学</li>
<li>英语</li>
</ul>
所以我们会写出这样的代码
const courses = ['语文', '数学', '英语'];
const ulEle = document.getElementsByTagName("ul")[0];
courses.forEach(item => {
const liEle = document.createElement('li');
liEle.innerText = item;
ulEle.append(liEle);
})
如果数组的内容发生改变,我们还需要手动更新上述的 HTML 结构。所以传统的开发方式为更新数据,根据数据操作 DOM 树。
那么使用 Vue 会有什么不同,来看一个使用 Vue 的方式来实现上述的功能
<div id="app">
<ul>
<li v-for="course in courses" :key="course">{
{course}}</li>
</ul>
</div>
<script src="vue.js"></script>
<script>
new Vue({
el: '#app',
data() {
return {
courses: ['语文', '数学', '英语']
}
},
})
</script>
上面的程序可能看不懂,毕竟还没有开始学,所以不必担心。从代码量上看,二者似乎相差不大,可能还有点多,但是当我们更新数组时,我们不必操作 DOM 树来更新页面了,当数据发生变化时,Vue 自动地帮我们更新页面,这种模式我们称为 MVVM,其中的 V 表示 View,而 M 表示 Model,数据与视图进行了绑定,当数据发生变化时,视图也会相应的更新,如下图
![](https://i-blog.csdnimg.cn/blog_migrate/3673fe71dc11662b6861f0b21f2ea2f1.png)
所以 Vue 给我们带来开发思维上的改变就是,我们只需要操作数据即可,而更新页面的工作不需要我们来做了。
Hello World
安装 Vue
安装 Vue 当然是选择官网了,当然我们也可以选择通过 CDN 引入文件,例如
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
Hello World
下面就是经典的 Hello World 程序,新建一个 HTML 文件,内容如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
{
{message}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
message: 'Hello World!'
}
}
})
</script>
</body>
</html>
页面上显示的内容如下:
![](https://i-blog.csdnimg.cn/blog_migrate/5e7d48293c5b7fd411086c2939790ee6.png)
发生了什么
我们先简单的捋一捋发生了什么,一切先从下面的代码说起
const vm = new Vue({
el: '#app',
data() {
return {
message: 'Hello World!'
}
}
})
上面我们创建了一个 Vue 的实例 new Vue()
,并且向其中传入一个对象,包括这么两个属性:
- el:绑定的 DOM 元素
- data:返回一个对象的函数,返回对象中的数据与视图进行了绑定,当修改数据时,相应的视图也会发生更新
当我们创建一个 Vue 实例时,首先它会根据 el 属性指定的选择器找到相应的 DOM 元素,我们称这个 DOM 结果为模板(template),例如上例根据 #app
选择器我们找到
<div id="app">
{
{message}}
</div>
{% raw %}
接着便会解析该模板,例如上面将 {
{message}}
替换为了 data
中定义的数据 message
的对应的值,即 Hello World!
,解析完毕后便会渲染页面,我们便在页面上看到了 Hello World!
。
因为 Vue
对 data
属性中定义的数据进行了拦截,一旦我们改变对象属性的值,Vue 便会对用到该属性的模板进行解析、渲染。
拦截数据是通过
Object.definePropety()
来做到的,可以通过 MDN 来了解该方法的使用。
Vue实例
上面我们使用变量 vm
接收了 new Vue()
返回的 Vue
实例,现在我们看看里面有什么。
$el
模板经过 Vue
解析、渲染以后,然后根据该模板生成一个 DOM 元素挂载在页面中,而这个 DOM 元素我们可以通过 vm.$el
进行访问得到
![](https://i-blog.csdnimg.cn/blog_migrate/4e962d450eee3cc82bdf8387403bf75d.png)
$data
通过 vm.$data
可以得到 data
属性返回的对象
![](https://i-blog.csdnimg.cn/blog_migrate/dac6260faa565d189acaebc5445df143.png)
我们可以通过 vm.$data
来修改数据
![](https://i-blog.csdnimg.cn/blog_migrate/b4925794f36ee666851024888c1d8886.png)
上面我们修改数据 message
为 Hello Vue
,页面便发生了变化,进一步证实了数据与视图的绑定。
为了方便通过 vm
操作数据,所有的数据都被挂载到了 vm
上,即我们可以直接通过 vm
访问以及修改数据,而不必通过 vm.$data
![](https://i-blog.csdnimg.cn/blog_migrate/cc2831e8422e4ccca5a7adda24b50335.png)
上面我们通过 vm.message
直接修改了数据,页面也立即发生了变化。
无论我们是通过
vm.message
还是vm.$data.message
修改数据,它们之间是互相影响的。即当我们通过vm.xxx
修改数据,那么vm.$data.xxx
的值也会发生改变,反之亦然。
模板语法
本小节主要讲如何在模板中引用在 data
属性中定义的数据。
插值
{% raw %}
在模板中通过 {
{}}
插值语法便可引用在 data
中定义的数据,正如上例中的 {
{message}}
,除此以外,{
{}}
内部可以是任何的 JavaScript 表达式,如
{
{
1 + 2}}
{
{
message === 'xxx' ? 'foo' : 'bar'}}
{
{
message.split('').reverse().join('')}}
{
{}}
中的内容会被解析,然后被替换为相应的内容。
{% endraw %}
指令
v-bind
如果我们想让模板中的属性与数据进行动态绑定,我们便需要借助于 v-bind
属性,有下面的模板以及数据
<div id="app">
<p title="message">Hello World</p>
</div>
const vm = new Vue({
el: '#app',
data() {
return {
message: 'Hello World!'
}
}
})
当我们将鼠标放置在 p
标签上时,显示的 title
是 message
,而不是数据 Hello World!
,说明 title
属性并没有与 message
进行绑定,因为图比较难截,所以自己试验一下。不过从渲染后的 DOM 元素可以证明这一点
![](https://i-blog.csdnimg.cn/blog_migrate/9251e4a01c8891563adec5a7a43422eb.png)
我们希望 p
标签的 title
属性与 data
中定义的 massage
进行绑定,我们只需要在属性 title
签名加上 v-bind:
即可
<div id="app">
<p v-bind:title="message">Hello World</p>
</div>
这时将鼠标放在 p
标签,这时显示的便是 Hello World!
,从渲染后的 DOM 元素可以证明这一点
![](https://i-blog.csdnimg.cn/blog_migrate/f7e584810d063cc18a0fa1a3ca3ba7bd.png)
并且这时我们对数据进行更改,相应的数据也会发生变化
![](https://i-blog.csdnimg.cn/blog_migrate/084e1389dba69ed3706c409d6f00f217.png)
因为 v-bind:
比较常用,所以它有一个缩写 :
,上述模板可以改为
<div id="app">
<p :title="message">Hello World</p>
</div>
class
属性与 style
属性也可以使用 v-bind
绑定属性,不过类与样式实在太过特殊,所以 Vue 对其有做一些特殊的扩展,可以参见官网。
v-on
指令 v-on
可以绑定一个事件
<div id="app">
<p v-on:click="clear">{
{message}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
message: 'Hello World!'
}
}
})
</script>
在上面我们为 p
标签添加了一个点击事件 v-on:click="clear"
,当我们点击 p
标签时会触发一个叫 clear
的方法,该方法需要在 methods
选项中进行定义,如下
const vm = new Vue({
el: '#app',
data() {
return {
message: 'Hello World!'
}
},
methods: {
clear() {
this.message = ""
}
}
})
clear
的方法会将 message
数据设置为空字符串
![](https://i-blog.csdnimg.cn/blog_migrate/e1520bc5e3ec36653b884bd5549884aa.gif)
当我们点击 p
标签时,message
数据变为空字符串,相应的页面也会发生改变。
绑定事件也是一个很常见的操作,所以也有缩写,上面的 v-on:
可以替换为 @
<div id="app">
<p @click="clear">{
{message}}</p>
</div>
除了使用 v-on
指令绑定 methods
中的事件,除此之外,我们也可以内联操作数据
<div id="app">
<p>
<!-- 直接内联修改数据 -->
<button @click="message = 'Hello'">Hello</button>
<button @click="message = 'Hi'">Hi</button>
</p>
<p>{
{message}}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const vm = new Vue({
el: "#app",
data() {
return {
message: "Hello Vue!"
}
},
})
</script>
![3](https://i-blog.csdnimg.cn/blog_migrate/a1c27b48a76c3419a2fef78703a5ef70.gif)
在内联的写法中,我们可以通过
$event
访问到event
事件对象。
在事件处理程序中调用 event.preventDefault()
或 event.stopPropagation()
是非常常见的操作,Vue 为 v-on
提供了事件修饰符
.stop
:阻止事件继续传播.prevent
:阻止默认行为.capture
:使用捕获模式.once
:事件只执行一次
在监听键盘事件时,我们一般需要检测按下了哪个键,Vue 可以在监听事件时添加按键修饰符
<input @keyup.enter="submit">
处理函数只会在 event.key
等于 enter
被调用,Vue 提供如下按键修饰符
.enter
.tab
.delete
.esc
.space
.up
.down
.left
.right
在监听鼠标点击事件时,有时也会判断按下了鼠标的哪个按钮,Vue 也提供了相应的鼠标修饰符
.left
.right
.middle
在日常的使用,我们经常使用快捷键进行快捷操作,设置快捷键一般需要系统按键符配合,如 ctrl
,因此 Vue
也为我们提供了系统按键符,包括
.ctrl
.alt
.shift
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
.exact
修饰符允许你控制由精确的系统修饰符组合触发的事件
<!-- 即使 Alt 或 Shift 被一同按下时也会触发 -->
<button v-on:click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button v-on:click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button v-on:click.exact="onClick">A</button>
v-if、v-show
v-if
和 v-show
指令可以控制元素是否渲染
<div id="app">
<p v-if="show">{
{message}}</p>
<button @click="toggle">toggle</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">