Vue.js 示例

Table of Contents

1. 计数器组件(基础响应式)

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">+1</button>
    <button @click="reset">Reset</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';

// 响应式变量
const count = ref(0);

// 方法
const increment = () => count.value++;
const reset = () => count.value = 0;
</script>

核心概念

  • ref 创建响应式变量
  • @click 事件绑定
  • 模板中直接使用变量

2. Todo List(列表渲染 & 表单绑定)

<template>
  <div>
    <input v-model="newTodo" @keyup.enter="addTodo" placeholder="Add a task">
    <ul>
      <li v-for="(todo, index) in todos" :key="index">
        {{ todo.text }}
        <button @click="removeTodo(index)">×</button>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref } from 'vue';

const todos = ref([{ text: 'Learn Vue' }]);
const newTodo = ref('');

const addTodo = () => {
  if (newTodo.value.trim()) {
    todos.value.push({ text: newTodo.value });
    newTodo.value = '';
  }
};

const removeTodo = (index) => {
  todos.value.splice(index, 1);
};
</script>

核心概念

  • v-model 双向绑定表单输入
  • v-for 列表渲染
  • 数组操作(push/splice)

3. 父子组件通信(Props & Emit)

<!-- ParentComponent.vue -->
<template>
  <ChildComponent 
    :message="parentMessage" 
    @update-message="handleUpdate"
  />
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const parentMessage = ref('Hello from parent');
const handleUpdate = (newMsg) => {
  parentMessage.value = newMsg;
};
</script>

<!-- ChildComponent.vue -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="sendMessage">Change Message</button>
  </div>
</template>

<script setup>
const props = defineProps(['message']);
const emit = defineEmits(['update-message']);

const sendMessage = () => {
  emit('update-message', 'New message from child');
};
</script>

核心概念

  • defineProps 接收父组件数据
  • defineEmits 定义自定义事件
  • 父子组件数据流

4. API 数据请求(axios 集成)

<template>
  <div v-if="loading">Loading...</div>
  <div v-else>
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';

const users = ref([]);
const loading = ref(true);

onMounted(async () => {
  try {
    const response = await axios.get('https://jsonplaceholder.typicode.com/users');
    users.value = response.data;
  } catch (error) {
    console.error('API Error:', error);
  } finally {
    loading.value = false;
  }
});
</script>

核心概念

  • onMounted 生命周期钩子
  • 异步数据请求
  • 条件渲染(v-if / v-else)

5. 计算属性(动态过滤)

<template>
  <input v-model="searchText" placeholder="Search...">
  <ul>
    <li v-for="item in filteredItems" :key="item">{{ item }}</li>
  </ul>
</template>

<script setup>
import { ref, computed } from 'vue';

const items = ref(['Apple', 'Banana', 'Orange', 'Grape']);
const searchText = ref('');

const filteredItems = computed(() => {
  return items.value.filter(item => 
    item.toLowerCase().includes(searchText.value.toLowerCase())
  );
});
</script>

核心概念

  • computed 计算属性
  • 实时过滤逻辑

6. 组件状态管理(Pinia 示例)

// store/counter.js
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() { this.count++ }
  }
});
<!-- Component.vue -->
<template>
  <button @click="counterStore.increment">{{ counterStore.count }}</button>
</template>

<script setup>
import { useCounterStore } from '@/store/counter';
const counterStore = useCounterStore();
</script>

核心概念

  • Pinia 状态管理
  • 跨组件共享状态

推荐学习资源:

  1. 官方示例

  2. 实战项目

    • 简易博客系统(文章列表 + 详情页)
    • 电商商品过滤器(价格/分类筛选)
    • 实时聊天界面(WebSocket 集成)
  3. 视频教程


学习建议

  1. 先通过 CodepenStackBlitz 在线编辑器快速尝试
  2. 从最简代码开始,逐步添加功能
  3. 使用 Chrome 的 Vue Devtools 调试响应式数据

Comments |0|

Legend *) Required fields are marked
**) You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
Category: 似水流年