Vue 2 入门教程:零基础学习 Vue – wiki基地


Vue 2 入门教程:零基础掌握前端开发的利器

引言:为什么选择 Vue 2?

欢迎来到前端开发的世界!如果你对构建交互性强、用户体验流畅的网页应用感兴趣,那么掌握一个现代化的前端框架是必不可少的。在众多框架中,Vue.js 脱颖而出,尤其是在中国社区拥有极高的人气和广泛的应用。

而 Vue 2,作为 Vue.js 的一个稳定且成熟的版本,至今仍被大量项目使用,并且它的核心概念是学习 Vue 3 的坚实基础。对于零基础的你来说,Vue 2 提供了一个相对平缓的学习曲线,让你能够快速上手并构建实际应用。

为什么选择 Vue 2?

  1. 易学易用: 设计简洁,文档详尽,非常适合初学者。你可以通过一个简单的 <script> 标签引入 Vue,立即开始编写代码。
  2. 灵活性: 既可以作为一个库嵌入到现有项目中,也可以用来构建大型单页应用 (SPA)。
  3. 性能优秀: 采用虚拟 DOM (Virtual DOM) 技术,高效地更新页面。
  4. 生态系统完善: 拥有配套的路由库 (Vue Router)、状态管理库 (Vuex) 以及构建工具 (Vue CLI)。
  5. 社区活跃: 遇到问题时,很容易找到解决方案和帮助。

本教程将带你从零开始,一步步了解 Vue 2 的核心概念和基本用法,让你能够搭建第一个 Vue 应用,并为将来深入学习打下坚实基础。

前提准备:你需要知道什么?

虽然我们说“零基础学习 Vue”,但这并不是说你不需要任何编程基础。为了更好地理解 Vue 2,你需要掌握以下基本技能:

  1. HTML: 理解网页结构和标签。
  2. CSS: 了解如何为页面添加样式。
  3. JavaScript: 非常重要! 你需要理解变量、数据类型、函数、对象、数组、条件判断、循环等基础概念,以及一些基本的 DOM 操作(虽然 Vue 会替你处理大部分)。

如果你对这些概念还不熟悉,建议先花一些时间学习 JavaScript 基础。

第一步:引入 Vue 2

学习任何新框架或库,最简单的方式就是通过 CDN (内容分发网络) 直接在 HTML 文件中引入。这不需要任何复杂的构建配置。

创建一个简单的 index.html 文件:

“`html






我的第一个 Vue 2 应用




“`

在这个例子中,我们通过 <script src="..."> 标签引入了 Vue 2 的开发版本。现在,你就可以在第二个 <script> 标签中开始编写 Vue 代码了。

第二步:创建你的第一个 Vue 实例

Vue 应用的核心是 Vue 实例 (Vue Instance)。每个 Vue 应用都是通过创建一个新的 Vue 实例来启动的。

Vue 实例需要一个 选项对象 (Options Object) 来进行配置。最基本的选项有两个:eldata

  • el (Element): 指定 Vue 实例将要挂载(控制)的 DOM 元素。通常是一个 CSS 选择器字符串,或者一个 DOM 元素本身。
  • data: 一个对象,包含应用中需要响应式的数据。当 data 中的数据发生变化时,视图会自动更新。

修改你的 <script> 标签内容:

“`html

“`

现在,你的 HTML 文件如下:

“`html






我的第一个 Vue 2 应用


“`

打开这个 HTML 文件,你会在浏览器中看到一个空白页面,因为我们还没有在 div#app 中使用 message 数据。

第三步:模板语法 (Template Syntax)

Vue 使用一种基于 HTML 的模板语法,允许你声明式地将 DOM 绑定到底层数据。最基本的数据绑定形式是 文本插值 (Text Interpolation),使用双大括号 {{}}

修改 index.html 中的 div#app 内容:

“`html

{{ message }}

“`

