Vue3 牛马时钟小程序实现方案

一、项目初始化

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 牛马时钟小程序实现方案_知途无界

二、核心组件实现

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 发布流程

  1. 准备素材​:
    • 牛/马图案图片(建议尺寸300×300)
    • 分享卡片图片(建议尺寸5:4)
  2. 配置小程序​: npm run build:mp-weixin
  3. 微信开发者工具​:
    • 导入项目目录下的dist/dev/mp-weixin
    • 完成微信小程序后台配置
    • 提交审核

核心功能总结​:

  1. 动态牛马主题时钟界面
  2. 工作/休息计时器功能
  3. 可配置的时间设置
  4. 主题切换与分享功能
  5. 成就系统与使用统计

优化建议​:

  1. 添加更多动物主题选项
  2. 实现云同步配置功能
  3. 增加社交排行榜
  4. 开发AR实景牛马时钟
  5. 添加自定义语录功能
© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞82 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容