一、项目初始化
1.1 创建Vue3项目
npm init vue@latest cow-horse-clock
cd cow-horse-clock
npm install
1.2 添加小程序支持(以uni-app为例)
npm install @dcloudio/uni-app
![图片[1]_Vue3 牛马时钟小程序实现方案_知途无界](https://zhituwujie.com/wp-content/uploads/2025/09/d2b5ca33bd20250909085041.png)
二、核心组件实现
2.1 牛马时钟组件 (CowHorseClock.vue)
<template>
<div class="clock-container" :style="clockStyle">
<!-- 背景动物图案 -->
<div class="animal" :class="currentAnimal"></div>
<!-- 时钟主体 -->
<div class="clock-face">
<!-- 时针 -->
<div class="hand hour-hand" :style="hourHandStyle"></div>
<!-- 分针 -->
<div class="hand minute-hand" :style="minuteHandStyle"></div>
<!-- 秒针(牛尾巴) -->
<div class="hand second-hand" :style="secondHandStyle"></div>
<!-- 数字刻度 -->
<div v-for="n in 12" :key="n"
class="clock-number"
:style="getNumberPosition(n)">
{{ animalNumbers[n-1] }}
</div>
</div>
<!-- 动态语录 -->
<div class="quote">{{ currentQuote }}</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
// 动物类型数据
const animals = ['cow', 'horse']
const animalNumbers = ['🐄', '🐎', '🐄', '🐎', '🐄', '🐎', '🐄', '🐎', '🐄', '🐎', '🐄', '🐎']
const quotes = [
"牛马时间到!",
"摸鱼时间到!",
"该喝水了!",
"起来走走!",
"你的工位在召唤!",
"老板来了!"
]
// 响应式数据
const currentTime = ref(new Date())
const currentAnimal = ref(animals[0])
const currentQuote = ref(quotes[0])
// 计算属性
const hourHandStyle = computed(() => ({
transform: `rotate(${currentTime.value.getHours() * 30 + currentTime.value.getMinutes() * 0.5}deg)`
}))
const minuteHandStyle = computed(() => ({
transform: `rotate(${currentTime.value.getMinutes() * 6}deg)`
}))
const secondHandStyle = computed(() => ({
transform: `rotate(${currentTime.value.getSeconds() * 6}deg)`
}))
const clockStyle = computed(() => ({
backgroundColor: currentAnimal.value === 'cow' ? '#f5f5dc' : '#f0e6d2'
}))
// 方法
const getNumberPosition = (n) => {
const angle = (n * 30) * (Math.PI / 180)
const radius = 120
return {
left: `${150 + Math.sin(angle) * radius}px`,
top: `${150 - Math.cos(angle) * radius}px`
}
}
const updateClock = () => {
currentTime.value = new Date()
// 每小时切换动物
if (currentTime.value.getMinutes() === 0 && currentTime.value.getSeconds() === 0) {
currentAnimal.value = currentAnimal.value === 'cow' ? 'horse' : 'cow'
}
// 随机语录
if (currentTime.value.getSeconds() % 30 === 0) {
currentQuote.value = quotes[Math.floor(Math.random() * quotes.length)]
}
}
// 生命周期
onMounted(() => {
const timer = setInterval(updateClock, 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
</script>
<style scoped>
.clock-container {
width: 300px;
height: 300px;
border-radius: 50%;
position: relative;
margin: 0 auto;
background: #f5f5dc;
box-shadow: 0 0 20px rgba(0,0,0,0.2);
}
.animal {
position: absolute;
width: 100%;
height: 100%;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
opacity: 0.1;
z-index: 0;
}
.animal.cow {
background-image: url('https://xxx/cow.png');
}
.animal.horse {
background-image: url('https://xxx/horse.png');
}
.clock-face {
position: relative;
width: 100%;
height: 100%;
}
.hand {
position: absolute;
left: 50%;
bottom: 50%;
transform-origin: 50% 100%;
background: #333;
border-radius: 10px;
}
.hour-hand {
width: 6px;
height: 60px;
margin-left: -3px;
}
.minute-hand {
width: 4px;
height: 90px;
margin-left: -2px;
}
.second-hand {
width: 2px;
height: 100px;
margin-left: -1px;
background: red;
}
.clock-number {
position: absolute;
font-size: 24px;
transform: translate(-50%, -50%);
}
.quote {
position: absolute;
bottom: -40px;
width: 100%;
text-align: center;
font-size: 18px;
color: #666;
font-weight: bold;
}
</style>
三、小程序集成适配
3.1 修改为uni-app兼容代码
<!-- 修改template部分 -->
<template>
<view class="clock-container" :style="clockStyle">
<!-- 使用小程序兼容的图片标签 -->
<image class="animal"
:class="currentAnimal"
:src="currentAnimal === 'cow' ? '/static/cow.png' : '/static/horse.png'}"
mode="aspectFit"></image>
<!-- 其余代码保持不变 -->
<!-- ... -->
</view>
</template>
<script>
// 修改为uni-app的API调用
import { ref, computed, onMounted, onUnmounted } from 'vue'
export default {
setup() {
// ...原有逻辑保持不变...
onMounted(() => {
// 使用uni-app的定时器
timer = setInterval(updateClock, 1000)
})
onUnmounted(() => {
clearInterval(timer)
})
return {
// ...暴露需要的变量...
}
}
}
</script>
<style>
/* 修改单位为rpx */
.clock-container {
width: 600rpx;
height: 600rpx;
/* ... */
}
.hour-hand {
width: 12rpx;
height: 120rpx;
/* ... */
}
/* 其他样式单位也做相应转换 */
</style>
四、增强功能实现
4.1 添加交互功能
// 在setup()中添加
const isWorking = ref(true)
const workTime = ref(45) // 默认工作时间45分钟
const restTime = ref(5) // 默认休息时间5分钟
const timeLeft = ref(workTime.value * 60)
const toggleMode = () => {
isWorking.value = !isWorking.value
timeLeft.value = isWorking.value ? workTime.value * 60 : restTime.value * 60
}
// 修改updateClock函数
const updateClock = () => {
currentTime.value = new Date()
// 倒计时逻辑
timeLeft.value--
if (timeLeft.value <= 0) {
toggleMode()
currentQuote.value = isWorking.value ? "开始工作!" : "休息时间到!"
}
// ...原有逻辑...
}
// 暴露方法
return {
// ...原有暴露...
isWorking,
timeLeft,
toggleMode,
formatTime: computed(() => {
const mins = Math.floor(timeLeft.value / 60)
const secs = timeLeft.value % 60
return `${mins}:${secs < 10 ? '0' + secs : secs}`
})
}
4.2 添加控制面板
<template>
<!-- 在时钟下方添加 -->
<view class="control-panel">
<view class="mode-display" :class="{'work': isWorking, 'rest': !isWorking}">
{{ isWorking ? '工作模式' : '休息模式' }}: {{ formatTime }}
</view>
<button @click="toggleMode" class="mode-btn">
{{ isWorking ? '我要休息' : '开始工作' }}
</button>
<slider :value="workTime" @change="setWorkTime" min="5" max="120" show-value />
<text>工作时间(分钟): {{ workTime }}</text>
<slider :value="restTime" @change="setRestTime" min="1" max="30" show-value />
<text>休息时间(分钟): {{ restTime }}</text>
</view>
</template>
<script>
// 添加方法
const setWorkTime = (e) => {
workTime.value = e.detail.value
if (isWorking.value) {
timeLeft.value = workTime.value * 60
}
}
const setRestTime = (e) => {
restTime.value = e.detail.value
if (!isWorking.value) {
timeLeft.value = restTime.value * 60
}
}
</script>
<style>
.control-panel {
margin-top: 40px;
padding: 20px;
background: #f8f8f8;
border-radius: 10px;
}
.mode-display {
font-size: 20px;
font-weight: bold;
margin-bottom: 15px;
text-align: center;
}
.mode-display.work {
color: #e74c3c;
}
.mode-display.rest {
color: #2ecc71;
}
.mode-btn {
background-color: #3498db;
color: white;
margin: 10px 0;
}
slider {
width: 100%;
margin: 10px 0;
}
</style>
五、小程序配置与发布
5.1 manifest.json配置
{
"name": "牛马时钟",
"appid": "YOUR_APPID",
"description": "一个有趣的牛马主题时钟",
"versionName": "1.0.0",
"versionCode": 100,
"mp-weixin": {
"appid": "WX_APPID",
"setting": {
"urlCheck": false,
"es6": true,
"postcss": true,
"minified": true
},
"usingComponents": true
}
}
5.2 pages.json配置
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "牛马时钟",
"navigationBarBackgroundColor": "#f5f5dc",
"navigationBarTextStyle": "black"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "牛马时钟",
"navigationBarBackgroundColor": "#f5f5dc",
"backgroundColor": "#f5f5dc"
}
}
六、完整页面示例
6.1 pages/index/index.vue
<template>
<view class="page-container">
<CowHorseClock />
<!-- 添加主题切换按钮 -->
<view class="theme-switcher">
<button @click="switchTheme('light')" class="theme-btn light">浅色模式</button>
<button @click="switchTheme('dark')" class="theme-btn dark">深色模式</button>
</view>
<!-- 添加分享功能 -->
<button open-type="share" class="share-btn">分享牛马时钟</button>
</view>
</template>
<script setup>
import CowHorseClock from '@/components/CowHorseClock.vue'
import { ref } from 'vue'
const currentTheme = ref('light')
const switchTheme = (theme) => {
currentTheme.value = theme
uni.setNavigationBarColor({
frontColor: theme === 'dark' ? '#ffffff' : '#000000',
backgroundColor: theme === 'dark' ? '#222222' : '#f5f5dc'
})
}
// 分享功能
const onShareAppMessage = () => {
return {
title: '牛马时钟',
path: '/pages/index/index',
imageUrl: '/static/share.jpg'
}
}
</script>
<style>
.page-container {
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
}
.theme-switcher {
margin-top: 20px;
display: flex;
gap: 10px;
}
.theme-btn {
padding: 5px 10px;
border-radius: 5px;
}
.theme-btn.light {
background-color: #f5f5dc;
color: #333;
}
.theme-btn.dark {
background-color: #333;
color: #fff;
}
.share-btn {
margin-top: 20px;
background-color: #4CAF50;
color: white;
}
</style>
七、高级功能扩展
7.1 添加成就系统
// 在CowHorseClock.vue中添加
const achievements = ref([
{ id: 1, name: '牛马新人', desc: '首次使用时钟', earned: false },
{ id: 2, name: '工作狂魔', desc: '连续工作2小时', earned: false },
{ id: 3, name: '摸鱼大师', desc: '连续休息30分钟', earned: false }
])
const checkAchievements = () => {
// 检查成就逻辑
if (!achievements.value[0].earned) {
achievements.value[0].earned = true
showToast('获得成就: ' + achievements.value[0].name)
}
// 其他成就检查...
}
const showToast = (msg) => {
uni.showToast({
title: msg,
icon: 'none',
duration: 2000
})
}
7.2 添加数据统计
// 使用uniCloud进行数据统计
const recordUsage = () => {
const db = uniCloud.database()
db.collection('usage_stats').add({
timestamp: Date.now(),
action: isWorking.value ? 'work' : 'rest',
duration: isWorking.value ? workTime.value : restTime.value
})
}
// 在updateClock中调用
if (timeLeft.value % 60 === 0) {
recordUsage()
}
八、最终效果与发布
8.1 效果预览
graph TD
A[启动小程序] --> B[显示牛马时钟]
B --> C[自动开始计时]
C --> D[工作/休息模式切换]
D --> E[成就解锁]
E --> F[数据统计]
F --> G[主题切换]
G --> H[分享功能]
8.2 发布流程
- 准备素材:
- 牛/马图案图片(建议尺寸300×300)
- 分享卡片图片(建议尺寸5:4)
- 配置小程序:
npm run build:mp-weixin - 微信开发者工具:
- 导入项目目录下的
dist/dev/mp-weixin - 完成微信小程序后台配置
- 提交审核
- 导入项目目录下的
核心功能总结:
- 动态牛马主题时钟界面
- 工作/休息计时器功能
- 可配置的时间设置
- 主题切换与分享功能
- 成就系统与使用统计
优化建议:
- 添加更多动物主题选项
- 实现云同步配置功能
- 增加社交排行榜
- 开发AR实景牛马时钟
- 添加自定义语录功能
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容