现在,刷新你的 HTML 文件,你会看到页面上显示了:Hello, Vue 2!

{{ message }} 中的 message 自动被 Vue 实例中的 data.message 的值所替换。这就是 Vue 的响应式魅力:如果我们在控制台中修改 app.message 的值(如果你给 Vue 实例一个变量名,例如 const app = new Vue({...})),页面上的文本会立即更新!

在浏览器开发者工具的 Console 中尝试输入 app.message = 'Vue is awesome!',你会看到页面内容瞬间改变。

第四步:指令 (Directives)

除了文本插值,Vue 还提供了 指令 (Directives)。指令是带有 v- 前缀的特殊属性,用于在 DOM 上应用特殊的响应式行为。

指令的语法通常是 v-指令名,后面可以跟一个 : 表示参数,再后面 = 跟着一个值。这个值通常是 JavaScript 表达式。

我们来学习几个常用的指令:

1. v-bind:绑定属性

v-bind 用于动态地绑定一个或多个 DOM 属性,或一个组件 prop 到表达式。

例如,你想动态地设置一个链接的 href 属性:

“`html

{{ message }}

点击这里

“`

javascript
new Vue({
el: '#app',
data: {
message: 'Hello, Vue 2!',
linkUrl: 'https://cn.vuejs.org/' // 链接地址保存在数据中
}
});

linkUrl 的值改变时,链接的 href 属性也会自动更新。

简写: v-bind: 可以简写为 :。所以 :href="linkUrl"v-bind:href="linkUrl" 是等价的。通常推荐使用简写。

html
<a :href="linkUrl">点击这里</a>

2. v-if:条件渲染

v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回真值时才被渲染。

“`html

这段文字会根据条件显示/隐藏。

“`

javascript
new Vue({
el: '#app',
data: {
isVisible: true // 初始时显示
},
methods: { // 在 methods 中定义方法
toggleShow: function() {
this.isVisible = !this.isVisible; // 点击按钮时切换 isVisible 的值
}
}
});

isVisibletrue 时,<p> 标签会出现在 DOM 中;当 isVisiblefalse 时,<p> 标签会被移除出 DOM。

v-elsev-else-if 你可以配合 v-elsev-else-if 来实现更复杂的条件渲染。

“`html

类型 A
类型 B
其他类型

“`

javascript
new Vue({
el: '#app',
data: {
type: 'A'
}
});

3. v-show:条件显示

v-show 也用于条件性地显示元素。不同于 v-ifv-show 总是会渲染元素到 DOM 中,只是简单地通过 CSS 的 display 属性来控制元素的显示或隐藏。

“`html

正在加载中…

“`

javascript
new Vue({
el: '#app',
data: {
isLoading: true
}
});

v-if vs v-show:

  • v-if 是“真正”的条件渲染,它会根据条件销毁或重建 DOM 元素。开销较高(销毁/重建),但如果条件不经常改变,则可以减少初始渲染开销。
  • v-show 只是基于 CSS 进行切换。初始渲染开销大(总是渲染),但切换开销小。
  • 一般来说,如果在运行时需要频繁切换元素的显示/隐藏,使用 v-show 更好;如果在运行时条件很少改变,或者你需要在条件变化时进行昂贵的初始化或销毁操作,使用 v-if 更好。

4. v-for:列表渲染

v-for 指令用于循环渲染一块元素或模板。它基于源数据多次渲染元素。

常见的用法是遍历数组:

“`html

  • {{ item.text }}

“`

javascript
new Vue({
el: '#app',
data: {
items: [
{ text: '学习 HTML' },
{ text: '学习 CSS' },
{ text: '学习 JavaScript' },
{ text: '学习 Vue' }
]
}
});

v-for="item in items" 中,items 是源数组,item 是当前迭代到的数组元素。

你也可以访问索引:v-for="(item, index) in items"

“`html


  • {{ index }} – {{ item.text }}

“`

