Vue.js 入门指南:从零开始构建你的第一个应用

Vue.js 入门指南:从零开始构建你的第一个应用

什么是 Vue.js?

Vue.js(通常简称为 Vue)是一个渐进式 JavaScript 框架,用于构建用户界面。由前 Google 工程师尤雨溪于 2014 年创建,如今已成为全球最流行的前端框架之一。Vue 的核心特点包括:

  • 渐进式架构:可以逐步采用,从增强静态页面到构建复杂单页应用
  • 响应式系统:自动追踪数据变化并更新视图
  • 组件化开发:将 UI 拆分为独立可复用的组件
  • 易学易用:基于标准 HTML、CSS 和 JavaScript,学习曲线平缓
  • 轻量高效:运行时仅 20KB 左右,性能优异

为什么选择 Vue?

  1. 简单易上手:对初学者友好,文档完善
  2. 灵活性强:可根据需求选择使用方式
  3. 社区活跃:拥有庞大开发者社区和丰富生态
  4. 性能出色:虚拟 DOM 和智能优化策略
  5. 现代工具链:Vite 构建工具提供极速开发体验

搭建第一个 Vue 应用

安装 Vue

方法一:CDN 引入(最简单方式)

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <title>第一个 Vue 应用</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
  <div id="app">
    {{ message }}
  </div>

  <script>
    const { createApp } = Vue
  
    createApp({
      data() {
        return {
          message: '你好,Vue!'
        }
      }
    }).mount('#app')
  </script>
</body>
</html>

方法二:使用 Vite 创建项目(推荐)

bash 复制代码
npm create vite@latest my-vue-app -- --template vue
cd my-vue-app
npm install
npm run dev

方法三:使用 Vue CLI 创建项目

bash 复制代码
npm install -g @vue/cli
# 或
yarn global add @vue/clinpm 

vue --version  # 验证安装是否成功
vue create my-project # 创建项目
cd my-project
npm run serve

Vue 应用基本结构

js 复制代码
// main.js
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
js 复制代码
<!-- App.vue -->
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>计数器: {{ count }}</p>
    <button @click="increment">增加</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      title: '我的第一个Vue应用',
      count: 0
    }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>

<style scoped>
h1 {
  color: #42b983;
}
</style>

Vue 核心概念详解

1. 模板语法

Vue 使用基于 HTML 的模板语法,允许你声明式地将数据绑定到 DOM:

js 复制代码
<template>
  <!-- 文本插值 -->
  <p>{{ message }}</p>
  
  <!-- 原始 HTML -->
  <p v-html="rawHtml"></p>
  
  <!-- 属性绑定 -->
  <a :href="url">链接</a>
  
  <!-- 条件渲染 -->
  <div v-if="isVisible">可见内容</div>
  <div v-else>其他内容</div>
  
  <!-- 列表渲染 -->
  <ul>
    <li v-for="(item, index) in items" :key="item.id">
      {{ index }}. {{ item.name }}
    </li>
  </ul>
</template>

2. 响应式数据

Vue 自动跟踪 JavaScript 对象的变化并更新 DOM:

js 复制代码
export default {
  data() {
    return {
      message: 'Hello Vue!',
      counter: 0,
      user: {
        name: '张三',
        age: 30
      },
      todos: [
        { id: 1, text: '学习Vue' },
        { id: 2, text: '构建应用' }
      ]
    }
  },
  methods: {
    updateUser() {
      // Vue 会自动检测这些变化并更新视图
      this.user.age = 31
      this.todos.push({ id: 3, text: '部署项目' })
    }
  }
}

3. 指令系统

指令是带有 v- 前缀的特殊属性:

指令 说明 示例
v-bind 动态绑定属性 :class="{ active: isActive }
v-on 绑定事件监听器 @click="handleClick"
v-model 表单输入双向绑定 <input v-model="message">
v-if/v-show 条件渲染 <p v-if="isVisible">显示</p>
v-for 列表渲染 <li v-for="item in items">
v-html 输出原始 HTML <div v-html="rawHtml">

4. 组件基础

