Crafting a Vue.js 'Auntie Tigress' Tracker with Kiro
Creating a compelling application in Vue.js is now simpler with the help of Kiro. This article explores the development of a fun and interactive "Auntie Tigress" tracker, inspired by the classic Taiwanese folk tale. The app utilizes Vue 3 Composition API and a watercolor map to track a mythical creature approaching your location.
App Features
The application provides a real-time map that tracks a creature, such as a tiger, puppy, or ghost, creeping towards your home. It uses the browser's geolocation or defaults to Taipei for location tracking.
Key Components
- Vue 3 Composition API: Employs
<script setup>for concise component logic. - Leaflet Map Integration: Displays an interactive map, with creature tracking via composables.
- Icon Picker: Uses
definePropsanddefineEmitsfor selecting creature icons.
Understanding Composables
In the app, Kiro expertly handles state management with ref() and reactive().
- Geolocation: Uses
ref()for the position as it replaces the entire object during updates. - Creature State: Utilizes
reactive()for the creature's attributes like lat, lng, and icon, allowing for mutable state.
// useGeolocation.js
const position = ref({ lat: 25.033, lng: 121.565 })
watchId = navigator.geolocation.watchPosition(
(pos) => {
position.value = { lat: pos.coords.latitude, lng: pos.coords.longitude }
},
(err) => { error.value = err.message },
{ enableHighAccuracy: true, timeout: 10000 }
)
// useCreatureTracker.js
const creature = reactive({ lat: 0, lng: 0, icon: '🐯', name: 'Auntie Tigress' })
Props and Emits
The app follows classic Vue patterns for data flow, leveraging defineProps and defineEmits for the icon picker component.
<script setup>
const props = defineProps({
options: { type: Array, required: true },
selected: { type: String, required: true },
})
const emit = defineEmits(['select'])
</script>
<template>
<button
v-for="opt in options"
:key="opt.id"
:class="{ active: selected === opt.icon }"
@click="emit('select', opt.id)"
>
{{ opt.icon }} {{ opt.name }}
</button>
</template>
Leveraging Computed Properties
The map component demonstrates the power of computed properties, creating a chain of reactivity from distance calculations to danger level assessments.
const distanceMeters = computed(() => {
// haversine formula
return Math.round(2 * R * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)))
})
const distanceLabel = computed(() =>
distanceMeters.value > 1000
? (distanceMeters.value / 1000).toFixed(1) + ' km'
: distanceMeters.value + ' m'
)
const dangerLevel = computed(() => {
const d = distanceMeters.value
if (d < 300) return { text: 'GO TO SLEEP NOW! 😱', color: '#ff4444' }
if (d < 600) return { text: 'Getting close… 😰', color: '#ff8844' }
if (d < 1000) return { text: 'Nearby… stay alert 😟', color: '#ffaa44' }
return { text: 'Safe… for now 😌', color: '#88cc66' }
})
Integrating Vue with Leaflet
Kiro effectively bridges Vue's reactivity with Leaflet's imperative API, ensuring both markers are visible and responsive.
watch(() => props.creature, (c) => {
creatureMarker?.setLatLng([c.lat, c.lng])
creatureMarker?.setIcon(emojiIcon(c.icon, 38))
creatureMarker?.setTooltipContent(c.name)
}, { deep: true })
Conclusion
Kiro adeptly applies Vue 3 patterns, making the development process seamless and intuitive. Whether you are a seasoned developer or new to Vue.js, building an app like the "Auntie Tigress" tracker is a rewarding experience.
Explore the possibilities with Kiro and Vue 3 today. Your creativity is the limit!