key 的重要性:

在使用 v-for 时,为列表的每个元素提供一个唯一的 key 属性 非常重要。Vue 会根据 key 来跟踪每个节点的身份,从而高效地复用和重排现有元素,而不是从头开始渲染。这可以显著提升性能。key 的值应该是唯一的字符串或数字,不要使用对象或数组作为 key。

通常,如果你的数据项有一个唯一的 ID,就使用 ID 作为 key。如果没有,可以使用索引,但这只适用于你的列表数据 不会 改变顺序或被过滤、添加、删除元素的情况。在实际开发中,尽量使用稳定唯一的 ID 作为 key

5. v-on:事件处理

v-on 指令用于监听 DOM 事件,并在触发时运行一些 JavaScript 代码或调用 Vue 实例的方法。

前面我们在 v-if 的例子中已经用过它了:

html
<button v-on:click="handleClick">点击我</button>

v-on:click="handleClick" 表示当按钮被点击时,调用 Vue 实例的 methods 中定义的 handleClick 方法。

简写: v-on: 可以简写为 @。所以 @click="handleClick"v-on:click="handleClick" 是等价的。通常推荐使用简写。

html
<button @click="handleClick">点击我</button>

你可以在 methods 对象中定义事件处理函数:

javascript
new Vue({
el: '#app',
data: {
count: 0
},
methods: {
increment: function() {
this.count++; // 在方法中可以通过 this 访问实例的数据
},
greet: function(event) { // 事件处理函数可以接收原生事件对象
alert('Hello!');
// event 是原生 DOM 事件
if (event) {
console.log(event.target.tagName);
}
}
}
});

你也可以直接在指令的值中写 JavaScript 表达式:@click="count++"。但这只适用于非常简单的操作,复杂的逻辑应该放在 methods 中。

6. v-model:表单输入绑定

v-model 指令用于在表单输入元素或组件上创建双向数据绑定。它会监听用户的输入事件,并自动更新 data 中的属性值;同时,当 data 中的属性值发生变化时,输入框的值也会自动更新。

这对于处理表单输入非常方便:

“`html

输入框的值:{{ message }}

复选框是否选中:{{ isChecked }}

选中的选项:{{ selectedOption }}

“`

javascript
new Vue({
el: '#app',
data: {
message: '', // 初始为空字符串
isChecked: false, // 初始为未选中
selectedOption: '' // 初始为空
}
});

v-model 会根据输入元素的类型自动选择合适的属性和事件来绑定:

  • 文本输入框 (<input type="text">, <textarea>) 使用 value 属性和 input 事件。
  • 复选框 (<input type="checkbox">) 使用 checked 属性和 change 事件。
  • 单选按钮 (<input type="radio">) 使用 checked 属性和 change 事件。
  • 选择框 (<select>) 使用 value 属性和 change 事件。

第五步:计算属性 (Computed Properties) 和侦听器 (Watchers)

在 Vue 实例中,除了 datamethods,还有两个非常有用的选项:computedwatch

计算属性 (Computed Properties)

计算属性是基于它们的响应式依赖进行缓存的。只有当它们的依赖发生改变时才会重新求值。这对于处理复杂逻辑并生成新的数据非常有用。

假设你有 firstNamelastName,你想显示全名:

“`html

姓:
名:

全名:{{ fullName }}

“`

javascript
new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '三'
},
computed: {
// 计算属性 fullName
fullName: function () {
// this 指向 Vue 实例
return this.lastName + ' ' + this.firstName;
}
}
});

fullName 不是一个数据属性,而是一个计算属性。它的值取决于 firstNamelastName。当 firstNamelastName 改变时,fullName 会自动重新计算并更新视图。

计算属性 vs 方法:

你可能会想,为什么不用一个方法来实现同样的功能呢?

“`html

全名:{{ getFullName() }}

“`