组件是 Vue 的核心概念,允许你将 UI 拆分为独立可复用的部分:

js 复制代码
<!-- 父组件 ParentComponent.vue -->
<template>
  <div>
    <child-component 
      :title="parentTitle"
      @child-event="handleChildEvent"
    />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue'

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentTitle: '来自父组件的消息'
    }
  },
  methods: {
    handleChildEvent(data) {
      console.log('收到子组件事件:', data)
    }
  }
}
</script>
js 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <div>
    <h2>{{ title }}</h2>
    <button @click="sendToParent">通知父组件</button>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      required: true
    }
  },
  emits: ['child-event'],
  methods: {
    sendToParent() {
      this.$emit('child-event', { message: '来自子组件的数据' })
    }
  }
}
</script>

5. 计算属性和侦听器

计算属性 :基于响应式数据派生值 侦听器:响应数据变化执行操作

js 复制代码
<template>
  <div>
    <p>原始价格: {{ price }} 元</p>
    <p>折扣后价格: {{ discountedPrice }} 元</p>
    <input v-model="discountPercent" placeholder="输入折扣百分比">
  </div>
</template>

<script>
export default {
  data() {
    return {
      price: 100,
      discountPercent: 10
    }
  },
  computed: {
    // 计算属性 - 自动缓存结果
    discountedPrice() {
      return this.price * (1 - this.discountPercent / 100)
    }
  },
  watch: {
    // 侦听器 - 响应特定数据变化
    discountPercent(newVal, oldVal) {
      if (newVal > 50) {
        alert('折扣不能超过50%!')
        this.discountPercent = 50
      }
    }
  }
}
</script>

6. 生命周期钩子

Vue 组件有多个生命周期阶段,你可以在特定阶段执行代码:

js 复制代码
export default {
  data() {
    return {
      data: null
    }
  },
  // 组件初始化后,数据观测已建立
  created() {
    console.log('组件已创建')
    this.fetchData()
  },
  // 组件挂载到 DOM 后
  mounted() {
    console.log('组件已挂载')
    this.setupEventListeners()
  },
  // 组件更新后
  updated() {
    console.log('组件已更新')
  },
  // 组件卸载前
  beforeUnmount() {
    console.log('组件即将卸载')
    this.cleanup()
  },
  methods: {
    fetchData() { /* 获取数据 */ },
    setupEventListeners() { /* 设置事件监听 */ },
    cleanup() { /* 清理操作 */ }
  }
}

实战:构建待办事项应用

js 复制代码
<template>
  <div class="todo-app">
    <h1>待办事项清单</h1>
  
    <!-- 添加新任务 -->
    <div class="add-todo">
      <input 
        v-model="newTodo" 
        @keyup.enter="addTodo"
        placeholder="添加新任务..."
      >
      <button @click="addTodo">添加</button>
    </div>
  
    <!-- 过滤选项 -->
    <div class="filters">
      <button 
        :class="{ active: filter === 'all' }"
        @click="filter = 'all'"
      >
        全部
      </button>
      <button 
        :class="{ active: filter === 'active' }"
        @click="filter = 'active'"
      >
        未完成
      </button>
      <button 
        :class="{ active: filter === 'completed' }"
        @click="filter = 'completed'"
      >
        已完成
      </button>
    </div>
  
    <!-- 任务列表 -->
    <ul class="todo-list">
      <li v-for="todo in filteredTodos" :key="todo.id">
        <input 
          type="checkbox" 
          v-model="todo.completed"
        >
        <span :class="{ completed: todo.completed }">
          {{ todo.text }}
        </span>
        <button @click="removeTodo(todo.id)">删除</button>
      </li>
    </ul>
  
    <!-- 统计信息 -->
    <div class="stats">
      <p>剩余任务: {{ activeTodosCount }} / 总任务: {{ todos.length }}</p>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      newTodo: '',
      todos: [
        { id: 1, text: '学习Vue基础', completed: false },
        { id: 2, text: '构建第一个Vue应用', completed: true },
        { id: 3, text: '探索Vue高级特性', completed: false }
      ],
      filter: 'all'
    }
  },
  computed: {
    activeTodosCount() {
      return this.todos.filter(todo => !todo.completed).length
    },
    filteredTodos() {
      switch (this.filter) {
        case 'active':
          return this.todos.filter(todo => !todo.completed)
        case 'completed':
          return this.todos.filter(todo => todo.completed)
        default:
          return this.todos
      }
    }
  },
  methods: {
    addTodo() {
      if (this.newTodo.trim() === '') return
  
      this.todos.push({
        id: Date.now(),
        text: this.newTodo,
        completed: false
      })
  
      this.newTodo = ''
    },
    removeTodo(id) {
      this.todos = this.todos.filter(todo => todo.id !== id)
    }
  }
}
</script>

