<!-- App.vue -->
<script setup lang="ts">
import { ref, computed } from 'vue';
const keyword = ref('');
const shops = ref([
{ id: 1, name: 'Vue 书店', district: 'A', open: true },
{ id: 2, name: 'Pinia 咖啡馆', district: 'A', open: false },
{ id: 3, name: 'Nuxt 茶馆', district: 'B', open: true },
]);
const visibleShops = computed(() =>
shops.value.filter(shop =>
shop.name.toLowerCase().includes(keyword.value.toLowerCase())
)
);
function toggleShop(id: number) {
const target = shops.value.find(shop => shop.id === id);
if (target) target.open = !target.open;
}
</script>
<template>
<main>
<h1>软件城市新城区商业街</h1>
<input v-model="keyword" placeholder="搜索店铺" />
<p>匹配店铺数:{{ visibleShops.length }}</p>
<ul>
<li v-for="shop in visibleShops" :key="shop.id">
<strong>{{ shop.name }}</strong>
<span> / {{ shop.district }} 区 / {{ shop.open ? '营业中' : '休息中' }}</span>
<button @click="toggleShop(shop.id)">切换状态</button>
</li>
</ul>
</main>
</template>input 输入
↓ v-model
keyword 改变
↓
computed(visibleShops) 重算
↓
列表自动刷新
↓
点击按钮
↓
shops 状态改变
↓
页面再次精准更新这就是 Vue 最核心的体验:
你维护业务状态,Vue 负责把街区界面稳定地映射出来。
#Vue 概念关系总图
Vue 新城区商业街宇宙
│
┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ ▼ ▼
组件蓝图层 响应式引擎层 应用治理层
│ │ │
├── SFC ├── ref / reactive ├── Vue Router
├── template ├── computed ├── Pinia
├── props / emits ├── watch / watchEffect ├── Vite / create-vue
├── v-model ├── lifecycle └── DevTools
├── slots └── composables
└── Transition /
Teleport / KeepAlive
│
▼
更大的上层框架
│
└── Nuxt 4.x