javascript
// 在 methods 中
methods: {
getFullName: function() {
return this.lastName + ' ' + this.firstName;
}
}

从结果上看,它们似乎一样。但区别在于 缓存

  • 计算属性: 只有在依赖的数据 (firstNamelastName) 改变时,fullName 才会重新计算。如果多次访问 fullName,只要依赖不变,它会立即返回之前缓存的结果,效率更高。
  • 方法: 每次访问 getFullName() 时,函数都会被调用一次,即使依赖的数据没有改变。

因此,对于任何复杂逻辑或需要从现有数据派生新数据的情况,并且这个数据在模板中会被多次使用,优先选择计算属性。

侦听器 (Watchers)

虽然计算属性在多数情况下都能胜任,但有时你需要执行一些副作用,例如:

  • 根据数据的变化执行异步操作或开销较大的操作。
  • 响应数据的变化来更新 DOM(尽管 Vue 通常会处理好)。
  • 侦听一个属性的变化,然后执行一些列相关的逻辑。

这时可以使用 watch 选项。它允许你“侦听”一个特定的数据属性,并在它发生变化时执行一个函数。

“`html

输入问题:

{{ answer }}

“`

javascript
new Vue({
el: '#app',
data: {
question: '',
answer: '在输入问题之前,我不会回答。'
},
watch: {
// 侦听 question 数据属性的变化
question: function (newQuestion, oldQuestion) {
this.answer = '正在思考...';
// 模拟一个异步操作来获取答案
this.getAnswer();
}
},
methods: {
getAnswer: function () {
if (this.question.indexOf('?') === -1) {
this.answer = '问题必须包含问号。';
return;
}
this.answer = '思考中...';
const vm = this; // 保存 this 的引用,以便在异步回调中使用
setTimeout(function () {
// 模拟网络请求延迟
const randomNum = Math.random();
if (randomNum < 0.5) {
vm.answer = '是的。';
} else {
vm.answer = '不是。';
}
}, 1000); // 延迟 1 秒
}
}
});

在这个例子中,我们侦听 question 的变化。当 question 改变时,watcher 函数被调用,它会更新 answer 的值,并调用一个异步方法 getAnswer 来获取最终答案。

计算属性 vs 侦听器:

  • 计算属性: 用于派生新的数据。它们是同步的,并且有缓存。适合处理数据的转换和计算。
  • 侦听器: 用于响应数据变化执行副作用。它们是异步的,没有缓存。适合执行复杂的逻辑,特别是涉及异步操作或需要“观察”某个属性的变化来触发其他行为时。

记住这条经验法则:大多数情况下,如果能用计算属性解决问题,就用计算属性。只有在需要执行异步操作或复杂的副作用时,才使用侦听器。

第六步:组件 (Components)

组件是 Vue 最强大、最核心的特性之一。组件可以看作是可复用的 Vue 实例,它们拥有自己的模板、逻辑和样式。组件化使得大型应用的代码组织更清晰、更易于维护。

想象一下网页上的一个按钮、一个列表项、一个导航栏,它们都可以被抽象成组件。

全局注册组件 (Simple Example)

在简单的教程示例中,我们可以使用 Vue.component() 方法全局注册一个组件:

“`html


“`

“`javascript
// 全局注册一个名为 my-button 的组件
Vue.component(‘my-button’, {
// 组件的模板
template: ‘‘,
// 组件的数据 – 必须是一个函数,这样每个组件实例才有独立的数据
data: function () {
return {
count: 0
}
}
});

new Vue({
el: ‘#app’
// 主实例不再需要 my-button 的数据,因为数据在组件内部
});
“`

现在,my-button 组件可以在 #app 元素内部的任何地方使用了。点击每个按钮,它们会独立地更新自己的计数器。

注意: 组件的 data 选项必须是一个函数,并且返回一个对象。这是为了确保每个组件实例都有自己独立的数据副本,而不是共享同一个数据对象。

