# Vue.js入门指南

Vue.js是一个渐进式JavaScript框架,用于构建用户界面。与其他重量级框架不同,Vue被设计为可以逐步采用。它的核心库只关注视图层,易于上手且与其他库或已有项目整合。本文将帮助你快速入门Vue.js开发。

# Vue.js核心特性

Vue.js的核心功能包括:

  1. 声明式渲染 - 使用简洁的模板语法声明式地将数据渲染到DOM
  2. 响应式系统 - 自动追踪依赖关系并在数据变化时更新DOM
  3. 组件化开发 - 构建可复用、可组合的UI组件
  4. 单文件组件 - 将HTML、CSS和JavaScript封装在一个.vue文件中
  5. 虚拟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

# 使用npm安装

对于大型应用,推荐使用npm进行安装:

# 安装最新稳定版
npm install vue

# Vue CLI - 命令行工具
npm install -g @vue/cli
1
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

# 数据绑定

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

# 条件渲染

使用v-ifv-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

# 列表渲染

使用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

# 事件处理

使用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

# 计算属性

使用计算属性处理复杂逻辑:

<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

# 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

# 组件通信

组件间通信的基本模式:

<!-- 父组件 -->
<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

# 实际项目案例

让我们构建一个简单的任务管理应用,展示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

# Vue生态系统

Vue拥有丰富的生态系统,帮助构建复杂应用:

  1. Vue Router - 官方路由管理器,实现单页应用导航
  2. Vuex - 状态管理模式+库,集中管理应用状态
  3. Vue CLI - 官方项目脚手架,简化项目配置
  4. Vue DevTools - 浏览器扩展,用于调试Vue应用
  5. Nuxt.js - 基于Vue的服务端渲染框架

# 从Vue 2迁移到Vue 3

Vue 3带来了许多重要变化和改进:

  1. Composition API - 更灵活的组织组件逻辑
  2. 性能改进 - 更小、更快、Tree-shaking友好
  3. Teleport组件 - 将内容渲染到DOM的不同位置
  4. 片段(Fragments) - 组件可以有多个根节点
  5. 响应式系统重写 - 使用Proxy代替Object.defineProperty

Vue 3兼容大部分Vue 2的API,但有一些破坏性变更,详见Vue 3迁移指南 (opens new window)

# 总结与最佳实践

Vue.js的核心优势在于其渐进式特性和易学性。以下是一些最佳实践:

  1. 组件设计 - 保持组件职责单一,便于复用和测试
  2. 数据管理 - 善用Vuex管理共享状态,避免过度传递props
  3. 性能优化 - 使用v-once渲染静态内容,合理使用计算属性
  4. 路由管理 - 使用Vue Router实现路由懒加载,减少初始包体积
  5. 测试 - 使用Vue Test Utils进行组件测试

通过本文的学习,你已经了解了Vue.js的基本概念和使用方法。Vue的官方文档非常完善,建议在实际开发中随时查阅。

在我在字节跳动的工作中,我们将Vue用于多个内部平台的开发,其简单性和灵活性极大提高了开发效率。无论是简单的页面还是复杂的企业应用,Vue都能很好地满足需求。

# 学习资源

Last Updated: 2025-03-11T08:38:33.000Z