# Vue.js入门指南
Vue.js是一个渐进式JavaScript框架,用于构建用户界面。与其他重量级框架不同,Vue被设计为可以逐步采用。它的核心库只关注视图层,易于上手且与其他库或已有项目整合。本文将帮助你快速入门Vue.js开发。
# Vue.js核心特性
Vue.js的核心功能包括:
- 声明式渲染 - 使用简洁的模板语法声明式地将数据渲染到DOM
- 响应式系统 - 自动追踪依赖关系并在数据变化时更新DOM
- 组件化开发 - 构建可复用、可组合的UI组件
- 单文件组件 - 将HTML、CSS和JavaScript封装在一个
.vue文件中 - 虚拟DOM - 高效DOM更新和渲染优化
# 安装Vue.js
# CDN引入
最简单的方式是通过CDN引入Vue.js:
<!-- 开发环境版本,包含有帮助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
1
2
3
4
5
2
3
4
5
# 使用npm安装
对于大型应用,推荐使用npm进行安装:
# 安装最新稳定版
npm install vue
# Vue CLI - 命令行工具
npm install -g @vue/cli
1
2
3
4
5
2
3
4
5
通过Vue CLI创建新项目:
vue create my-vue-project
1
# Vue.js基础
# 创建Vue实例
一个最简单的Vue应用:
<div id="app">
{{ message }}
</div>
<script>
const app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 数据绑定
Vue使用双大括号语法进行文本插值,使用指令进行特殊绑定:
<!-- 文本插值 -->
<span>{{ message }}</span>
<!-- 属性绑定 -->
<a v-bind:href="url">链接</a>
<!-- 简写 -->
<a :href="url">链接</a>
<!-- 双向数据绑定 -->
<input v-model="message">
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 条件渲染
使用v-if和v-show控制元素的显示:
<!-- v-if:条件为false时,元素不会出现在DOM中 -->
<p v-if="seen">现在你看到我了</p>
<p v-else-if="maybe">也许能看到我</p>
<p v-else>看不到我</p>
<!-- v-show:控制CSS的display属性 -->
<p v-show="visible">总是在DOM中,但可能被隐藏</p>
1
2
3
4
5
6
7
2
3
4
5
6
7
# 列表渲染
使用v-for渲染列表:
<ul>
<li v-for="(item, index) in items" :key="item.id">
{{ index }} - {{ item.name }}
</li>
</ul>
<script>
new Vue({
el: '#app',
data: {
items: [
{ id: 1, name: '张三' },
{ id: 2, name: '李四' },
{ id: 3, name: '王五' }
]
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 事件处理
使用v-on指令绑定事件监听器:
<div id="app">
<p>{{ counter }}</p>
<button v-on:click="increment">增加</button>
<!-- 简写 -->
<button @click="decrement">减少</button>
</div>
<script>
new Vue({
el: '#app',
data: {
counter: 0
},
methods: {
increment() {
this.counter += 1
},
decrement() {
this.counter -= 1
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 计算属性
使用计算属性处理复杂逻辑:
<div id="app">
<p>原始消息: "{{ message }}"</p>
<p>计算后的反转消息: "{{ reversedMessage }}"</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
computed: {
// 计算属性会基于它的依赖进行缓存
reversedMessage: function() {
return this.message.split('').reverse().join('')
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Vue组件系统
# 基本组件
组件是可复用的Vue实例,接受相同的选项(除了特定根实例选项):
// 注册全局组件
Vue.component('my-component', {
// 组件选项
template: '<div>自定义组件!</div>'
})
// 局部组件
const app = new Vue({
el: '#app',
components: {
'local-component': {
template: '<div>局部组件</div>'
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 组件通信
组件间通信的基本模式:
<!-- 父组件 -->
<div id="app">
<child-component :message="parentMessage" @child-event="handleChildEvent"></child-component>
</div>
<script>
// 子组件
Vue.component('child-component', {
props: ['message'],
template: `
<div>
<p>来自父组件的消息: {{ message }}</p>
<button @click="sendToParent">发送事件到父组件</button>
</div>
`,
methods: {
sendToParent() {
this.$emit('child-event', '这是来自子组件的数据')
}
}
})
// 父组件
new Vue({
el: '#app',
data: {
parentMessage: '父组件的消息'
},
methods: {
handleChildEvent(data) {
console.log('收到子组件的事件:', data)
}
}
})
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 实际项目案例
让我们构建一个简单的任务管理应用,展示Vue的核心特性:
<div id="todo-app">
<h1>任务清单</h1>
<div class="add-task">
<input
v-model="newTask"
@keyup.enter="addTask"
placeholder="添加新任务..."
>
<button @click="addTask">添加</button>
</div>
<div class="filters">
<button @click="currentFilter = 'all'" :class="{active: currentFilter === 'all'}">全部</button>
<button @click="currentFilter = 'active'" :class="{active: currentFilter === 'active'}">未完成</button>
<button @click="currentFilter = 'completed'" :class="{active: currentFilter === 'completed'}">已完成</button>
</div>
<ul class="task-list">
<li v-for="task in filteredTasks" :key="task.id" :class="{completed: task.completed}">
<input type="checkbox" v-model="task.completed">
<span>{{ task.text }}</span>
<button @click="removeTask(task)">删除</button>
</li>
</ul>
<div class="footer" v-if="tasks.length > 0">
<span>{{ activeTaskCount }} 个待办任务</span>
<button @click="clearCompleted" v-if="completedTaskCount > 0">清除已完成</button>
</div>
</div>
<script>
new Vue({
el: '#todo-app',
data: {
newTask: '',
tasks: [
{ id: 1, text: '学习Vue基础', completed: false },
{ id: 2, text: '完成项目实战', completed: false },
{ id: 3, text: '精通Vue组件', completed: false }
],
currentFilter: 'all'
},
computed: {
filteredTasks() {
switch (this.currentFilter) {
case 'active':
return this.tasks.filter(task => !task.completed)
case 'completed':
return this.tasks.filter(task => task.completed)
default:
return this.tasks
}
},
activeTaskCount() {
return this.tasks.filter(task => !task.completed).length
},
completedTaskCount() {
return this.tasks.filter(task => task.completed).length
}
},
methods: {
addTask() {
if (this.newTask.trim()) {
this.tasks.push({
id: Date.now(),
text: this.newTask.trim(),
completed: false
})
this.newTask = ''
}
},
removeTask(task) {
const index = this.tasks.indexOf(task)
this.tasks.splice(index, 1)
},
clearCompleted() {
this.tasks = this.tasks.filter(task => !task.completed)
}
}
})
</script>
<style>
/* 添加样式以美化应用 */
.completed {
text-decoration: line-through;
color: #999;
}
.active {
background-color: #42b983;
color: white;
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# Vue生态系统
Vue拥有丰富的生态系统,帮助构建复杂应用:
- Vue Router - 官方路由管理器,实现单页应用导航
- Vuex - 状态管理模式+库,集中管理应用状态
- Vue CLI - 官方项目脚手架,简化项目配置
- Vue DevTools - 浏览器扩展,用于调试Vue应用
- Nuxt.js - 基于Vue的服务端渲染框架
# 从Vue 2迁移到Vue 3
Vue 3带来了许多重要变化和改进:
- Composition API - 更灵活的组织组件逻辑
- 性能改进 - 更小、更快、Tree-shaking友好
- Teleport组件 - 将内容渲染到DOM的不同位置
- 片段(Fragments) - 组件可以有多个根节点
- 响应式系统重写 - 使用Proxy代替Object.defineProperty
Vue 3兼容大部分Vue 2的API,但有一些破坏性变更,详见Vue 3迁移指南 (opens new window)。
# 总结与最佳实践
Vue.js的核心优势在于其渐进式特性和易学性。以下是一些最佳实践:
- 组件设计 - 保持组件职责单一,便于复用和测试
- 数据管理 - 善用Vuex管理共享状态,避免过度传递props
- 性能优化 - 使用
v-once渲染静态内容,合理使用计算属性 - 路由管理 - 使用Vue Router实现路由懒加载,减少初始包体积
- 测试 - 使用Vue Test Utils进行组件测试
通过本文的学习,你已经了解了Vue.js的基本概念和使用方法。Vue的官方文档非常完善,建议在实际开发中随时查阅。
在我在字节跳动的工作中,我们将Vue用于多个内部平台的开发,其简单性和灵活性极大提高了开发效率。无论是简单的页面还是复杂的企业应用,Vue都能很好地满足需求。
# 学习资源
- Vue.js官方文档 (opens new window)
- Vue Mastery (opens new window) - 高质量Vue视频教程
- Vue.js Examples (opens new window) - Vue项目示例集合
- Awesome Vue (opens new window) - Vue相关资源列表