一文带你了解 Vue.js:基础概念介绍
在当今瞬息万变的Web开发领域,前端框架已成为构建复杂、交互式用户界面的基石。在众多流行的框架中,Vue.js凭借其易学易用、灵活高效的特性,赢得了全球开发者广泛的青睐。无论是初学者还是有经验的开发者,了解Vue.js的基础概念都是迈入前端开发新世界的重要一步。
本文将带你深入探索Vue.js的核心基础概念,从它是什么,到如何使用它的基本特性构建简单的应用。我们将详细讲解模板语法、数据绑定、指令、事件处理、计算属性、侦听器以及组件的基础知识,为你构建扎实的Vue.js学习基础。
第一章:Vue.js 是什么?为什么选择 Vue.js?
1.1 Vue.js 的定义
Vue.js(读音 /vjuː/,类似于 view)是一个渐进式的JavaScript框架,用于构建用户界面。与其他大型框架不同的是,Vue被设计成可以自底向上逐层应用。这意味着你可以只使用Vue的核心库来构建应用的一小部分,也可以使用官方支持的库和扩展构建完整的单页应用(SPA)。
其核心是一个响应式的数据绑定系统和组件系统。它简化了DOM操作的复杂性,让开发者能够更专注于应用的数据和逻辑,而不是直接操作DOM元素。
1.2 为什么选择 Vue.js?
- 易学易用: Vue.js的设计简洁明了,API直观。如果你有HTML、CSS、JavaScript的基础,学习Vue.js会非常顺畅。它不需要复杂的构建设置(虽然实际开发中通常会用构建工具),可以通过简单的CDN引入快速开始。
- 渐进式框架: 这是Vue最大的特点之一。你可以根据项目需求,逐步引入Vue的各个功能。例如,只使用其声明式渲染和组件系统,或者进一步引入Vue Router(路由)、Pinia/Vuex(状态管理)等,构建大型应用。这种灵活性使得Vue既适用于小型项目,也适用于大型企业级应用。
- 高性能: Vue.js使用了虚拟DOM(Virtual DOM)技术,并进行了优化,使得DOM更新非常高效。当数据发生变化时,Vue会对比新旧虚拟DOM树,找出差异,然后只更新需要改变的真实DOM部分,极大地提升了性能。
- 组件化: Vue鼓励开发者将UI拆分成独立、可复用的组件。每个组件包含自己的HTML模板、JavaScript逻辑和CSS样式,使得代码组织清晰,易于维护和重用。
- 完善的生态系统: Vue拥有活跃的社区和丰富的官方及第三方库,如Vue Router、Pinia/Vuex、Vite(构建工具)、Nuxt.js(SSR框架)等,能够满足各种复杂的开发需求。
- 友好的开发者体验: 结合官方提供的Vue Devtools浏览器扩展,调试Vue应用变得非常方便。详细的错误提示和警告也帮助开发者快速定位问题。
总而言之,Vue.js凭借其易学性、灵活性、高性能和完善的生态,成为了前端开发领域中一个非常具有竞争力的选择。
第二章:快速上手第一个 Vue.js 应用
在深入探讨Vue.js的基础概念之前,我们先来创建一个最简单的Vue应用,体验一下它的魅力。
2.1 通过 CDN 引入 Vue
最快速上手的方式是通过内容分发网络(CDN)直接在HTML文件中引入Vue库。
“`html
“`
将以上代码保存为HTML文件并在浏览器中打开,你将看到页面上显示 “Hello, Vue!”。
这是一个非常基础的例子,但它展示了Vue的几个核心思想:
- 声明式渲染: 我们在HTML模板中使用了
{{ message }}
语法,而不是手动通过JavaScript查找DOM元素并修改其内容。Vue会根据data
中的message
值自动渲染到页面上。 - 数据绑定:
{{ message }}
与Vue实例中的message
数据是关联的。如果message
数据发生变化,页面上的显示会自动更新。 - 应用实例 (
createApp
): Vue 3 中通过Vue.createApp()
方法创建一个应用实例,它是整个Vue应用的根。 - 选项 (
data
): 在应用实例的选项中,data
函数返回一个对象,这个对象里的属性就是应用的状态数据。 - 挂载 (
mount
):app.mount('#app')
将Vue应用实例与HTML中的特定DOM元素(id为app
的div)关联起来,使Vue能够控制这个DOM区域。
第三章:Vue 实例 (App Instance) 与 Options API
在Vue 3中,我们通过 createApp()
方法创建应用实例。一个应用实例可以配置各种选项,其中最基础和常用的就是 data
、methods
、computed
、watch
等,这些构成了Options API。
“`javascript
const app = Vue.createApp({
// 根组件的选项对象,配置了应用的初始状态、行为等
data() {
return {
// … 响应式数据
}
},
methods: {
// … 定义方法
},
computed: {
// … 定义计算属性
},
watch: {
// … 定义侦听器
},
// … 其他选项如 components, mounted 等
})
// 挂载应用
app.mount(‘#app’)
“`
data
: 前面已经介绍过,它是一个函数,返回一个对象。这个对象里的属性将成为应用实例的响应式状态。当这些数据变化时,依赖于它们渲染的DOM会自动更新。methods
: 一个对象,用于定义应用实例中的方法。这些方法可以在模板中通过事件指令(如v-on:click
或@click
)调用。computed
: 一个对象,用于定义计算属性。计算属性基于其依赖的响应式数据计算得来,并且具有缓存特性。watch
: 一个对象,用于侦听响应式数据的变化,并在数据变化时执行特定的副作用(如异步操作或复杂的逻辑)。
我们将在后续章节详细介绍 methods
、computed
和 watch
。
第四章:模板语法与数据绑定
Vue.js 使用基于HTML的模板语法,允许你声明式地将DOM绑定到底层的数据。所有Vue模板都是合法的HTML,所以能被遵循规范的浏览器和HTML解析器解析。
4.1 插值 (Interpolation)
最基本的数据绑定形式是文本插值,使用“Mustache”语法(双大括号):
“`html
{{ message }}
现在的日期是: {{ new Date().toLocaleDateString() }}
“`
javascript
const app = Vue.createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app');
{{ message }}
会被替换为Vue实例中 message
属性的值。插值内部可以放置任何JavaScript表达式,包括简单的算术运算、字符串连接、三元运算符等。
4.2 原始 HTML (Raw HTML)
默认情况下,插值会将数据解释为纯文本。如果你需要输出真正的HTML内容,可以使用 v-html
指令:
“`html
使用 Mustache 语法: {{ rawHtml }}
使用 v-html 指令:
“`
javascript
const app = Vue.createApp({
data() {
return {
rawHtml: '<span style="color: red;">这段文字是红色的</span>'
}
}
}).mount('#app');
使用 v-html
要非常小心,因为它可能导致XSS攻击。只在你信任内容来源时使用它。
4.3 Attribute 绑定 (v-bind
)
Mustache语法不能用于HTML attributes。要响应式地绑定一个 attribute,例如 id
、class
、href
、src
等,你需要使用 v-bind
指令:
“`html
“`
javascript
const app = Vue.createApp({
data() {
return {
isButtonDisabled: true,
linkUrl: 'https://vuejs.org',
imageUrl: 'path/to/your/image.png'
}
}
}).mount('#app');
当 isButtonDisabled
为 true
时,按钮会被禁用;当为 false
时,按钮变为可用。linkUrl
和 imageUrl
会根据数据动态设置。
v-bind
的简写: v-bind
有一个常用的简写形式:省略 v-bind:
,只保留属性名。
html
<button :disabled="isButtonDisabled">按钮</button>
<a :href="linkUrl">链接</a>
<img :src="imageUrl" alt="图片">
这是实际开发中最常用的形式。
4.4 类和样式绑定 (v-bind:class
, v-bind:style
)
绑定HTML class和inline style是常见的需求,Vue为此提供了增强的功能。你可以将表达式计算结果绑定到一个字符串、对象或数组。
绑定 HTML Class:
-
对象语法:
html
<div id="app">
<div :class="{ active: isActive, 'text-danger': hasError }">
绑定Class的对象语法
</div>
</div>javascript
const app = Vue.createApp({
data() {
return {
isActive: true,
hasError: false
}
}
}).mount('#app');active
类是否存在取决于isActive
的真假值,text-danger
类是否存在取决于hasError
的真假值。你可以在对象中绑定多个类。 -
数组语法:
html
<div id="app">
<div :class="[activeClass, errorClass]">
绑定Class的数组语法
</div>
</div>javascript
const app = Vue.createApp({
data() {
return {
activeClass: 'active',
errorClass: 'text-danger'
}
}
}).mount('#app');数组中的每个元素都是需要添加的类名。你也可以在数组中使用对象语法。
绑定 Inline Style:
-
对象语法:
html
<div id="app">
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }">
绑定Style的对象语法
</div>
</div>javascript
const app = Vue.createApp({
data() {
return {
activeColor: 'blue',
fontSize: 20
}
}
}).mount('#app');CSS属性名可以使用驼峰式(camelCase)或短横线分隔(kebab-case),通常推荐驼峰式。
-
数组语法:
html
<div id="app">
<div :style="[baseStyles, overridingStyles]">
绑定Style的数组语法
</div>
</div>javascript
const app = Vue.createApp({
data() {
return {
baseStyles: {
color: 'green',
fontSize: '16px'
},
overridingStyles: {
fontWeight: 'bold'
}
}
}
}).mount('#app');数组中的多个样式对象会合并。
第五章:指令 (Directives)
指令是带有 v-
前缀的特殊 attribute。指令的职责是当表达式的值改变时,响应式地更新DOM。前面我们已经见到了 v-html
和 v-bind
。接下来看更多常用的内置指令。
5.1 条件渲染 (v-if
, v-else-if
, v-else
, v-show
)
用于根据条件控制元素的显示与隐藏。
-
v-if
: 根据表达式的真假值条件渲染元素。如果在元素上使用v-if
,该元素及其子组件会被销毁/重新创建。“`html
欢迎回来!
请先登录。
<div v-if="type === 'A'">类型A</div> <div v-else-if="type === 'B'">类型B</div> <div v-else-if="type === 'C'">类型C</div> <div v-else>其他类型</div>
“`
javascript
const app = Vue.createApp({
data() {
return {
loggedIn: true,
type: 'B'
}
}
}).mount('#app'); -
v-show
: 也是根据条件渲染元素,但不同之处在于,带有v-show
的元素始终会被渲染并保留在DOM中。v-show
只是简单地切换元素的CSS属性display
。html
<div id="app">
<p v-show="showMessage">这条消息会显示或隐藏</p>
</div>javascript
const app = Vue.createApp({
data() {
return {
showMessage: true
}
}
}).mount('#app');
v-if
vs v-show
:
v-if
是“真正”的条件渲染,因为它会根据条件销毁或重建元素及其子组件。v-show
只是基于CSS进行切换。
选择哪个?
- 如果需要非常频繁地切换元素的显示/隐藏,使用
v-show
性能更好,因为它避免了重复的创建和销毁开销。 - 如果在运行时条件很少改变,或者条件为假时希望完全不渲染元素,使用
v-if
更合适。
5.2 列表渲染 (v-for
)
用于根据数组或对象的列表渲染多个元素。
-
遍历数组:
html
<div id="app">
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.text }}
</li>
</ul>
</div>javascript
const app = Vue.createApp({
data() {
return {
items: [
{ id: 1, text: '学习 Vue' },
{ id: 2, text: '学习 JavaScript' },
{ id: 3, text: '构建很棒的应用' }
]
}
}
}).mount('#app');v-for
语法是(item, index) in items
,其中items
是源数据数组,item
是当前遍历到的元素,index
是其索引(可选)。 -
key
的重要性: 当使用v-for
时,务必为每个渲染项提供一个唯一的key
attribute。这是Vue的虚拟DOM算法优化所必需的。Vue会通过key
来跟踪每个节点的身份,从而重用和重新排序现有元素,而不是从头开始渲染,这大大提高了列表更新的效率和稳定性。理想的key
值是每个项目的唯一ID。避免使用数组索引作为key
,除非你的列表数据永远不会改变顺序。 -
遍历对象:
v-for
也可以遍历一个对象的属性。html
<div id="app">
<ul>
<li v-for="(value, key, index) in myObject" :key="key">
{{ index }}. {{ key }}: {{ value }}
</li>
</ul>
</div>javascript
const app = Vue.createApp({
data() {
return {
myObject: {
title: '如何学习 Vue',
author: 'Vue Team',
publishedYear: 2021
}
}
}
}).mount('#app');遍历对象时,
v-for
的参数是(value, key, index)
,其中value
是属性值,key
是属性名,index
是索引(从0开始)。
5.3 事件处理 (v-on
)
用于监听DOM事件并在触发时运行JavaScript代码。
“`html
计数: {{ counter }}
输入内容: {{ message }}
“`
javascript
const app = Vue.createApp({
data() {
return {
counter: 0,
message: ''
}
},
methods: {
incrementCounter() {
this.counter++;
},
updateMessage(event) {
this.message = event.target.value;
}
}
}).mount('#app');
v-on:click="incrementCounter"
监听按钮的点击事件,当点击发生时,调用Vue实例中methods
对象里定义的incrementCounter
方法。v-on:input="updateMessage"
监听输入框的input
事件,调用updateMessage
方法,并将原生事件对象event
作为参数传递。在方法中,可以通过event.target.value
获取输入框的当前值。
v-on
的简写: v-on
也有一个常用的简写形式:@
。
html
<button @click="incrementCounter">点击增加计数</button>
<input @input="updateMessage" :value="message">
这是实际开发中最常用的形式。
事件修饰符: Vue提供了事件修饰符来处理常见的DOM事件细节,如阻止默认行为、停止事件冒泡等。修饰符通过.
连接在事件名称后面:
.stop
: 阻止事件继续传播(冒泡)。.prevent
: 阻止元素的默认行为(例如,阻止链接跳转)。.capture
: 添加事件侦听器时使用捕获模式。.self
: 只当事件是从元素本身触发时才触发处理函数。.once
: 事件只会被触发一次。.passive
: 提高移动端滚动的性能。
“`html
“`
5.4 双向绑定 (v-model
)
v-model
指令在表单输入元素或组件上创建双向绑定。它本质上是 v-bind
和 v-on
的语法糖。
“`html
输入内容: {{ message }}
多行输入: {{ longMessage }}
选择了: {{ checkedNames }}
选择了: {{ picked }}
选择了: {{ selected }}
选择了: {{ multiSelected }}
“`
javascript
const app = Vue.createApp({
data() {
return {
message: '',
longMessage: '',
checked: false,
checkedNames: [], // 多个复选框通常绑定到数组
picked: '', // 单选按钮通常绑定到字符串
selected: '', // 单选选择框绑定到字符串
multiSelected: [] // 多选选择框绑定到数组
}
}
}).mount('#app');
v-model
会根据表单元素的类型自动选取合适的方式进行数据绑定:
* text
和 textarea
元素:绑定 value
property 并监听 input
事件。
* checkbox
和 radio
按钮:绑定 checked
property 并监听 change
事件。
* select
元素:绑定 value
property 并监听 change
事件。
v-model
也可以配合修饰符使用:
* .lazy
: 默认情况下 v-model
在每次 input
事件触发后更新数据,.lazy
会将更新推迟到 change
事件发生时。
* .number
: 将输入内容自动转换为数字类型。
* .trim
: 自动过滤输入内容两端的空白字符。
第六章:方法 (Methods)
方法是与Vue实例相关联的函数,通常用于处理事件或执行特定的业务逻辑。它们定义在Vue实例选项对象的 methods
属性中。
“`html
{{ greetingMessage }}
“`
javascript
const app = Vue.createApp({
data() {
return {
greetingMessage: ''
}
},
methods: {
greet(message) {
this.greetingMessage = message + ', Vue!';
// 在方法内部,可以通过 this 访问实例的数据和其他属性
},
say(msg, event) {
console.log(event); // 可以访问原生事件对象
this.greetingMessage = msg + ', ' + event.target.tagName + '!';
}
}
}).mount('#app');
- 方法可以直接通过
this
访问Vue实例的数据 (this.greetingMessage
) 以及其他方法。 - 方法可以在模板中通过
v-on
或@
指令调用。 - 调用方法时可以传递参数。如果要访问原生DOM事件对象,可以在调用时显式传递
$event
。
第七章:计算属性 (Computed Properties)
计算属性是基于响应式依赖进行缓存的属性。它们定义在Vue实例选项对象的 computed
属性中。
“`html
原字符串: “{{ message }}”
反转字符串 (计算属性): “{{ reversedMessage }}”
价格: {{ price }}
税率: {{ taxRate }}
含税价格 (计算属性): {{ taxedPrice }}
“`
javascript
const app = Vue.createApp({
data() {
return {
message: 'Hello',
price: 100,
taxRate: 0.1
}
},
computed: {
// 一个计算属性的 getter
reversedMessage() {
// 当 message 变化时,reversedMessage 会重新计算
return this.message.split('').reverse().join('');
},
taxedPrice() {
// 当 price 或 taxRate 变化时,taxedPrice 会重新计算
return this.price * (1 + this.taxRate);
}
}
}).mount('#app');
为什么使用计算属性?
- 可读性: 将复杂的逻辑放入计算属性中,模板会更简洁。
- 缓存: 计算属性是基于它们的响应式依赖进行缓存的。只有当其依赖的响应式数据发生变化时,计算属性才会重新求值。如果依赖的数据没有变化,多次访问计算属性会立即返回之前缓存的结果,而不是重新执行函数。这对于计算开销较大的情况非常有用。
计算属性 vs 方法:
虽然你也可以在 methods
中定义一个函数来实现反转字符串的逻辑并在模板中调用,例如 {{ reverseString() }}
,但计算属性有缓存的优势。
- 计算属性: 只在其依赖的数据发生变化时重新计算。
- 方法: 只要组件重新渲染(例如,任何数据发生变化),调用方法就会执行函数。
通常,对于需要根据现有响应式数据派生出新数据的情况,并且这个派生过程可能涉及一些逻辑或计算,优先考虑使用计算属性。如果只是需要执行一些行为(如事件处理),则使用方法。
计算属性的 Setter:
计算属性默认只有 getter(获取值),但你也可以提供一个 setter(设置值):
javascript
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName;
},
// setter
set(newValue) {
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[names.length - 1];
}
}
}
现在当你设置 app.fullName = 'John Doe'
时,setter 会被调用,并根据新的值更新 firstName
和 lastName
。
第八章:侦听器 (Watchers)
侦听器是一种更通用的方式来响应数据的变化。当你需要在响应式数据变化时执行一些副作用,例如执行异步操作、开销较大的操作、或根据数据变化进行一些复杂的DOM操作(虽然通常应该让Vue处理DOM),这时可以使用侦听器。它们定义在Vue实例选项对象的 watch
属性中。
“`html
{{ answer }}
“`
javascript
const app = Vue.createApp({
data() {
return {
question: '',
answer: '我无法回答,直到你提问!'
}
},
watch: {
// 当 question 变化时,这个函数会被执行
question(newQuestion, oldQuestion) {
if (newQuestion.includes('?')) {
this.getAnswer();
} else {
this.answer = '问题必须包含一个问号 (?)';
}
}
},
methods: {
getAnswer() {
this.answer = '思考中...';
// 模拟一个异步请求
setTimeout(() => {
const random = Math.random();
if (random < 0.5) {
this.answer = '当然可以。';
} else {
this.answer = '不可以。';
}
}, 1000);
}
}
}).mount('#app');
在上面的例子中,我们 watch
侦听了 question
数据的变化。当 question
变化时,侦听函数会被调用,并接收到新值 (newQuestion
) 和旧值 (oldQuestion
) 作为参数。我们在侦听函数中根据新值是否包含问号来决定是调用异步方法获取答案还是给出提示。
计算属性 vs 侦听器:
- 计算属性: 用于基于现有响应式数据派生出新的数据,并具有缓存。它们是声明式的,关注的是“数据是什么”。
- 侦听器: 用于在响应式数据变化时执行副作用。它们是命令式的,关注的是“数据变化后做什么”。
大多数情况下,如果只是需要派生数据并显示在模板中,计算属性是更好的选择。侦听器适用于执行更复杂的、带有副作用的异步或开销大的操作,或者当你需要根据数据的旧值和新值执行不同的逻辑时。
第九章:组件基础
组件是Vue.js中构建用户界面的核心概念。组件将模板、脚本和样式封装在一起,使代码更具组织性、可重用性和可维护性。可以把组件看作是自定义的HTML元素。
9.1 注册组件
Vue组件需要先注册才能使用。可以全局注册或局部注册。
-
全局注册 (Vue 3): 使用
app.component()
方法进行全局注册,注册后可以在应用的任何地方使用。“`javascript
const app = Vue.createApp({});// 全局注册一个名为 ‘my-component’ 的组件
app.component(‘my-component’, {
data() {
return {
count: 0
}
},
template:<button @click="count++">
你点击了我 {{ count }} 次
</button>
});app.mount(‘#app’);
“` -
局部注册: 将组件注册到父组件的
components
选项中。这种方式更常用,因为它避免了全局命名冲突,并且可以明确知道组件的依赖关系。html
<div id="app">
<local-component></local-component>
</div>javascript
const app = Vue.createApp({
// 局部注册一个名为 'local-component' 的组件
components: {
'local-component': {
data() {
return {
message: '我是局部组件'
}
},
template: '<p>{{ message }}</p>'
}
}
}).mount('#app');
一旦注册,你就可以在父组件的模板中像使用普通HTML标签一样使用这个组件:
“`html
“`
9.2 组件的组成
一个典型的单文件组件(Single File Component, SFC,使用 .vue
文件)包含了 <template>
、<script>
和 <style>
三个部分,但从基础概念上看,一个组件对象只需要 template
和包含数据、方法、计算属性等的选项。
javascript
const myComponent = {
// 组件自身的数据,必须是函数返回对象,保证每个组件实例都有独立的数据副本
data() {
return {
// ...
}
},
// 组件自身的方法
methods: {
// ...
},
// 组件自身的计算属性
computed: {
// ...
},
// 组件自身的侦听器
watch: {
// ...
},
// 组件接受的外部数据
props: [
// ...
],
// 组件发出的自定义事件
emits: [
// ...
],
// 组件的模板结构
template: `
<!-- HTML 模板,只能有一个根元素 -->
<div>
<p>组件内容</p>
</div>
`,
// 组件的样式(通常在 SFC 的 <style> 标签中)
// style: '...'
}
9.3 组件间通信 (基础概念)
虽然深入的组件通信是更高级的主题,但在基础概念层面,了解最基本的父子组件通信方式是很重要的:
-
Props(属性): 父组件通过
v-bind
将数据传递给子组件。子组件在其props
选项中声明接收的属性。这是一种单向数据流:数据总是从父组件流向子组件。html
<!-- 父组件模板 -->
<div id="app">
<child-component :my-prop="parentMessage"></child-component>
</div>javascript
const app = Vue.createApp({
data() {
return {
parentMessage: '来自父组件的消息'
}
},
components: {
'child-component': {
// 声明接收 myProp 属性
props: ['myProp'],
template: '<p>接收到的消息: {{ myProp }}</p>'
}
}
}).mount('#app'); -
Custom Events(自定义事件): 子组件通过调用
$emit()
方法触发一个自定义事件,父组件通过v-on
监听这个事件,从而实现子组件向父组件传递信息。html
<!-- 父组件模板 -->
<div id="app">
<child-button @button-clicked="handleButtonClick"></child-button>
<p>父组件接收到的事件: {{ eventReceived }}</p>
</div>javascript
const app = Vue.createApp({
data() {
return {
eventReceived: ''
}
},
methods: {
handleButtonClick(payload) {
this.eventReceived = '子组件按钮被点击,并传递了: ' + payload;
}
},
components: {
'child-button': {
// 声明发出的事件 (Vue 3 推荐,增强可读性和验证)
emits: ['button-clicked'],
template: `
<button @click="$emit('button-clicked', '一些数据')">
点击我,触发事件
</button>
`
}
}
}).mount('#app');
父子组件之间的 Props Down, Events Up (父传子用 props,子传父用事件) 是Vue中最基本的组件通信模式。
第十章:生命周期钩子 (Lifecycle Hooks)
每个Vue组件实例在创建时都会经过一系列初始化步骤,例如设置数据观测、编译模板、将实例挂载到DOM、更新DOM时触发、以及在销毁前做一些清理工作。这些过程中会运行一些特定的函数,称为生命周期钩子。
常用的生命周期钩子:
beforeCreate
: 实例刚刚被创建,选项处理之前,数据和方法都未初始化。created
: 实例已经创建完成,数据观测 (data),属性和方法的运算,事件回调都已经初始化。可以在这里访问data
和methods
。 常用于发送异步请求获取数据。beforeMount
: 模板编译/或者el
选项指定的DOM,即将挂载到页面之前。mounted
: 实例已经被挂载到页面上,DOM已经可以访问。可以在这里执行需要访问DOM的操作。beforeUpdate
: 数据发生变化,更新视图之前调用。updated
: 数据更新,视图重新渲染之后调用。beforeUnmount
: 实例被卸载销毁之前调用。常用于清理资源,如取消定时器、解绑事件监听器。unmounted
: 实例已被卸载销毁。
“`javascript
const app = Vue.createApp({
data() {
return {
message: ‘Hello Lifecycle’
}
},
beforeCreate() {
console.log(‘— beforeCreate —‘);
console.log(‘数据:’, this.message); // undefined
},
created() {
console.log(‘— created —‘);
console.log(‘数据:’, this.message); // ‘Hello Lifecycle’
// 这里可以发起异步请求
},
beforeMount() {
console.log(‘— beforeMount —‘);
console.log(‘DOM 挂载点:’, document.getElementById(‘app’).innerHTML); // 此时DOM还没被Vue修改
},
mounted() {
console.log(‘— mounted —‘);
console.log(‘DOM 挂载点:’, document.getElementById(‘app’).innerHTML); // 此时DOM已经被Vue渲染
// 这里可以进行DOM操作
},
beforeUpdate() {
console.log(‘— beforeUpdate —‘);
console.log(‘更新前的数据:’, this.message);
},
updated() {
console.log(‘— updated —‘);
console.log(‘更新后的数据:’, this.message);
// DOM 已更新
},
beforeUnmount() {
console.log(‘— beforeUnmount —‘);
},
unmounted() {
console.log(‘— unmounted —‘);
}
}).mount(‘#app’);
// 可以在开发者工具中修改 app.message 来观察 update 钩子
// 可以通过 app.unmount() 来观察 unmount 钩子
“`
理解生命周期钩子对于在应用的正确时机执行代码非常重要。
结语
恭喜你,已经了解了Vue.js的大部分基础概念!我们从Vue.js的定义和优势出发,通过CDN引入的方式快速搭建了第一个Vue应用,并详细探讨了Vue实例、模板语法、数据绑定(包括属性、类、样式)、常用的指令(v-if
, v-for
, v-on
, v-model
),以及Methods、Computed properties和Watchers这三个重要的实例选项。最后,我们初步接触了组件的概念和生命周期钩子。
这些基础知识是构建任何规模的Vue.js应用的基础。掌握它们,你就能理解Vue如何实现声明式渲染和响应式更新,以及如何组织和管理UI。
当然,Vue.js的世界远不止于此。在实际开发中,你会接触到单文件组件(.vue 文件)、构建工具(如 Vite 或 Webpack)、Vue Router(用于路由)、Pinia/Vuex(用于复杂状态管理)、异步组件、过渡动画等等。但请记住,所有这些更高级的功能都是建立在本文介绍的基础概念之上的。
接下来的学习建议:
- 动手实践:尝试使用这些基础概念构建一些小的示例应用。
- 阅读官方文档:Vue.js的官方文档非常优秀,详细且易懂,是最佳的学习资源。
- 深入单文件组件:理解
.vue
文件如何工作,以及构建工具的作用。 - 学习Vue Router和Pinia/Vuex:这是构建单页应用的必备工具。
- 参与社区:提问、解答、分享经验,与他人交流能加速学习进程。
希望这篇文章能够为你打开Vue.js的大门,助你在前端开发的道路上更进一步!祝你学习愉快,编码顺利!