使用deepseek学习写vue组件
从零开始,
创建一个vue项目,并写一个vue组件
然后回答的很详细
然后一步步的告诉你怎么写
然后编写一个组件,计数器
<!-- src/components/Counter.vue --> <template> <div class="counter-container"> <h2>当前计数: {{ count }}</h2> <div class="button-group"> <button @click="increment" class="btn btn-inc">+</button> <button @click="decrement" class="btn btn-dec">-</button> <button @click="reset" class="btn btn-reset">重置</button> </div> </div> </template> <script setup> import { ref } from 'vue' // 响应式数据 const count = ref(0) // 方法定义 const increment = () => { count.value++ } const decrement = () => { if (count.value > 0) { count.value-- } } const reset = () => { count.value = 0 } </script> <style scoped> .counter-container { text-align: center; padding: 2rem; border: 1px solid #e0e0e0; border-radius: 8px; max-width: 400px; margin: 2rem auto; } .button-group { margin-top: 1rem; } .btn { padding: 0.5rem 1rem; margin: 0 0.5rem; border: none; border-radius: 4px; cursor: pointer; transition: all 0.3s; } .btn-inc { background-color: #4CAF50; color: white; } .btn-dec { background-color: #f44336; color: white; } .btn-reset { background-color: #2196F3; color: white; } .btn:hover { opacity: 0.8; } </style>
然后告诉你怎么使用,在 App.vue 中使用组件
<!-- src/App.vue --> <template> <div class="app"> <h1>Vue 计数器示例</h1> <Counter /> </div> </template> <script setup> import Counter from './components/Counter.vue' </script> <style> .app { font-family: Arial, sans-serif; text-align: center; padding: 20px; } h1 { color: #2c3e50; } </style>
还有扩展建议给你
然后又是一步步的告诉你怎么写,怎么优化,使用props,事件,动画等
最后你写的代码
<!-- src/components/Counter.vue --> <template> <div class="counter-container"> <h2> <Transition name="count" mode="out-in"> <span :key="count" class="count-display"> {{ count }} </span> </Transition> </h2> <div class="button-group"> <button @click="increment" class="btn btn-inc">+</button> <button @click="decrement" class="btn btn-dec">-</button> <button @click="reset" class="btn btn-reset">重置</button> </div> </div> </template> <script setup> import { ref, watchEffect } from 'vue' import { inject } from 'vue' const config = inject('counterConfig', { // 默认配置 max: Infinity, min: -Infinity, step: 1, theme: 'light' }) // 声明参数类型 const props = defineProps({ initialCount: { type: Number, default: 0, validator: value => value >= 0 } }) // 使用 prop 初始化 const count = ref(props.initialCount) // 监听 prop 变化(可选) watchEffect(() => { count.value = props.initialCount }) // 定义事件 const emit = defineEmits(['count-change', 'reset']) const increment = () => { if (count.value < config.max) { count.value += config.step } emit('count-change', { type: 'increment', value: count.value }) } const decrement = () => { if (count.value > config.min) { count.value -= config.step } emit('count-change', { type: 'decrement', value: count.value }) } const reset = () => { count.value = 0 emit('reset',{ type: 'reset', value: count.value }) } </script> <style scoped> .counter-container { text-align: center; padding: 2rem; border: 1px solid #e0e0e0; border-radius: 8px; max-width: 400px; margin: 2rem auto; } .button-group { margin-top: 1rem; } .btn { padding: 0.5rem 1rem; margin: 0 0.5rem; border: none; border-radius: 4px; cursor: pointer; /* transition: all 0.3s; */ transform: scale(1); transition: transform 0.1s ease; } .btn-inc { background-color: #4CAF50; color: white; } .btn-dec { background-color: #f44336; color: white; } .btn-reset { background-color: #2196F3; color: white; } .btn:hover { opacity: 0.8; } .btn:active { transform: scale(0.95); } .count-display { display: inline-block; } .count-enter-active, .count-leave-active { transition: all 0.3s ease; } .count-enter-from { opacity: 0; transform: translateY(-20px); } .count-leave-to { opacity: 0; transform: translateY(20px); } </style>
优化后的代码
<!-- src/components/Counter2.vue --> <template> <div class="counter" :class="[themeClass, sizeClass]" role="group" aria-labelledby="counter-label" > <header> <slot name="header"> <h2 id="counter-label">计数器</h2> </slot> </header> <div class="counter-container"> <Transition name="count" mode="out-in"> <span :key="count" class="count-display" role="status" aria-live="polite" style="font-size: 30px;" > {{ count }} </span> </Transition> <div class="controls"> <button v-for="btn in buttons" :key="btn.id" :class="btn.class" @click="btn.handler" :aria-label="btn.label" :disabled="btn.disabled?.()" > {{ btn.text }} </button> </div> </div> <slot name="footer"></slot> </div> </template> <script setup lang="ts"> import { computed, ref } from 'vue' interface Props { initialCount?: number step?: number theme?: 'light' | 'dark' size?: 'sm' | 'md' | 'lg' min?: number max?: number } const props = withDefaults(defineProps<Props>(), { initialCount: 0, step: 1, theme: 'light', size: 'md', min: -Infinity, max: Infinity }) const emit = defineEmits<{ (e: 'update:count', value: number): void (e: 'change', payload: { oldValue: number, newValue: number }): void }>() const count = ref(props.initialCount) const themeClass = computed(() => `theme-${props.theme}`) const sizeClass = computed(() => `size-${props.size}`) const buttons = computed(() => [ { id: 'btn-dec', text: '-', label: '减少', class: 'btn btn-dec', handler: () => changeCount(-props.step), disabled: () => count.value - props.step < props.min }, { id: 'btn-inc', text: '+', label: '增加', class: 'btn btn-inc', handler: () => changeCount(props.step), disabled: () => count.value + props.step > props.max }, { id: 'btn-reset', text: '重置', label: '重置计数器', class: 'btn btn-reset', handler: () => { count.value = props.initialCount emit('change', { oldValue: count.value, newValue: props.initialCount }) } } ]) const changeCount = (delta: number) => { const newValue = count.value + delta if (newValue >= props.min && newValue <= props.max) { const oldValue = count.value count.value = newValue emit('update:count', newValue) emit('change', { oldValue, newValue }) } } </script> <style scoped> .counter-container { text-align: center; padding: 2rem; border: 1px solid #e0e0e0; border-radius: 8px; max-width: 400px; margin: 2rem auto; } .button-group { margin-top: 1rem; } .btn { padding: 0.5rem 1rem; margin: 0 0.5rem; border: none; border-radius: 4px; cursor: pointer; /* transition: all 0.3s; */ transform: scale(1); transition: transform 0.1s ease; } .btn-inc { background-color: #4CAF50; color: white; } .btn-dec { background-color: #f44336; color: white; } .btn-reset { background-color: #2196F3; color: white; } .btn:hover { opacity: 0.8; } .btn:active { transform: scale(0.95); } .count-display { display: inline-block; } .count-enter-active, .count-leave-active { transition: all 0.3s ease; } .count-enter-from { opacity: 0; transform: translateY(-20px); } .count-leave-to { opacity: 0; transform: translateY(20px); } </style>
然后就是使用
<!-- src/App.vue --> <template> <div class="app"> <h1>Vue 计数器示例</h1> <!-- <Counter :initial-count="5"/> --> <Counter :initialCount="10" @count-change="handleCountChange" @reset="showResetAlert" /> <Counter2 :initialCount="2"/> </div> </template> <script setup> import { provide } from 'vue' import Counter from './components/Counter.vue' import Counter2 from './components/Counter2.vue' const handleCountChange = (payload) => { console.log('操作类型:', payload.type) console.log('当前值:', payload.value) } const showResetAlert = (payload) => { console.log('操作类型:', payload.type) console.log('当前值:', payload.value) alert('计数器已重置!') } //祖先配件 provide('counterConfig', { max: 100, min: 0, step: 1, theme: 'light' }) </script> <style> .app { font-family: Arial, sans-serif; text-align: center; padding: 20px; } h1 { color: #2c3e50; } </style>
一步步的来,最终的效果,是真的可以
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)