组件之间的通信

在实际应用中,组件通常需要相互通信:父组件向子组件传递数据,子组件通知父组件发生了某些事情。

父组件向子组件传递数据:Props

使用 props (属性) 可以将数据从父组件传递到子组件。子组件在 props 选项中声明它接受的属性。

“`html



“`

“`javascript
Vue.component(‘greeting-message’, {
// 声明组件接受一个名为 message 的 prop
props: [‘message’],
template: ‘

{{ message }}


});

new Vue({
el: ‘#app’,
data: {
dynamicMessage: ‘来自父组件的动态问候!’
}
});
“`

在上面的例子中,greeting-message 组件声明它接受一个 message prop。父组件通过在子组件标签上像 HTML 属性一样绑定 message 来传递数据。注意,传递静态字符串时直接写,传递父组件的数据时需要使用 v-bind (或 : 简写)。

子组件通知父组件:Custom Events

子组件可以使用 $emit() 方法触发自定义事件,父组件可以使用 v-on (或 @ 简写) 监听这些事件,从而响应子组件的动作。

“`html

总点击次数:{{ totalClicks }}


“`

“`javascript
Vue.component(‘child-button’, {
template: ‘‘,
methods: {
handleClick: function() {
// 触发一个名为 ‘child-click’ 的自定义事件
this.$emit(‘child-click’);
}
}
});

new Vue({
el: ‘#app’,
data: {
totalClicks: 0
},
methods: {
incrementTotal: function() {
this.totalClicks++;
}
}
});
“`

child-button 被点击时,它会触发 child-click 事件。父组件监听了这个事件,并执行了 incrementTotal 方法,从而更新了 totalClicks

$emit() 方法还可以接收额外的参数,作为事件的回调函数的参数传递给父组件。

“`javascript
// 子组件触发事件时传递数据
this.$emit(‘child-click’, 5); // 传递数字 5

// 父组件监听事件并接收数据

// 父组件方法接收参数
methods: {
incrementTotalBy: function(amount) { // amount 将接收到 5
this.totalClicks += amount;
}
}
“`

组件通信是一个非常重要的主题,理解 Props 和 Custom Events 是构建复杂应用的基础。

第七步:生命周期钩子 (Lifecycle Hooks)

每个 Vue 实例在被创建时都要经过一系列的初始化过程。例如,它需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM。同时,它也会运行一些函数,这给了用户在不同阶段添加自己的代码的机会。这些函数被称为 生命周期钩子 (Lifecycle Hooks)

常用的生命周期钩子有:

  • created: 实例已经创建完成,数据 data 和方法 methods 已经可以使用,但尚未挂载到 DOM。在这个钩子中,你可以访问数据和调用方法,常用于发起异步请求获取数据。
  • mounted: 实例已经挂载到 DOM,模板已经渲染到页面上。可以在这个钩子中进行 DOM 操作或集成第三方库。
  • updated: 数据发生变化后,虚拟 DOM 重新渲染并更新 DOM。不建议在这里修改数据,可能会导致无限循环。
  • destroyed: Vue 实例被销毁。实例的指令都被解绑,事件监听器被移除,子实例也被销毁。可以在这里进行清理工作,如清除定时器、取消事件监听等。

你可以在选项对象中添加这些钩子函数:

javascript
new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
created: function () {
// `this` 指向 vm 实例
console.log('实例已创建 - data 和 methods 可用');
console.log('message is: ' + this.message);
},
mounted: function () {
// `this` 指向 vm 实例
console.log('实例已挂载到 DOM');
console.log('el is: ', this.$el); // $el 是 Vue 实例挂载的 DOM 元素
},
updated: function () {
console.log('视图已更新');
},
destroyed: function () {
console.log('实例已销毁');
}
});

通过在浏览器控制台中观察输出,你可以更好地理解这些钩子何时被调用。

