Vue.js 基础语法详解:4 万字带你领略渐进式 JavaScript 框架的魅力
Vue.js 作为一款渐进式 JavaScript 框架,以其易用性、灵活性以及高效性,在前端开发领域迅速崛起,成为了构建现代 Web 应用的热门选择。其简洁的语法和强大的功能,让开发者能够轻松地构建出交互丰富、性能优异的 Web 应用。
本篇文章将化身一位经验丰富的导师,带领大家深入探索 Vue.js 的基础语法,从最简单的入门知识到进阶技巧,逐一讲解,并结合大量实例,将理论知识与实践应用紧密结合,助你构建稳固的 Vue.js 知识体系,并将其应用于实际项目开发中。
第一部分:Vue.js 入门 - 踏入新世界,开启旅程
第一章:初识 Vue.js - 邂逅前端开发的新宠
1.1 什么是 Vue.js?
Vue.js 是一款用于构建用户界面的渐进式 JavaScript 框架。它易学易用,性能出色,并且拥有活跃的社区支持,成为了众多开发者构建 Web 应用的首选框架。
1.2 Vue.js 的特点
- 渐进式: Vue.js 可以逐步引入到项目中,从小巧的组件开始,逐步扩展到复杂的单页应用。
- 响应式数据绑定: 数据模型的变化会自动更新视图,无需手动操作 DOM。
- 组件化开发: 将用户界面拆分成独立、可复用的组件,提高代码复用性和可维护性。
- 虚拟 DOM: 通过虚拟 DOM 技术,优化 DOM 操作,提升应用性能。
- 轻量级: Vue.js 核心库体积小巧,gzip 压缩后仅有 20KB 左右。
- 活跃的社区: Vue.js 拥有庞大而活跃的社区,为开发者提供丰富的学习资源和技术支持。
1.3 Vue.js 的应用场景
- 单页应用 (SPA)
- 交互式 Web 应用
- 移动端混合应用
- 桌面端应用
第二章:创建 Vue 实例 - 构建基础,开启旅程
2.1 使用 CDN 引入 Vue.js
<!DOCTYPE html>
<html>
<head>
<title>Vue.js 入门</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
{{ message }}
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
</script>
</body>
</html>
代码解析:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
: 使用 CDN 引入 Vue.js 库。new Vue({ ... })
: 创建一个 Vue 实例。el: '#app'
: 指定 Vue 实例管理的 DOM 元素,这里为id
为app
的div
元素。data: { message: 'Hello Vue!' }
: 定义数据模型,message
属性的值为'Hello Vue!'
。{{ message }}
: 使用双大括号语法将数据模型中的message
属性值渲染到页面上。
2.2 使用 npm 安装 Vue.js
npm install vue
import Vue from 'vue';
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
代码解析:
npm install vue
: 使用 npm 安装 Vue.js 库。import Vue from 'vue';
: 导入 Vue.js 库。- 剩下的代码与使用 CDN 引入 Vue.js 的代码相同。
第三章:数据绑定 - 数据驱动视图,核心机制
3.1 文本插值
使用双大括号 {{ }}
将数据模型中的值插入到 HTML 元素中。
<div id="app">
<p>欢迎来到 {{ message }} 的世界!</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Vue.js'
}
});
</script>
代码解析:
{{ message }}
: 将数据模型中的message
属性值插入到p
元素中。
3.2 属性绑定
使用 v-bind
指令将数据模型中的值绑定到 HTML 元素的属性上。
<div id="app">
<img v-bind:src="imageUrl" alt="Vue.js Logo">
</div>
<script>
new Vue({
el: '#app',
data: {
imageUrl: 'https://vuejs.org/images/logo.png'
}
});
</script>
代码解析:
v-bind:src="imageUrl"
: 将数据模型中的imageUrl
属性值绑定到img
元素的src
属性上。
3.3 事件绑定
使用 v-on
指令将事件监听器绑定到 HTML 元素上。
<div id="app">
<button v-on:click="handleClick">点击我</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleClick() {
alert('你点击了按钮!');
}
}
});
</script>
代码解析:
v-on:click="handleClick"
: 将handleClick
方法绑定到button
元素的click
事件上。handleClick()
: 当按钮被点击时,该方法会被调用。
3.4 双向绑定
使用 v-model
指令实现表单元素与数据模型的双向绑定。
<div id="app">
<input type="text" v-model="message">
<p>你输入的内容是:{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello'
}
});
</script>
代码解析:
v-model="message"
: 将input
元素的值与数据模型中的message
属性值进行双向绑定。- 当用户在
input
元素中输入内容时,message
属性值会自动更新。 - 当
message
属性值发生变化时,input
元素的值也会自动更新。
第四章:指令系统 - 扩展 HTML 功能,增强表达力
4.1 v-text
指令
更新元素的文本内容。
<div id="app">
<p v-text="message"></p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
});
</script>
代码解析:
v-text="message"
: 将数据模型中的message
属性值设置为p
元素的文本内容。
4.2 v-html
指令
更新元素的 HTML 内容。
<div id="app">
<div v-html="htmlContent"></div>
</div>
<script>
new Vue({
el: '#app',
data: {
htmlContent: '<h1>这是一个标题</h1><p>这是一段文字</p>'
}
});
</script>
代码解析:
v-html="htmlContent"
: 将数据模型中的htmlContent
属性值解析为 HTML 代码,并渲染到div
元素中。
4.3 v-show
指令
根据条件控制元素的显示状态。
<div id="app">
<p v-show="showParagraph">这是一段文字</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showParagraph: true
}
});
</script>
代码解析:
v-show="showParagraph"
: 当showParagraph
属性值为true
时,p
元素显示;当showParagraph
属性值为false
时,p
元素隐藏。
4.4 v-if
指令
根据条件动态创建或销毁元素。
<div id="app">
<p v-if="showParagraph">这是一段文字</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showParagraph: true
}
});
</script>
代码解析:
v-if="showParagraph"
: 当showParagraph
属性值为true
时,p
元素被创建并显示;当showParagraph
属性值为false
时,p
元素被销毁。
4.5 v-for
指令
循环渲染列表数据。
<div id="app">
<ul>
<li v-for="(item, index) in items" :key="index">
{{ item }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
items: ['Apple', 'Banana', 'Orange']
}
});
</script>
代码解析:
v-for="(item, index) in items"
: 循环遍历items
数组,并将每个元素的值赋给item
变量,索引赋给index
变量。:key="index"
: 为每个列表项设置唯一的key
属性,用于优化列表渲染性能。
4.6 v-bind
指令
动态绑定 HTML 属性。
<div id="app">
<a v-bind:href="url">访问网站</a>
</div>
<script>
new Vue({
el: '#app',
data: {
url: 'https://vuejs.org'
}
});
</script>
代码解析:
v-bind:href="url"
: 将数据模型中的url
属性值绑定到a
元素的href
属性上。
4.7 v-on
指令
绑定事件监听器。
<div id="app">
<button v-on:click="handleClick">点击我</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleClick() {
alert('你点击了按钮!');
}
}
});
</script>
代码解析:
v-on:click="handleClick"
: 将handleClick
方法绑定到button
元素的click
事件上。handleClick()
: 当按钮被点击时,该方法会被调用。
4.8 v-model
指令
实现表单元素与数据模型的双向绑定。
<div id="app">
<input type="text" v-model="message">
<p>你输入的内容是:{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello'
}
});
</script>
代码解析:
v-model="message"
: 将input
元素的值与数据模型中的message
属性值进行双向绑定。- 当用户在
input
元素中输入内容时,message
属性值会自动更新。 - 当
message
属性值发生变化时,input
元素的值也会自动更新。
第五章:计算属性 - 优化逻辑,提升性能
计算属性用于根据数据模型计算出一个新的值,并缓存计算结果,提高性能。
<div id="app">
<p>反转后的消息:{{ reversedMessage }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
computed: {
reversedMessage: function () {
return this.message.split('').reverse().join('');
}
}
});
</script>
代码解析:
computed: { reversedMessage: function () { ... } }
: 定义一个名为reversedMessage
的计算属性。reversedMessage
计算属性的值是通过this.message.split('').reverse().join('')
计算得到的,即反转message
属性值。- 当
message
属性值发生变化时,reversedMessage
计算属性的值也会自动更新。
第六章:侦听器 - 监听变化,触发动作
侦听器用于监听数据模型的变化,并在变化发生时执行相应的操作。
<div id="app">
<p>消息:{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
watch: {
message: function (newValue, oldValue) {
console.log('message 属性值发生了变化:', newValue, oldValue);
}
}
});
</script>
代码解析:
watch: { message: function (newValue, oldValue) { ... } }
: 定义一个名为message
的侦听器。- 当
message
属性值发生变化时,message
侦听器会触发回调函数,并将新值和旧值作为参数传递给回调函数。 - 回调函数中,可以使用
console.log()
打印新值和旧值,或者执行其他操作。
第七章:生命周期钩子 - 控制流程,灵活应用
生命周期钩子函数允许我们在 Vue 实例的不同阶段执行自定义逻辑。
<div id="app">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
created() {
console.log('实例创建完成!');
},
mounted() {
console.log('实例挂载完成!');
},
beforeUpdate() {
console.log('数据更新之前!');
},
updated() {
console.log('数据更新完成!');
},
beforeDestroy() {
console.log('实例销毁之前!');
},
destroyed() {
console.log('实例销毁完成!');
}
});
</script>
代码解析:
created()
: 实例创建完成后调用。mounted()
: 实例挂载完成后调用。beforeUpdate()
: 数据更新之前调用。updated()
: 数据更新完成后调用。beforeDestroy()
: 实例销毁之前调用。destroyed()
: 实例销毁完成后调用。
第二部分:Vue.js 进阶 - 掌握技巧,游刃有余
第八章:条件渲染 - 灵活控制,展现动态
8.1 v-if
指令
根据条件动态创建或销毁元素。
<div id="app">
<p v-if="showParagraph">这是一段文字</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showParagraph: true
}
});
</script>
代码解析:
v-if="showParagraph"
: 当showParagraph
属性值为true
时,p
元素被创建并显示;当showParagraph
属性值为false
时,p
元素被销毁。
8.2 v-else
指令
与 v-if
配合使用,提供另一种条件分支。
<div id="app">
<p v-if="showParagraph">这是一段文字</p>
<p v-else>这是一段隐藏的文字</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showParagraph: false
}
});
</script>
代码解析:
v-else
: 当v-if
条件不满足时,v-else
块中的内容会被渲染。
8.3 v-show
指令
根据条件控制元素的显示状态。
<div id="app">
<p v-show="showParagraph">这是一段文字</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showParagraph: true
}
});
</script>
代码解析:
v-show="showParagraph"
: 当showParagraph
属性值为true
时,p
元素显示;当showParagraph
属性值为false
时,p
元素隐藏。
第九章:列表渲染 - 循环展示,丰富内容
9.1 v-for
指令
循环渲染列表数据。
<div id="app">
<ul>
<li v-for="(item, index) in items" :key="index">
{{ item }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
items: ['Apple', 'Banana', 'Orange']
}
});
</script>
代码解析:
v-for="(item, index) in items"
: 循环遍历items
数组,并将每个元素的值赋给item
变量,索引赋给index
变量。:key="index"
: 为每个列表项设置唯一的key
属性,用于优化列表渲染性能。
9.2 数组方法
Vue.js 提供了一些数组方法,可以方便地操作数据模型中的数组。
push()
: 在数组末尾添加一个或多个元素。pop()
: 删除数组的最后一个元素。unshift()
: 在数组开头添加一个或多个元素。shift()
: 删除数组的第一个元素。splice()
: 在数组中删除或插入元素。sort()
: 对数组进行排序。reverse()
: 反转数组元素的顺序。filter()
: 过滤数组元素。map()
: 映射数组元素。
第十章:事件处理 - 响应交互,增强体验
10.1 事件绑定
使用 v-on
指令将事件监听器绑定到 HTML 元素上。
<div id="app">
<button v-on:click="handleClick">点击我</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleClick() {
alert('你点击了按钮!');
}
}
});
</script>
代码解析:
v-on:click="handleClick"
: 将handleClick
方法绑定到button
元素的click
事件上。handleClick()
: 当按钮被点击时,该方法会被调用。
10.2 事件修饰符
Vue.js 提供了一些事件修饰符,可以方便地对事件的默认行为进行修改。
.stop
: 阻止事件冒泡。.prevent
: 阻止默认行为。.self
: 只当事件是从侦听器绑定的元素本身触发时才触发回调。.once
: 只触发一次回调。
<div id="app">
<a v-on:click.prevent="handleClick">链接</a>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleClick() {
alert('你点击了链接!');
}
}
});
</script>
代码解析:
v-on:click.prevent="handleClick"
: 使用.prevent
修饰符阻止链接的默认跳转行为。
10.3 事件参数
在事件处理函数中,可以使用 $event
对象获取原生事件对象。
<div id="app">
<button v-on:click="handleClick">点击我</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleClick(event) {
console.log('你点击了按钮!', event);
}
}
});
</script>
代码解析:
handleClick(event)
: 事件处理函数接收event
参数,该参数为原生事件对象。
第十一章:表单处理 - 收集数据,实现交互
11.1 表单绑定
使用 v-model
指令实现表单元素与数据模型的双向绑定。
<div id="app">
<input type="text" v-model="message">
<p>你输入的内容是:{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello'
}
});
</script>
代码解析:
v-model="message"
: 将input
元素的值与数据模型中的message
属性值进行双向绑定。- 当用户在
input
元素中输入内容时,message
属性值会自动更新。 - 当
message
属性值发生变化时,input
元素的值也会自动更新。
11.2 表单验证
Vue.js 提供了一些方法,可以方便地对表单数据进行验证。
required
: 确保字段不能为空。min
: 确保字段的最小值。max
: 确保字段的最大值。pattern
: 确保字段的值符合指定的正则表达式。
<div id="app">
<input type="text" v-model="message" required>
<p v-if="message.length < 5">请输入至少 5 个字符</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: ''
}
});
</script>
代码解析:
required
: 确保input
元素的值不能为空。v-if="message.length < 5"
: 当message
属性值的长度小于 5 时,显示错误提示信息。
11.3 表单提交
可以使用 v-on:submit
指令监听表单提交事件。
<div id="app">
<form v-on:submit.prevent="handleSubmit">
<input type="text" v-model="message">
<button type="submit">提交</button>
</form>
</div>
<script>
new Vue({
el: '#app',
data: {
message: ''
},
methods: {
handleSubmit() {
console.log('表单提交成功!', this.message);
}
}
});
</script>
代码解析:
v-on:submit.prevent="handleSubmit"
: 使用.prevent
修饰符阻止表单的默认提交行为,并将handleSubmit
方法绑定到表单的submit
事件上。handleSubmit()
: 当表单提交时,该方法会被调用。
第十二章:模板语法 - 灵活表达,构建视图
12.1 文本插值
使用双大括号 {{ }}
将数据模型中的值插入到 HTML 元素中。
<div id="app">
<p>欢迎来到 {{ message }} 的世界!</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Vue.js'
}
});
</script>
代码解析:
{{ message }}
: 将数据模型中的message
属性值插入到p
元素中。
12.2 属性绑定
使用 v-bind
指令将数据模型中的值绑定到 HTML 元素的属性上。
<div id="app">
<img v-bind:src="imageUrl" alt="Vue.js Logo">
</div>
<script>
new Vue({
el: '#app',
data: {
imageUrl: 'https://vuejs.org/images/logo.png'
}
});
</script>
代码解析:
v-bind:src="imageUrl"
: 将数据模型中的imageUrl
属性值绑定到img
元素的src
属性上。
12.3 事件绑定
使用 v-on
指令将事件监听器绑定到 HTML 元素上。
<div id="app">
<button v-on:click="handleClick">点击我</button>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleClick() {
alert('你点击了按钮!');
}
}
});
</script>
代码解析:
v-on:click="handleClick"
: 将handleClick
方法绑定到button
元素的click
事件上。handleClick()
: 当按钮被点击时,该方法会被调用。
12.4 双向绑定
使用 v-model
指令实现表单元素与数据模型的双向绑定。
<div id="app">
<input type="text" v-model="message">
<p>你输入的内容是:{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello'
}
});
</script>
代码解析:
v-model="message"
: 将input
元素的值与数据模型中的message
属性值进行双向绑定。- 当用户在
input
元素中输入内容时,message
属性值会自动更新。 - 当
message
属性值发生变化时,input
元素的值也会自动更新。
12.5 条件渲染
使用 v-if
、v-else
和 v-show
指令根据条件动态渲染元素。
<div id="app">
<p v-if="showParagraph">这是一段文字</p>
<p v-else>这是一段隐藏的文字</p>
</div>
<script>
new Vue({
el: '#app',
data: {
showParagraph: false
}
});
</script>
代码解析:
v-if="showParagraph"
: 当showParagraph
属性值为true
时,第一个p
元素被创建并显示;当showParagraph
属性值为false
时,第一个p
元素被销毁。v-else
: 当v-if
条件不满足时,第二个p
元素会被渲染。
12.6 列表渲染
使用 v-for
指令循环渲染列表数据。
<div id="app">
<ul>
<li v-for="(item, index) in items" :key="index">
{{ item }}
</li>
</ul>
</div>
<script>
new Vue({
el: '#app',
data: {
items: ['Apple', 'Banana', 'Orange']
}
});
</script>
代码解析:
v-for="(item, index) in items"
: 循环遍历items
数组,并将每个元素的值赋给item
变量,索引赋给index
变量。:key="index"
: 为每个列表项设置唯一的key
属性,用于优化列表渲染性能。
第十三章:过滤器 - 格式化数据,增强可读性
过滤器用于对数据进行格式化,使其更易于阅读或展示。
<div id="app">
<p>当前时间:{{ date | formatDate }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
date: new Date()
},
filters: {
formatDate: function (value) {
return value.toLocaleDateString();
}
}
});
</script>
代码解析:
filters: { formatDate: function (value) { ... } }
: 定义一个名为formatDate
的过滤器。{{ date | formatDate }}
: 使用管道符|
将date
属性值传递给formatDate
过滤器进行格式化。formatDate
过滤器将日期对象格式化为本地日期字符串。
第十四章:自定义指令 - 扩展功能,增强灵活性
自定义指令允许我们扩展 HTML 元素的功能,实现更复杂的交互效果。
Vue.directive('focus', {
inserted: function (el) {
el.focus();
}
});
<div id="app">
<input type="text" v-focus>
</div>
<script>
new Vue({
el: '#app'
});
</script>
代码解析:
Vue.directive('focus', { ... })
: 定义一个名为focus
的自定义指令。inserted: function (el) { ... }
: 指令插入到 DOM 中时执行的回调函数。el.focus()
: 将焦点设置到input
元素上。
第三部分:Vue.js 组件化开发 - 模块化设计,提高效率
第十五章:创建组件 - 拆分模块,提高复用
组件是 Vue.js 中构建用户界面的基本单元,它可以将用户界面拆分成独立、可复用的模块,提高代码复用性和可维护性。
Vue.component('my-component', {
template: '<div>这是一个自定义组件</div>'
});
<div id="app">
<my-component></my-component>
</div>
<script>
new Vue({
el: '#app'
});
</script>
代码解析:
Vue.component('my-component', { ... })
: 创建一个名为my-component
的组件。template: '<div>这是一个自定义组件</div>'
: 定义组件的模板。<my-component></my-component>
: 在模板中使用组件。
第十六章:组件数据 - 独立管理,清晰结构
组件可以拥有自己的数据模型,用于管理组件内部的数据。
Vue.component('my-component', {
template: '<div>{{ message }}</div>',
data() {
return {
message: 'Hello from component!'
};
}
});
<div id="app">
<my-component></my-component>
</div>
<script>
new Vue({
el: '#app'
});
</script>
代码解析:
data() { ... }
: 定义组件的数据模型。{{ message }}
: 在组件模板中使用组件数据模型中的message
属性值。
第十七章:组件通信 - 数据传递,协同工作
17.1 父组件向子组件传递数据
使用 props
属性将数据从父组件传递给子组件。
Vue.component('my-component', {
template: '<div>{{ message }}</div>',
props: ['message']
});
<div id="app">
<my-component :message="'Hello from parent!'"></my-component>
</div>
<script>
new Vue({
el: '#app'
});
</script>
代码解析:
props: ['message']
: 定义组件接收的props
属性。:message="'Hello from parent!'"
: 在父组件模板中使用v-bind
指令将数据传递给子组件。
17.2 子组件向父组件传递数据
使用 $emit
方法触发自定义事件,并将数据作为参数传递给父组件。
Vue.component('my-component', {
template: '<button @click="handleClick">点击我</button>',
methods: {
handleClick() {
this.$emit('custom-event', 'Hello from child!');
}
}
});
<div id="app">
<my-component @custom-event="handleCustomEvent"></my-component>
</div>
<script>
new Vue({
el: '#app',
methods: {
handleCustomEvent(message) {
console.log('接收到子组件的消息:', message);
}
}
});
</script>
代码解析:
this.$emit('custom-event', 'Hello from child!')
: 在子组件中触发名为custom-event
的自定义事件,并将'Hello from child!'
作为参数传递给父组件。@custom-event="handleCustomEvent"
: 在父组件模板中使用v-on
指令监听子组件触发的自定义事件。handleCustomEvent(message)
: 父组件的事件处理函数,接收子组件传递过来的数据。
17.3 兄弟组件之间通信
可以使用事件总线或 Vuex 状态管理模式实现兄弟组件之间的通信。
事件总线:
const bus = new Vue();
Vue.component('my-component-a', {
template: '<button @click="handleClick">发送消息</button>',
methods: {
handleClick() {
bus.$emit('custom-event', 'Hello from component A!');
}
}
});
Vue.component('my-component-b', {
template: '<p>{{ message }}</p>',
data() {
return {
message: ''
};
},
mounted() {
bus.$on('custom-event', (message) => {
this.message = message;
});
}
});
<div id="app">
<my-component-a></my-component-a>
<my-component-b></my-component-b>
</div>
<script>
new Vue({
el: '#app'
});
</script>
代码解析:
const bus = new Vue();
: 创建一个新的 Vue 实例作为事件总线。bus.$emit('custom-event', 'Hello from component A!');
: 在组件 A 中触发名为custom-event
的自定义事件,并将'Hello from component A!'
作为参数传递给事件总线。bus.$on('custom-event', (message) => { ... });
: 在组件 B 中监听事件总线触发的custom-event