<style>
.todo-app {
  max-width: 600px;
  margin: 20px auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

.add-todo {
  display: flex;
  margin-bottom: 20px;
}

.add-todo input {
  flex-grow: 1;
  padding: 10px;
  font-size: 16px;
}

.add-todo button {
  margin-left: 10px;
  padding: 10px 15px;
  background: #42b983;
  color: white;
  border: none;
  cursor: pointer;
}

.filters {
  margin-bottom: 20px;
}

.filters button {
  padding: 5px 10px;
  margin-right: 5px;
  background: #f0f0f0;
  border: 1px solid #ddd;
  cursor: pointer;
}

.filters button.active {
  background: #42b983;
  color: white;
}

.todo-list {
  list-style: none;
  padding: 0;
}

.todo-list li {
  display: flex;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid #eee;
}

.todo-list input[type="checkbox"] {
  margin-right: 10px;
}

.todo-list span.completed {
  text-decoration: line-through;
  color: #888;
}

.todo-list button {
  margin-left: auto;
  background: #ff6b6b;
  color: white;
  border: none;
  padding: 5px 10px;
  cursor: pointer;
}

.stats {
  margin-top: 20px;
  text-align: center;
  color: #666;
}
</style>

下一步学习路径

掌握了 Vue 基础后,你可以继续深入学习:

  1. Vue Router:构建单页面应用(SPA)的路由管理
  2. 状态管理:使用 Pinia 管理全局状态
  3. 组合式 API:Vue 3 的现代代码组织方式
  4. 服务端渲染:使用 Nuxt.js 提升应用性能
  5. UI 框架:Element Plus、Vuetify 等流行 UI 库
  6. 测试:使用 Vitest 和 Vue Test Utils 进行组件测试

学习资源推荐

结语

Vue.js 以其简洁的设计和强大的功能,已成为现代前端开发的首选框架之一。通过本指南,你已经掌握了 Vue 的核心概念和基本用法。现在,是时候动手实践,构建你自己的 Vue 应用了!

记住,学习编程最好的方法就是不断实践。从简单的项目开始,逐步挑战更复杂的应用,你将很快成为一名熟练的 Vue 开发者。祝你编程愉快!

相关推荐
OpenTiny社区1 小时前
从零开发 AI 聊天页要两周?试试这款 Vue3 垂直对话组件库 TinyRobot,直接开箱即用
前端·vue.js·github
Cobyte1 小时前
22.Vue Vapor 组件 props 的实现
前端·javascript·vue.js
白雾茫茫丶3 小时前
探索 Nuxt.js 全栈能力:用 Better-Auth 打造类型安全的 RBAC 权限系统
前端·vue.js·nuxt.js
向阳而生6604 小时前
文件上传也能玩出花?Vue3 教你优雅实现“选择文件”和“选择文件夹”🚀
vue.js
3630458414 小时前
Signal 带来的架构问题思考
前端·vue.js
古夕21 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js
Ruihong21 小时前
Vue withDefaults 转 React:VuReact 怎么处理?
vue.js·react.js·面试
稀土熊猫君1 天前
一个人能做出什么开源项目?
vue.js·后端·开源
DarkLONGLOVE2 天前
快速上手 Pinia!Vue3 极简状态管理使用教程
javascript·vue.js
宸翰2 天前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app