理解生命周期钩子对于在正确的时间执行代码(如数据获取、DOM 操作或清理)至关重要。

第八步:走向更远 – Vue CLI (简介)

通过 CDN 引入 Vue 适用于学习和小型项目,但对于更大型、更复杂的应用,推荐使用 Vue CLI (Command Line Interface)

Vue CLI 是一个官方提供的命令行工具,可以快速搭建基于 Vue 的开发环境。它集成了:

  • 模块化开发: 使用 ES Module 规范组织代码。
  • 单文件组件 (.vue): 将组件的模板、脚本和样式写在一个 .vue 文件中,极大地提高了代码的可维护性。
  • 构建工具: 集成 Webpack 或 Parcel,自动处理模块打包、代码转译 (如 ES6 -> ES5)、CSS 预处理器、图片优化、热重载等。
  • 开发服务器: 提供一个带有热模块替换 (Hot Module Replacement) 功能的本地开发服务器,提高开发效率。

使用 Vue CLI 构建项目通常是现代 Vue 应用的标准方式。

如何使用 Vue CLI (简要步骤):

  1. 安装 Node.js 和 npm/yarn: Vue CLI 需要 Node.js 环境。
  2. 安装 Vue CLI: 在命令行中运行 npm install -g @vue/cliyarn global add @vue/cli
  3. 创建项目: 在命令行中进入你想创建项目的目录,然后运行 vue create my-vue-app。按照提示选择 Vue 版本 (选择 2.x) 和需要的特性。
  4. 启动开发服务器: 进入项目目录 (cd my-vue-app),运行 npm run serveyarn serve。你的应用将在本地服务器上运行,并且在你修改代码时自动刷新。

通过 Vue CLI 创建的项目结构清晰,适合团队协作和构建大型应用。当你熟悉了 Vue 的核心概念后,强烈建议学习和使用 Vue CLI。

第九步:总结与下一步学习

恭喜你!你已经掌握了 Vue 2 的基本知识,包括:

  • 什么是 Vue 实例,以及 eldata 选项。
  • 如何使用 {{}} 进行文本插值。
  • 常用的指令:v-bind (:),v-if,v-show,v-for,v-on(@),v-model`。
  • 如何在 methods 中定义事件处理函数。
  • 计算属性 computed 和侦听器 watch 的区别与用法。
  • 组件的基本概念,如何全局注册组件。
  • 组件之间通过 props$emit 进行通信。
  • Vue 实例的生命周期钩子。
  • Vue CLI 的作用。

这只是 Vue 2 的冰山一角,但这些基础概念是构建任何 Vue 应用的基石。

接下来的学习方向:

  1. 深入理解组件: 局部注册组件、组件插槽 (Slot)。
  2. Vue Router: 学习如何构建单页应用并进行页面导航。
  3. Vuex: 学习如何进行状态管理,特别是在大型应用中共享和管理复杂的状态。
  4. 单文件组件 (.vue): 学习如何使用 .vue 文件进行组件化开发 (通过 Vue CLI)。
  5. 混入 (Mixins): 学习如何在多个组件之间共享代码。
  6. 自定义指令和插件。
  7. 测试 (Unit Testing, End-to-End Testing)。
  8. 学习 Vue 3: 虽然 Vue 2 仍在使用,但 Vue 3 是未来的方向,学习 Vue 2 的基础将帮助你更快地掌握 Vue 3。

结语

学习编程最好的方式就是动手实践。尝试使用你学到的知识,构建一些小项目:

  • 一个简单的计数器。
  • 一个待办事项列表 (To-Do List)。
  • 一个简单的计算器。
  • 从 API 获取数据并显示 (需要了解异步请求,如 fetchaxios)。

通过不断地练习和挑战,你会越来越熟练。Vue 2 是一个非常棒的入门框架,它为你打开了现代化前端开发的大门。祝你在 Vue 的学习之旅中取得成功!


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部