北京成立公司咖啡seo是什么意思
了解组件基础概念:学习组件的定义、注册和使用方式。
组件间数据传递:完善并实现课本日历综合案例,要求使用vue3语法,按照组件应用方法编写程序。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue 3 日历组件</title><script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script><style>body {font-family: Arial, sans-serif;display: flex;justify-content: center;align-items: center;min-height: 100vh;margin: 0;background-color: #f5f5f5;}.calendar-container {width: 350px;background: white;border: 1px solid #ddd;border-radius: 8px;overflow: hidden;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);}.calendar-header {display: flex;justify-content: space-between;align-items: center;padding: 10px;background-color: #f5f5f5;border-bottom: 1px solid #ddd;}.calendar-header button {background: none;border: 1px solid #ddd;border-radius: 4px;padding: 5px 10px;cursor: pointer;transition: background-color 0.2s;}.calendar-header button:hover {background-color: #e0e0e0;}.calendar-weekdays {display: grid;grid-template-columns: repeat(7, 1fr);background-color: #f9f9f9;padding: 8px 0;text-align: center;font-weight: bold;} .calendar-days {display: grid;grid-template-columns: repeat(7, 1fr);gap: 4px;padding: 8px;} .day {height: 40px;display: flex;align-items: center;justify-content: center;border-radius: 4px;cursor: pointer;transition: all 0.2s;} .day:hover {background-color: #f0f0f0;} .current-month {background-color: white;}.day:not(.current-month) {color: #aaa;}.selected {background-color: #4285f4;color: white;}.selected:hover {background-color: #3367d6;}.today {font-weight: bold;border: 1px solid #4285f4;}.selected.today {border-color: white;}.selected-day {margin-top: 20px;text-align: center;font-size: 1.2em;}</style>
</head>
<body><div id="app"><calendar v-model="selectedDate"></calendar><div class="selected-day" v-if="selectedDate">已选择: {{ formatDate(selectedDate) }}</div></div><script>const { createApp, ref, computed } = Vue;const Calendar = {template: `<div class="calendar-container"><div class="calendar-header"><button @click="prevMonth"><</button><h2>{{ currentMonthYear }}</h2><button @click="nextMonth">></button></div><div class="calendar-weekdays"><div v-for="day in weekdays" :key="day" class="weekday">{{ day }}</div></div><div class="calendar-days"><div v-for="(day, index) in days" :key="index":class="{'day': true,'current-month': day.isCurrentMonth,'selected': isSelected(day.date),'today': isToday(day.date)}"@click="selectDate(day)">{{ day.date.getDate() }}</div></div></div>`,props: {modelValue: {type: Date,default: null}},emits: ['update:modelValue'],setup(props, { emit }) {const currentDate = ref(new Date());const selectedDate = ref(props.modelValue ? new Date(props.modelValue) : null);const weekdays = ['日', '一', '二', '三', '四', '五', '六'];const currentMonthYear = computed(() => {return `${currentDate.value.getFullYear()}年${currentDate.value.getMonth() + 1}月`;});const days = computed(() => {const year = currentDate.value.getFullYear();const month = currentDate.value.getMonth();// 当月第一天const firstDay = new Date(year, month, 1);// 当月最后一天const lastDay = new Date(year, month + 1, 0);// 上个月最后几天const prevLastDay = new Date(year, month, 0);// 下个月前几天const nextFirstDay = new Date(year, month + 1, 1);const days = [];// 添加上个月的最后几天const prevDays = firstDay.getDay();for (let i = prevDays > 0 ? prevDays - 1 : 6; i >= 0; i--) {days.push({date: new Date(year, month - 1, prevLastDay.getDate() - i),isCurrentMonth: false});}// 添加当月的所有天for (let i = 1; i <= lastDay.getDate(); i++) {days.push({date: new Date(year, month, i),isCurrentMonth: true});}// 添加下个月的前几天const nextDays = 7 - lastDay.getDay() - 1;for (let i = 1; i <= nextDays; i++) {days.push({date: new Date(year, month + 1, i),isCurrentMonth: false});}// 确保总是显示6行(42天)while (days.length < 42) {const lastDate = days[days.length - 1].date;days.push({date: new Date(lastDate.getFullYear(), lastDate.getMonth(), lastDate.getDate() + 1),isCurrentMonth: false});}return days;});const prevMonth = () => {currentDate.value = new Date(currentDate.value.getFullYear(),currentDate.value.getMonth() - 1,1);};const nextMonth = () => {currentDate.value = new Date(currentDate.value.getFullYear(),currentDate.value.getMonth() + 1,1);};const selectDate = (day) => {if (day.isCurrentMonth) {selectedDate.value = new Date(day.date);emit('update:modelValue', selectedDate.value);}};const isSelected = (date) => {if (!selectedDate.value) return false;return (date.getDate() === selectedDate.value.getDate() &&date.getMonth() === selectedDate.value.getMonth() &&date.getFullYear() === selectedDate.value.getFullYear());};const isToday = (date) => {const today = new Date();return (date.getDate() === today.getDate() &&date.getMonth() === today.getMonth() &&date.getFullYear() === today.getFullYear());};return {currentDate,selectedDate,weekdays,currentMonthYear,days,prevMonth,nextMonth,selectDate,isSelected,isToday};}};const app = createApp({components: {Calendar},setup() {const selectedDate = ref(null);const formatDate = (date) => {return date.toLocaleDateString('zh-CN', {year: 'numeric',month: 'long',day: 'numeric',weekday: 'long'});};return {selectedDate,formatDate};}});// app.component('Calendar', Calendar);app.mount('#app');</script>
</body>
</html>
运行结果如图: