当前位置: 首页 > news >正文

vue3的watch用法

<template><div class="container mx-auto p-4"><h1 class="text-2xl font-bold mb-4">Vue 3 Watch 示例</h1><div class="grid grid-cols-1 md:grid-cols-2 gap-6"><!-- 基本数据监听 --><div class="bg-white rounded-lg shadow-md p-6"><h2 class="text-xl font-semibold mb-4">基本数据监听</h2><div class="space-y-4"><div class="flex justify-between items-center"><label>计数器:</label><div class="flex items-center"><button @click="state.counter--" class="bg-gray-200 hover:bg-gray-300 px-3 py-1 rounded-l">-</button><span class="px-3 py-1 border-y border-gray-300">{{ state.counter }}</span><button @click="state.counter++" class="bg-gray-200 hover:bg-gray-300 px-3 py-1 rounded-r">+</button></div></div><p class="text-gray-600">上次修改: {{ state.lastCounterUpdate }}</p></div></div><!-- 对象属性监听 --><div class="bg-white rounded-lg shadow-md p-6"><h2 class="text-xl font-semibold mb-4">对象属性监听</h2><div class="space-y-4"><div><label class="block mb-2">姓名:</label><input v-model="state.user.name" type="text" class="w-full px-3 py-2 border border-gray-300 rounded"></div><div><label class="block mb-2">年龄:</label><input v-model.number="state.user.age" type="number" class="w-full px-3 py-2 border border-gray-300 rounded"></div><p class="text-gray-600">上次修改: {{ state.lastUserUpdate }}</p></div></div><!-- 深度监听 --><div class="bg-white rounded-lg shadow-md p-6"><h2 class="text-xl font-semibold mb-4">深度监听</h2><div class="space-y-4"><div><label class="block mb-2">添加爱好:</label><div class="flex"><input v-model="state.newHobby" type="text" class="flex-1 px-3 py-2 border border-gray-300 rounded-l"placeholder="输入爱好"><button @click="addHobby" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-r">添加</button></div></div><div><label class="block mb-2">爱好列表:</label><ul class="space-y-2"><li v-for="(hobby, index) in state.user.hobbies" :key="index" class="flex items-center"><span>{{ hobby }}</span><button @click="removeHobby(index)" class="ml-2 text-red-500 hover:text-red-700"><i class="fa fa-times"></i></button></li></ul></div><p class="text-gray-600">爱好更新次数: {{ state.hobbyUpdateCount }}</p></div></div><!-- 多个数据源监听 --><div class="bg-white rounded-lg shadow-md p-6"><h2 class="text-xl font-semibold mb-4">多个数据源监听</h2><div class="space-y-4"><div><label class="block mb-2">宽度:</label><input v-model.number="state.dimensions.width" type="number" class="w-full px-3 py-2 border border-gray-300 rounded"></div><div><label class="block mb-2">高度:</label><input v-model.number="state.dimensions.height" type="number" class="w-full px-3 py-2 border border-gray-300 rounded"></div><div class="bg-gray-100 p-3 rounded"><p>面积: {{ state.area }}</p><p class="text-sm text-gray-500">上次计算: {{ state.lastAreaCalculation }}</p></div></div></div></div></div>
</template><script setup lang="ts">
import { reactive, watch } from 'vue'interface User {name: stringage: numberhobbies: string[]
}interface Dimensions {width: numberheight: number
}// 使用 reactive 创建响应式状态
const state = reactive({counter: 0,lastCounterUpdate: new Date().toISOString(),user: {name: '张三',age: 25,hobbies: ['阅读', '编程']} as User,newHobby: '', // 新增的爱好输入lastUserUpdate: new Date().toISOString(),hobbyUpdateCount: 0,dimensions: {width: 10,height: 20} as Dimensions,area: 200,lastAreaCalculation: new Date().toISOString()
})// 基本数据监听
watch(() => state.counter,(newValue, oldValue) => {console.log(`计数器从 ${oldValue} 变为 ${newValue}`)state.lastCounterUpdate = new Date().toISOString()}
)// 对象属性监听
watch(() => state.user.name,(newName, oldName) => {console.log(`姓名从 ${oldName} 变为 ${newName}`)state.lastUserUpdate = new Date().toISOString()}
)watch(() => state.user.age,(newAge, oldAge) => {console.log(`年龄从 ${oldAge} 变为 ${newAge}`)state.lastUserUpdate = new Date().toISOString()}
)// 深度监听
watch(() => state.user.hobbies,(newHobbies, oldHobbies) => {console.log('爱好列表更新')console.log('旧列表:', oldHobbies)console.log('新列表:', newHobbies)state.hobbyUpdateCount++},{ deep: true }
)// 多个数据源监听
watch([() => state.dimensions.width,() => state.dimensions.height],([newWidth, newHeight], [oldWidth, oldHeight]) => {console.log(`尺寸从 ${oldWidth}x${oldHeight} 变为 ${newWidth}x${newHeight}`)state.area = newWidth * newHeightstate.lastAreaCalculation = new Date().toISOString()}
)// 方法
const addHobby = () => {if (state.newHobby.trim()) {state.user.hobbies.push(state.newHobby.trim())state.newHobby = ''}
}const removeHobby = (index: number) => {state.user.hobbies.splice(index, 1)
}
</script><style scoped>
.container {max-width: 1200px;
}
</style>

相关文章:

  • 产品规格书写作结构、规范(编写指南)
  • 力扣热题100之翻转二叉树
  • 26考研——文件管理_文件目录(4)
  • 电机驱动器辐射骚扰整改
  • 关于用Cloudflare的Zero Trust实现绕过备案访问国内站点说明
  • HackMyVM-Ephemeral3
  • 考研系列—操作系统:第三章、内存管理(part.2)
  • AI书签管理工具开发全记录(八):Ai创建书签功能实现
  • MySQL事务与锁机制详解:确保数据一致性的关键【MySQL系列】
  • PostIn入门教程 - 使用IDEA插件快速生成API接口定义
  • Halcon
  • 力扣HOT100之动态规划:139. 单词拆分
  • 牛客周赛94
  • 极智项目 | 多模态大模型推理平台-Streamlit版(支持Qwen2.5/InternVL3/KimiVL三大模型)
  • 【CBAP50技术手册】#31 Observation(观察法):BA(业务分析师)的“现场侦探术”
  • 浮点数舍入规则_编程语言对比
  • CTFHub-RCE 命令注入-过滤运算符
  • [SC]SystemC在CPU/GPU验证中的应用(二)
  • R语言错误处理方法大全
  • CRISPR-Cas系统的小型化研究进展-文献精读137
  • 网站建设浏览器不兼容/淘宝站外引流推广方法
  • 东莞的网站建设/最近营销热点
  • 个人 做自媒体 建网站/企业网站推广策略
  • 小榄做网站/seo标题优化的方法
  • 网站维护一般怎么做/新媒体口碑营销案例
  • 西安微信网站建设/想要导航推广网页怎么做