fix
fix CustomPoem
This commit is contained in:
		
							parent
							
								
									07d748cb0a
								
							
						
					
					
						commit
						627384bfb9
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -28,3 +28,4 @@ coverage | ||||
| *.sw? | ||||
| 
 | ||||
| *.tsbuildinfo | ||||
| /package-lock.json | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| <script setup> | ||||
| import { RouterLink, RouterView } from 'vue-router' | ||||
| import HelloWorld from './components/HelloWorld.vue' | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
| @ -8,8 +7,6 @@ import HelloWorld from './components/HelloWorld.vue' | ||||
|     <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" /> | ||||
| 
 | ||||
|     <div class="wrapper"> | ||||
|       <HelloWorld msg="You did it!" /> | ||||
| 
 | ||||
|       <nav> | ||||
|         <RouterLink to="/">Home</RouterLink> | ||||
|         <RouterLink to="/about">About</RouterLink> | ||||
|  | ||||
| @ -28,8 +28,6 @@ a, | ||||
|   } | ||||
| 
 | ||||
|   #app { | ||||
|     display: grid; | ||||
|     grid-template-columns: 1fr 1fr; | ||||
|     padding: 0 2rem; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -1,76 +1,74 @@ | ||||
| <script> | ||||
| import { defineComponent } from 'vue'; | ||||
| import Post from '../utils/Post.js'; | ||||
| import { defineComponent } from 'vue' | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|     props: { | ||||
|         post: { type: Post, required: true }, | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
|             childPost: {} | ||||
|         }; | ||||
|     }, | ||||
|     created() { | ||||
|         this.childPost = this.post; | ||||
|     }, | ||||
| }); | ||||
|   props: { | ||||
|     post: { type: null, required: true } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       childPost: {} | ||||
|     } | ||||
|   }, | ||||
|   created() { | ||||
|     this.childPost = this.post | ||||
|   } | ||||
| }) | ||||
| </script> | ||||
| <template> | ||||
|     <div class="card"> | ||||
|         <div class="title"> | ||||
|             <h2>{{ childPost.title }}</h2> | ||||
|         </div> | ||||
| 
 | ||||
|         <div class="content"> | ||||
|             <p>{{ childPost.content }}</p> | ||||
|         </div> | ||||
|   <div class="card"> | ||||
|     <div class="title"> | ||||
|       <h2>{{ childPost.title }}</h2> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="content"> | ||||
|       <p>{{ childPost.content }}</p> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| .card { | ||||
|     box-sizing: border-box; | ||||
|     box-shadow: 0 0 10px 0 rgba(0, 0, 0, .24); | ||||
|     border-radius: 4px; | ||||
|     padding: 8px; | ||||
|     cursor: pointer; | ||||
|     margin: 10px 0; | ||||
|     /* height: 100px; */ | ||||
|   box-sizing: border-box; | ||||
|   box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.24); | ||||
|   border-radius: 4px; | ||||
|   padding: 8px; | ||||
|   cursor: pointer; | ||||
|   margin: 10px 0; | ||||
|   /* height: 100px; */ | ||||
| } | ||||
| 
 | ||||
| .card .title { | ||||
|     /* height: 24px; */ | ||||
|     line-height: 24px; | ||||
|     /* margin-bottom: 4px; */ | ||||
|     padding-bottom: 4px; | ||||
|     border-bottom: 1px solid rgba(0, 0, 0, .24); | ||||
|   /* height: 24px; */ | ||||
|   line-height: 24px; | ||||
|   /* margin-bottom: 4px; */ | ||||
|   padding-bottom: 4px; | ||||
|   border-bottom: 1px solid rgba(0, 0, 0, 0.24); | ||||
| } | ||||
| 
 | ||||
| .card .title:hover { | ||||
|     color: burlywood; | ||||
|   color: burlywood; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| .card .content { | ||||
|     padding: 4px; | ||||
|     /* height: 100%; */ | ||||
|     /* max-height: calc(100% - 36px); */ | ||||
|   padding: 4px; | ||||
|   /* height: 100%; */ | ||||
|   /* max-height: calc(100% - 36px); */ | ||||
| } | ||||
| 
 | ||||
| .card .content p { | ||||
|     /* 单行显示 */ | ||||
|     text-overflow: ellipsis; | ||||
|     overflow: hidden; | ||||
|     word-break: break-all; | ||||
|     white-space: nowrap; | ||||
|     /* 多行显示 */ | ||||
|     /* word-break: break-all; | ||||
|   /* 单行显示 */ | ||||
|   text-overflow: ellipsis; | ||||
|   overflow: hidden; | ||||
|   word-break: break-all; | ||||
|   white-space: nowrap; | ||||
|   /* 多行显示 */ | ||||
|   /* word-break: break-all; | ||||
|     overflow: hidden; | ||||
|     display: -webkit-box; | ||||
|     -webkit-line-clamp: 2; | ||||
|     -webkit-box-orient: vertical; */ | ||||
|     /*  */ | ||||
|     /* height: 100%; */ | ||||
|   /*  */ | ||||
|   /* height: 100%; */ | ||||
| } | ||||
| </style> | ||||
| @ -1,21 +1,19 @@ | ||||
| 
 | ||||
| 
 | ||||
| const weekDayNumber = 7; | ||||
| const week_zh_cn = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]; | ||||
| const week_en_us = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]; | ||||
| const weekDayNumber = 7 | ||||
| const week_zh_cn = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'] | ||||
| const week_en_us = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'] | ||||
| 
 | ||||
| class Day { | ||||
|     constructor(year, month, day, content, isCurrentMonth = false, isCurrentDay = false) { | ||||
|         this.year = year; | ||||
|         this.month = month; | ||||
|         this.day = day; | ||||
|         this.content = content; | ||||
|         this.isCurrentMonth = isCurrentMonth; | ||||
|         this.isCurrentDay = isCurrentDay | ||||
|     } | ||||
|   constructor(year, month, day, content, isCurrentMonth = false, isCurrentDay = false) { | ||||
|     this.year = year | ||||
|     this.month = month | ||||
|     this.day = day | ||||
|     this.content = content | ||||
|     this.isCurrentMonth = isCurrentMonth | ||||
|     this.isCurrentDay = isCurrentDay | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| const defaultDate = new Date(); | ||||
| const defaultDate = new Date() | ||||
| const defaultYear = defaultDate.getFullYear() | ||||
| const defaultMonth = defaultDate.getMonth() | ||||
| const defaultDay = defaultDate.getDate() | ||||
| @ -28,54 +26,48 @@ const defaultDay = defaultDate.getDate() | ||||
|  * @param {number} [day = defaultDay] | ||||
|  * @returns {[Day]} | ||||
|  */ | ||||
| function initDay(currentDays = new Array(42), year = defaultYear, month = defaultMonth, day = defaultDay) { | ||||
| function initDay( | ||||
|   currentDays = new Array(42), | ||||
|   year = defaultYear, | ||||
|   month = defaultMonth, | ||||
|   day = defaultDay | ||||
| ) { | ||||
|   if (!Array.isArray(currentDays)) { | ||||
|     currentDays = new Array(42) | ||||
|   } else if (currentDays.length !== 42) { | ||||
|     console.log(currentDays) | ||||
|     throw new Error('currentDays:' + currentDays) | ||||
|   } else { | ||||
|     currentDays = [...currentDays] | ||||
|   } | ||||
| 
 | ||||
|     if (!Array.isArray(currentDays)) { | ||||
|         currentDays = new Array(42); | ||||
|     } else if (currentDays.length != 42) { | ||||
|         console.log(currentDays); | ||||
|         throw new Error(currentDays) | ||||
|     } else { | ||||
|         currentDays = [...currentDays]; | ||||
|   const days = currentDays | ||||
|   const lastDayOfLastMonth = new Date(year, month, 0) | ||||
|   const firstDayOfMonth = new Date(year, month, 1) | ||||
|   const lastDayOfMonth = new Date(year, month + 1, 0) | ||||
|   const currentDaysOfMonth = lastDayOfMonth.getDate() | ||||
|   const daysOfLastMonth = lastDayOfLastMonth.getDate() | ||||
| 
 | ||||
|   for (let i = 0; i < firstDayOfMonth.getDay(); i++) { | ||||
|     const weekDay = firstDayOfMonth.getDay() - 1 | ||||
|     days[i] = new Day(year, month - 1, daysOfLastMonth - weekDay + i, week_zh_cn[i]) | ||||
|   } | ||||
| 
 | ||||
|   for (let i = 0; i < currentDaysOfMonth; i++) { | ||||
|     const weekDay = (firstDayOfMonth.getDay() + i) % weekDayNumber | ||||
|     days[firstDayOfMonth.getDay() + i] = new Day(year, month, i + 1, week_zh_cn[weekDay], true) | ||||
|     if (i === day - 1) { | ||||
|       days[firstDayOfMonth.getDay() + i].isCurrentDay = true | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|     const days = currentDays; | ||||
|     const lastDayOfLastMonth = new Date(year, month, 0); | ||||
|     const firstDayOfMonth = new Date(year, month, 1); | ||||
|     const lastDayOfMonth = new Date(year, month + 1, 0); | ||||
|     const currentDaysOfMonth = lastDayOfMonth.getDate(); | ||||
|     const daysOfLastMonth = lastDayOfLastMonth.getDate(); | ||||
|   for (let i = currentDaysOfMonth + firstDayOfMonth.getDay(); i < days.length; i++) { | ||||
|     const extraDay = i - currentDaysOfMonth - firstDayOfMonth.getDay() + 1 | ||||
|     const weekDay = i % weekDayNumber | ||||
|     days[i] = new Day(year, month + 1, extraDay, week_zh_cn[weekDay]) | ||||
|   } | ||||
| 
 | ||||
|     for (let i = 0; i < firstDayOfMonth.getDay(); i++) { | ||||
|         const weekDay = firstDayOfMonth.getDay() - 1; | ||||
|         days[i] = new Day(year, month - 1, daysOfLastMonth - weekDay + i, week_zh_cn[i]); | ||||
|     } | ||||
| 
 | ||||
|     for (let i = 0; i < currentDaysOfMonth; i++) { | ||||
|         const weekDay = (firstDayOfMonth.getDay() + i) % weekDayNumber; | ||||
|         days[firstDayOfMonth.getDay() + i] = new Day(year, month, i + 1, week_zh_cn[weekDay], true); | ||||
|         if (i === day - 1) { | ||||
|             days[firstDayOfMonth.getDay() + i].isCurrentDay = true; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     for (let i = currentDaysOfMonth + firstDayOfMonth.getDay(); i < days.length; i++) { | ||||
|         const extraDay = i - currentDaysOfMonth - firstDayOfMonth.getDay() + 1; | ||||
|         const weekDay = i % weekDayNumber; | ||||
|         days[i] = new Day(year, month + 1, extraDay, week_zh_cn[weekDay]); | ||||
|     } | ||||
| 
 | ||||
|     return currentDays; | ||||
|   return currentDays | ||||
| } | ||||
| 
 | ||||
| export { week_zh_cn, week_en_us, defaultYear, defaultMonth, defaultDay, initDay }; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| export { week_zh_cn, week_en_us, defaultYear, defaultMonth, defaultDay, initDay } | ||||
|  | ||||
| @ -14,11 +14,21 @@ const day = ref(defaultDay) | ||||
| 
 | ||||
| const editMonth = { | ||||
|   add: () => { | ||||
|     month.value >= 11 ? ((month.value = 0), (year.value += 1)) : (month.value += 1) | ||||
|     if (month.value >= 11) { | ||||
|       month.value = 0 | ||||
|       year.value += 1 | ||||
|     } else { | ||||
|       month.value += 1 | ||||
|     } | ||||
|     dayArray.value = initDay(dayArray.value, year.value, month.value, day.value) | ||||
|   }, | ||||
|   sub: () => { | ||||
|     month.value <= 0 ? ((month.value = 11), (year.value -= 1)) : (month.value -= 1) | ||||
|     if (month.value <= 0) { | ||||
|       month.value = 11 | ||||
|       year.value -= 1 | ||||
|     } else { | ||||
|       month.value -= 1 | ||||
|     } | ||||
|     dayArray.value = initDay(dayArray.value, year.value, month.value, day.value) | ||||
|   } | ||||
| } | ||||
| @ -73,8 +83,10 @@ const handleDayClick = (date) => { | ||||
|     justify-content: space-around; | ||||
|     width: 100%; | ||||
|   } | ||||
| 
 | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| #calendar .title { | ||||
|   > button { | ||||
|     height: 20px; | ||||
| @ -89,6 +101,7 @@ const handleDayClick = (date) => { | ||||
| .content { | ||||
|   display: grid; | ||||
|   grid-template-columns: repeat(7, 1fr); | ||||
| 
 | ||||
|   > div { | ||||
|     outline: 1px solid; | ||||
|     display: flex; | ||||
| @ -103,6 +116,7 @@ const handleDayClick = (date) => { | ||||
|   #calendar { | ||||
|     width: 280px; | ||||
|   } | ||||
| 
 | ||||
|   .content { | ||||
|     height: 240px; | ||||
|   } | ||||
| @ -112,6 +126,7 @@ const handleDayClick = (date) => { | ||||
|   #calendar { | ||||
|     max-width: 350px; | ||||
|   } | ||||
| 
 | ||||
|   .content { | ||||
|     height: 300px; | ||||
|   } | ||||
|  | ||||
| @ -1,83 +1,83 @@ | ||||
| <script> | ||||
| import { defineComponent } from 'vue'; | ||||
| <script setup> | ||||
| import { reactive } from 'vue' | ||||
| const poem = reactive({ | ||||
|   title: '雨霖铃·寒蝉凄切', | ||||
|   body: [ | ||||
|     '寒蝉凄切,对长亭晚,骤雨初歇。', | ||||
|     '都门帐饮无绪,留恋处,兰舟催发。', | ||||
|     '执手相看泪眼,竟无语凝噎。', | ||||
|     '念去去,千里烟波,暮霭沉沉楚天阔。', | ||||
|     '多情自古伤离别,更那堪,冷落清秋节!', | ||||
|     '今宵酒醒何处?杨柳岸,晓风残月。', | ||||
|     '此去经年,应是良辰好景虚设。', | ||||
|     '便纵有千种风情,更与何人说?' | ||||
|   ] | ||||
| }) | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|     props: { | ||||
|         poemTitle: { | ||||
|             type: String, | ||||
|             default: '雨霖铃·寒蝉凄切' | ||||
|         }, | ||||
|         poemBody: { | ||||
|             type: Array, | ||||
|             default: () => [ | ||||
|                 '寒蝉凄切,对长亭晚,骤雨初歇。', | ||||
|                 '都门帐饮无绪,留恋处,兰舟催发。', | ||||
|                 '执手相看泪眼,竟无语凝噎。', | ||||
|                 '念去去,千里烟波,暮霭沉沉楚天阔。', | ||||
|                 '多情自古伤离别,更那堪,冷落清秋节!', | ||||
|                 '今宵酒醒何处?杨柳岸,晓风残月。', | ||||
|                 '此去经年,应是良辰好景虚设。', | ||||
|                 '便纵有千种风情,更与何人说?' | ||||
|             ], | ||||
|         } | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
| 
 | ||||
|         }; | ||||
|     }, | ||||
| }); | ||||
| console.log(poem.body) | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <div class="poem"> | ||||
|         <h2 class="poem-title"> | ||||
|             {{ this.poemTitle }} | ||||
|         </h2> | ||||
|         <ul class="poem-body"> | ||||
|             <li v-for="{poem, index} in this.poemBody" :key="index"> | ||||
|                 {{ poem }} | ||||
|             </li> | ||||
|         </ul> | ||||
|     </div> | ||||
|   <div class="poem"> | ||||
|     <h2 class="poem_title">{{ poem.title }}</h2> | ||||
|     <ul class="poem_body"> | ||||
|       <li v-for="(line, index) in poem.body" :key="index"> | ||||
|         <span | ||||
|           v-for="(char, charIndex) in line.split('')" | ||||
|           :key="charIndex" | ||||
|           :style="{ animationDelay: charIndex * 0.1 + 's' }" | ||||
|           >{{ char }}</span | ||||
|         > | ||||
|       </li> | ||||
|     </ul> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| * { | ||||
|     /* box-sizing: border-box; */ | ||||
|     font-family: 'Ma Shan Zheng', cursive; | ||||
|     margin: 0; | ||||
|     padding: 0; | ||||
|     color: #000; | ||||
|   box-sizing: border-box; | ||||
|   font-family: 'Ma Shan Zheng', cursive; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   color: #000; | ||||
| } | ||||
| 
 | ||||
| ol, | ||||
| ul { | ||||
|     list-style: none; | ||||
|   list-style: none; | ||||
| } | ||||
| 
 | ||||
| .poem { | ||||
|     width: 280px; | ||||
|     border-radius: 4px; | ||||
|     box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); | ||||
| } | ||||
| 
 | ||||
| .poem-title { | ||||
|     text-align: center; | ||||
|   width: 280px; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 0 10px rgba(0, 0, 0, 0.4); | ||||
|   text-align: center; | ||||
|   > .poem_title { | ||||
|     white-space: nowrap; | ||||
|     padding-top: 10px; | ||||
|     font-size: 24px; | ||||
|     width: 100%; | ||||
| } | ||||
| 
 | ||||
| .poem-body { | ||||
|   } | ||||
|   > .poem_body { | ||||
|     text-align: center; | ||||
|     white-space: nowrap; | ||||
|     font-size: 16px; | ||||
|     padding: 10px 0; | ||||
| 
 | ||||
|     >li { | ||||
|         margin: 5px auto; | ||||
|     > li { | ||||
|       margin: 5px auto; | ||||
|     } | ||||
| 
 | ||||
|     > li span { | ||||
|       opacity: 0; | ||||
|       animation: fadeIn 1s forwards; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| @keyframes fadeIn { | ||||
|   to { | ||||
|     opacity: 1; | ||||
|   } | ||||
| } | ||||
| </style> | ||||
| @ -1,23 +0,0 @@ | ||||
| <script> | ||||
| import { defineComponent } from 'vue'; | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|     props: { | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
| 
 | ||||
|         }; | ||||
|     }, | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <div> | ||||
|         PersonInfoHHHHH | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| @ -1,36 +1,36 @@ | ||||
| <script> | ||||
| import { defineComponent } from "vue"; | ||||
| import { defineComponent } from 'vue' | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|     data() { | ||||
|         return { | ||||
|             test: '' | ||||
|         } | ||||
|     }, | ||||
|     methods: { | ||||
|         testapi() { | ||||
|             fetch("http://127.0.0.1:3000/user") | ||||
|                 .then(res => res.json()) | ||||
|                 .then(data => { | ||||
|                     this.test = data; | ||||
|                 }) | ||||
|                 .catch(err => console.log('Request Failed', err)) | ||||
|         } | ||||
|   data() { | ||||
|     return { | ||||
|       test: '' | ||||
|     } | ||||
| }); | ||||
|   }, | ||||
|   methods: { | ||||
|     testapi() { | ||||
|       fetch('http://127.0.0.1:3000/user') | ||||
|         .then((res) => res.json()) | ||||
|         .then((data) => { | ||||
|           this.test = data | ||||
|         }) | ||||
|         .catch((err) => console.log('Request Failed', err)) | ||||
|     } | ||||
|   } | ||||
| }) | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <button @click="testapi">测试接口调用</button> | ||||
|     <p v-if="this.test != ''"> | ||||
|         {{ this.test[0].name }}<br> | ||||
|         {{ this.test[0].birth }}<br> | ||||
|         {{ this.test[0].gender }}<br> | ||||
|         {{ this.test[0].name }}<br> | ||||
|         {{ this.test[0].password }}<br> | ||||
|         {{ this.test[0].register_date }}<br> | ||||
|         {{ this.test[0].status }}<br> | ||||
|     </p> | ||||
|   <button @click="testapi">测试接口调用</button> | ||||
|   <p v-if="this.test != ''"> | ||||
|     {{ this.test[0].name }}<br /> | ||||
|     {{ this.test[0].birth }}<br /> | ||||
|     {{ this.test[0].gender }}<br /> | ||||
|     {{ this.test[0].name }}<br /> | ||||
|     {{ this.test[0].password }}<br /> | ||||
|     {{ this.test[0].register_date }}<br /> | ||||
|     {{ this.test[0].status }}<br /> | ||||
|   </p> | ||||
| </template> | ||||
| 
 | ||||
| <style></style> | ||||
| @ -1,340 +1,346 @@ | ||||
| <script> | ||||
| import { defineComponent } from 'vue'; | ||||
| import { defineComponent } from 'vue' | ||||
| 
 | ||||
| export default defineComponent({ | ||||
|     props: { | ||||
|         welcome: { | ||||
|             type: String, | ||||
|             default: '你好', | ||||
|         }, | ||||
|         url: { | ||||
|             type: String, | ||||
|             default: 'http://127.0.0.1:3000/login', | ||||
|         }, | ||||
|   props: { | ||||
|     welcome: { | ||||
|       type: String, | ||||
|       default: '你好' | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
|             showAccountError: false, | ||||
|             showPasswordError: false, | ||||
|             accountAbove: false, | ||||
|             passwordAbove: false, | ||||
|             accountShow: true, | ||||
|             passwordShow: true, | ||||
|             account: '', | ||||
|             password: '', | ||||
|         }; | ||||
|     }, | ||||
|     watch: { | ||||
|         account(val) { | ||||
|             val.length > 0 ? (this.showAccountError = false, this.accountShow = false) : | ||||
|                 (this.showAccountError = false, this.accountShow = false); | ||||
|         }, | ||||
|         password(val) { | ||||
|             val.length > 0 ? (this.showPasswordError = false, this.passwordShow = false) : | ||||
|                 (this.showPasswordError = false, this.passwordShow = false); | ||||
|         }, | ||||
|     }, | ||||
|     methods: { | ||||
|         accountFocus() { | ||||
|             if (this.account.length <= 0) { | ||||
|                 this.accountShow = true; | ||||
|                 this.accountAbove = true; | ||||
|                 this.showAccountError = true; | ||||
|             } | ||||
|         }, | ||||
|         accountBlur() { | ||||
|             if (this.account.length <= 0) { | ||||
|                 this.accountShow = false; | ||||
|                 this.accountAbove = false; | ||||
|                 this.showAccountError = false; | ||||
|             } | ||||
|         }, | ||||
|         passwordFocus() { | ||||
|             if (this.password.length <= 0) { | ||||
|                 this.passwordShow = true; | ||||
|                 this.passwordAbove = true; | ||||
|                 this.showPasswordError = true; | ||||
|             } | ||||
|         }, | ||||
|         passwordBlur() { | ||||
|             if (this.password.length <= 0) { | ||||
|                 this.passwordShow = false; | ||||
|                 this.passwordAbove = false; | ||||
|                 this.showPasswordError = false; | ||||
|             } | ||||
|         }, | ||||
|         async login() { | ||||
|             const payload = { | ||||
|                 account: this.account, | ||||
|                 password: this.password | ||||
|             }; | ||||
|             try { | ||||
|                 console.log(this.url); | ||||
|                 const response = await fetch(this.url, { | ||||
|                     method: "POST", | ||||
|                     mode: "cors", | ||||
|                     cache: "default", | ||||
|                     headers: { | ||||
|                         'Content-Type': 'application/json; charset=utf-8' | ||||
|                     }, | ||||
|                     credentials: 'include', | ||||
|                     body: JSON.stringify(payload) | ||||
|                 }); | ||||
|                 const data = await response.json(); | ||||
|                 console.log(data); | ||||
|             } catch (err) { | ||||
|                 console.error(err); | ||||
|             } | ||||
|         } | ||||
|     url: { | ||||
|       type: String, | ||||
|       default: 'http://127.0.0.1:3000/login' | ||||
|     } | ||||
|   }, | ||||
|   data() { | ||||
|     return { | ||||
|       showAccountError: false, | ||||
|       showPasswordError: false, | ||||
|       accountAbove: false, | ||||
|       passwordAbove: false, | ||||
|       accountShow: true, | ||||
|       passwordShow: true, | ||||
|       account: '', | ||||
|       password: '' | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     account(val) { | ||||
|       if (val.length > 0) { | ||||
|         this.showAccountError = false | ||||
|         this.accountShow = false | ||||
|       } else { | ||||
|         this.showAccountError = false | ||||
|         this.accountShow = false | ||||
|       } | ||||
|     }, | ||||
|     password(val) { | ||||
|       if (val.length > 0) { | ||||
|         this.showPasswordError = false | ||||
|         this.passwordShow = false | ||||
|       } else { | ||||
|         this.showPasswordError = false | ||||
|         this.passwordShow = false | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     accountFocus() { | ||||
|       if (this.account.length <= 0) { | ||||
|         this.accountShow = true | ||||
|         this.accountAbove = true | ||||
|         this.showAccountError = true | ||||
|       } | ||||
|     }, | ||||
|     accountBlur() { | ||||
|       if (this.account.length <= 0) { | ||||
|         this.accountShow = false | ||||
|         this.accountAbove = false | ||||
|         this.showAccountError = false | ||||
|       } | ||||
|     }, | ||||
|     passwordFocus() { | ||||
|       if (this.password.length <= 0) { | ||||
|         this.passwordShow = true | ||||
|         this.passwordAbove = true | ||||
|         this.showPasswordError = true | ||||
|       } | ||||
|     }, | ||||
|     passwordBlur() { | ||||
|       if (this.password.length <= 0) { | ||||
|         this.passwordShow = false | ||||
|         this.passwordAbove = false | ||||
|         this.showPasswordError = false | ||||
|       } | ||||
|     }, | ||||
|     async login() { | ||||
|       const payload = { | ||||
|         account: this.account, | ||||
|         password: this.password | ||||
|       } | ||||
|       try { | ||||
|         console.log(this.url) | ||||
|         const response = await fetch(this.url, { | ||||
|           method: 'POST', | ||||
|           mode: 'cors', | ||||
|           cache: 'default', | ||||
|           headers: { | ||||
|             'Content-Type': 'application/json; charset=utf-8' | ||||
|           }, | ||||
|           credentials: 'include', | ||||
|           body: JSON.stringify(payload) | ||||
|         }) | ||||
|         const data = await response.json() | ||||
|         console.log(data) | ||||
|       } catch (err) { | ||||
|         console.error(err) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }) | ||||
| </script> | ||||
| <template> | ||||
|     <div class="login-from"> | ||||
|         <p class="title">{{ welcome }}</p> | ||||
|         <form @submit.prevent="login"> | ||||
|             <div class="account"> | ||||
|                 <div class="form-field" :class="{ 'form-field-error': showAccountError }"> | ||||
|                     <div class="form-control"> | ||||
|                         <div> | ||||
|                             <input | ||||
|                                 v-model="account" | ||||
|                                 @focus="accountFocus" | ||||
|                                 @blur="accountBlur" | ||||
|                                 class="account-input" | ||||
|                                 type="text" | ||||
|                                 name="account" | ||||
|                                 id="account" | ||||
|                                 autocomplete="off" | ||||
|                                 required | ||||
|                             /> | ||||
|                             <label | ||||
|                                 class="floating-label" | ||||
|                                 :class="{ 'floating-label-above': accountAbove, 'floating-label-error': showAccountError }" | ||||
|                                 for="account" | ||||
|                                 >邮箱/手机号码</label | ||||
|                             > | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div v-if="showAccountError" class="floating-label-error">请输入账号</div> | ||||
|   <div class="login-from"> | ||||
|     <p class="title">{{ welcome }}</p> | ||||
|     <form @submit.prevent="login"> | ||||
|       <div class="account"> | ||||
|         <div class="form-field" :class="{ 'form-field-error': showAccountError }"> | ||||
|           <div class="form-control"> | ||||
|             <div> | ||||
|               <input | ||||
|                 v-model="account" | ||||
|                 @focus="accountFocus" | ||||
|                 @blur="accountBlur" | ||||
|                 class="account-input" | ||||
|                 type="text" | ||||
|                 name="account" | ||||
|                 id="account" | ||||
|                 autocomplete="off" | ||||
|                 required | ||||
|               /> | ||||
|               <label | ||||
|                 class="floating-label" | ||||
|                 :class="{ | ||||
|                   'floating-label-above': accountAbove, | ||||
|                   'floating-label-error': showAccountError | ||||
|                 }" | ||||
|                 for="account" | ||||
|                 >邮箱/手机号码</label | ||||
|               > | ||||
|             </div> | ||||
|             <div class="password"> | ||||
|                 <div class="form-field" :class="{ 'form-field-error': showPasswordError }"> | ||||
|                     <div class="form-control"> | ||||
|                         <div> | ||||
|                             <input | ||||
|                                 v-model="password" | ||||
|                                 @focus="passwordFocus" | ||||
|                                 @blur="passwordBlur" | ||||
|                                 class="password-input" | ||||
|                                 type="password" | ||||
|                                 name="password" | ||||
|                                 id="password" | ||||
|                                 autocomplete="off" | ||||
|                                 required | ||||
|                             /> | ||||
|                             <label | ||||
|                                 class="floating-label" | ||||
|                                 :class="{ 'floating-label-above': passwordAbove, 'floating-label-error': showPasswordError }" | ||||
|                                 for="password" | ||||
|                                 >密码</label | ||||
|                             > | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div v-if="showPasswordError" class="floating-label-error">请输入密码</div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div v-if="showAccountError" class="floating-label-error">请输入账号</div> | ||||
|       </div> | ||||
|       <div class="password"> | ||||
|         <div class="form-field" :class="{ 'form-field-error': showPasswordError }"> | ||||
|           <div class="form-control"> | ||||
|             <div> | ||||
|               <input | ||||
|                 v-model="password" | ||||
|                 @focus="passwordFocus" | ||||
|                 @blur="passwordBlur" | ||||
|                 class="password-input" | ||||
|                 type="password" | ||||
|                 name="password" | ||||
|                 id="password" | ||||
|                 autocomplete="off" | ||||
|                 required | ||||
|               /> | ||||
|               <label | ||||
|                 class="floating-label" | ||||
|                 :class="{ | ||||
|                   'floating-label-above': passwordAbove, | ||||
|                   'floating-label-error': showPasswordError | ||||
|                 }" | ||||
|                 for="password" | ||||
|                 >密码</label | ||||
|               > | ||||
|             </div> | ||||
|             <div class="accept-terms"> | ||||
|                 <label for="agreement" class="accept"> | ||||
|                     <span class="agreement-checkbox"> | ||||
|                         <input | ||||
|                             class="accept-checkbox-input" | ||||
|                             type="checkbox" | ||||
|                             name="agreement" | ||||
|                             id="agreement" | ||||
|                         /> | ||||
|                         <span class="agreement-inner"></span> | ||||
|                     </span> | ||||
|                     <span class="accept-text" | ||||
|                         >已阅读并同意小米账号<span>用户协议</span><span>隐私政策</span></span | ||||
|                     > | ||||
|                 </label> | ||||
|             </div> | ||||
|             <button class="login-button" type="submit">登录</button> | ||||
|             <div class="form-action"> | ||||
|                 <div class="form-action-start">忘记密码?</div> | ||||
|                 <div class="form-action-end">手机号登录</div> | ||||
|             </div> | ||||
|         </form> | ||||
|     </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div v-if="showPasswordError" class="floating-label-error">请输入密码</div> | ||||
|       </div> | ||||
|       <div class="accept-terms"> | ||||
|         <label for="agreement" class="accept"> | ||||
|           <span class="agreement-checkbox"> | ||||
|             <input class="accept-checkbox-input" type="checkbox" name="agreement" id="agreement" /> | ||||
|             <span class="agreement-inner"></span> | ||||
|           </span> | ||||
|           <span class="accept-text" | ||||
|             >已阅读并同意小米账号<span>用户协议</span><span>隐私政策</span></span | ||||
|           > | ||||
|         </label> | ||||
|       </div> | ||||
|       <button class="login-button" type="submit">登录</button> | ||||
|       <div class="form-action"> | ||||
|         <div class="form-action-start">忘记密码?</div> | ||||
|         <div class="form-action-end">手机号登录</div> | ||||
|       </div> | ||||
|     </form> | ||||
|   </div> | ||||
| </template> | ||||
| <style scoped> | ||||
| * { | ||||
|     box-sizing: border-box; | ||||
|   box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .title { | ||||
|     color: #000; | ||||
|     text-align: center; | ||||
|   color: #000; | ||||
|   text-align: center; | ||||
| } | ||||
| 
 | ||||
| .login-from { | ||||
|     width: 400px; | ||||
|     padding: 20px; | ||||
|     border-radius: 4px; | ||||
|     box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.7); | ||||
|   width: 400px; | ||||
|   padding: 20px; | ||||
|   border-radius: 4px; | ||||
|   box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.7); | ||||
| } | ||||
| 
 | ||||
| .password, | ||||
| .account { | ||||
|     width: 360px; | ||||
|     margin: 10px auto; | ||||
|   width: 360px; | ||||
|   margin: 10px auto; | ||||
| } | ||||
| 
 | ||||
| .password-input, | ||||
| .account-input { | ||||
|     background-color: rgba(0, 0, 0, 0); | ||||
|     height: 60px; | ||||
|     width: 100%; | ||||
|     padding: 30px 20px 10px; | ||||
|     display: block; | ||||
|     border-width: 0; | ||||
|   background-color: rgba(0, 0, 0, 0); | ||||
|   height: 60px; | ||||
|   width: 100%; | ||||
|   padding: 30px 20px 10px; | ||||
|   display: block; | ||||
|   border-width: 0; | ||||
| } | ||||
| 
 | ||||
| .password-input:focus-visible, | ||||
| .account-input:focus-visible { | ||||
|     outline-color: rgb(255, 92, 0); | ||||
|   outline-color: rgb(255, 92, 0); | ||||
| } | ||||
| 
 | ||||
| .form-field { | ||||
|     background-color: rgb(249, 249, 249); | ||||
|     /* background-color: #000; */ | ||||
|     position: relative; | ||||
|     border-radius: 4px; | ||||
|     overflow: hidden; | ||||
|     transform: all 0.1s ease; | ||||
|   background-color: rgb(249, 249, 249); | ||||
|   /* background-color: #000; */ | ||||
|   position: relative; | ||||
|   border-radius: 4px; | ||||
|   overflow: hidden; | ||||
| } | ||||
| 
 | ||||
| .form-field-error { | ||||
|     background-color: rgb(252, 242, 243); | ||||
|   background-color: rgb(252, 242, 243); | ||||
| } | ||||
| 
 | ||||
| .form-control { | ||||
|     position: relative; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .floating-label { | ||||
|     position: absolute; | ||||
|     top: 20px; | ||||
|     left: 20px; | ||||
|     font-size: 17px; | ||||
|     height: 20px; | ||||
|     line-height: 20px; | ||||
|     transition: all 0.15s ease-in-out 0.15s; | ||||
|   position: absolute; | ||||
|   top: 20px; | ||||
|   left: 20px; | ||||
|   font-size: 17px; | ||||
|   height: 20px; | ||||
|   line-height: 20px; | ||||
|   transition: all 0.15s ease-in-out 0.15s; | ||||
| } | ||||
| 
 | ||||
| .floating-label-above { | ||||
|     top: 10px; | ||||
|     font-size: 12px; | ||||
|     color: #aaa; | ||||
|   top: 10px; | ||||
|   font-size: 12px; | ||||
|   color: #aaa; | ||||
| } | ||||
| 
 | ||||
| .floating-label-error { | ||||
|     color: red; | ||||
| } | ||||
| 
 | ||||
| .form-helper { | ||||
|     font-size: 12px; | ||||
|     color: red; | ||||
|   color: red; | ||||
| } | ||||
| 
 | ||||
| .accept-terms { | ||||
|     height: 25px; | ||||
|     line-height: 20px; | ||||
|   height: 25px; | ||||
|   line-height: 20px; | ||||
| } | ||||
| 
 | ||||
| .accept { | ||||
|     top: 20px; | ||||
|     color: #aaa; | ||||
|     font-size: 14px; | ||||
|     cursor: pointer; | ||||
|     line-height: 20px; | ||||
|     display: inline-flex; | ||||
|   top: 20px; | ||||
|   color: #aaa; | ||||
|   font-size: 14px; | ||||
|   cursor: pointer; | ||||
|   line-height: 20px; | ||||
|   display: inline-flex; | ||||
| } | ||||
| 
 | ||||
| .accept>span { | ||||
|     display: block; | ||||
| .accept > span { | ||||
|   display: block; | ||||
| } | ||||
| 
 | ||||
| .agreement-checkbox { | ||||
|     position: relative; | ||||
|     height: 20px; | ||||
|     width: 20px; | ||||
|     line-height: 1; | ||||
|   position: relative; | ||||
|   height: 20px; | ||||
|   width: 20px; | ||||
|   line-height: 1; | ||||
| } | ||||
| 
 | ||||
| .accept-checkbox-input { | ||||
|     background-color: rgba(0, 0, 0, 0); | ||||
|     border-color: transparent; | ||||
|     position: absolute; | ||||
|     height: 100%; | ||||
|     width: 100%; | ||||
|     z-index: 1; | ||||
|   background-color: rgba(0, 0, 0, 0); | ||||
|   border-color: transparent; | ||||
|   position: absolute; | ||||
|   height: 100%; | ||||
|   width: 100%; | ||||
|   z-index: 1; | ||||
| } | ||||
| 
 | ||||
| .agreement-inner { | ||||
|     position: absolute; | ||||
|     display: block; | ||||
|     /* height: 20px; */ | ||||
|     width: 20px; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     bottom: 0; | ||||
|     right: 0; | ||||
|     border: 1px solid #ddd; | ||||
|     border-radius: 4px; | ||||
|   position: absolute; | ||||
|   display: block; | ||||
|   /* height: 20px; */ | ||||
|   width: 20px; | ||||
|   top: 0; | ||||
|   left: 0; | ||||
|   bottom: 0; | ||||
|   right: 0; | ||||
|   border: 1px solid #ddd; | ||||
|   border-radius: 4px; | ||||
| } | ||||
| 
 | ||||
| .accept-text { | ||||
|     padding-left: 4px; | ||||
|     padding-right: 4px; | ||||
|     display: block; | ||||
|   padding-left: 4px; | ||||
|   padding-right: 4px; | ||||
|   display: block; | ||||
| } | ||||
| 
 | ||||
| .form-action { | ||||
|     display: block; | ||||
|   display: block; | ||||
| } | ||||
| 
 | ||||
| .form-action::after { | ||||
|     content: ""; | ||||
|     display: block; | ||||
|     clear: both; | ||||
|   content: ''; | ||||
|   display: block; | ||||
|   clear: both; | ||||
| } | ||||
| 
 | ||||
| .form-action-start { | ||||
|     float: left; | ||||
|   float: left; | ||||
| } | ||||
| 
 | ||||
| .form-action-end { | ||||
|     float: right; | ||||
|   float: right; | ||||
| } | ||||
| 
 | ||||
| .login-button { | ||||
|     width: 100%; | ||||
|     padding: 10px; | ||||
|     height: 60px; | ||||
|     margin-top: 10px; | ||||
|     margin-bottom: 10px; | ||||
|   width: 100%; | ||||
|   padding: 10px; | ||||
|   height: 60px; | ||||
|   margin-top: 10px; | ||||
|   margin-bottom: 10px; | ||||
| 
 | ||||
|     border-width: 0; | ||||
|     background-color: #ff5c02; | ||||
|     border-radius: 4px; | ||||
|     font-size: 18px; | ||||
|     color: rgba(255, 255, 255); | ||||
|     cursor: pointer; | ||||
|   border-width: 0; | ||||
|   background-color: #ff5c02; | ||||
|   border-radius: 4px; | ||||
|   font-size: 18px; | ||||
|   color: rgba(255, 255, 255); | ||||
|   cursor: pointer; | ||||
| } | ||||
| 
 | ||||
| .login-button:hover { | ||||
|     opacity: 0.9; | ||||
|   opacity: 0.9; | ||||
| } | ||||
| </style> | ||||
|  | ||||
| @ -1,9 +1,55 @@ | ||||
| <script setup> | ||||
| import CustomCalendar from '../components/CustomCalendar.vue' | ||||
| </script> | ||||
| <script setup></script> | ||||
| 
 | ||||
| <template> | ||||
|   <main> | ||||
|     <CustomCalendar /> | ||||
|     <article> | ||||
|       <h1>An Exciting Blog Post</h1> | ||||
|       <p> | ||||
|         Veggies es bonus vobis, proinde vos postulo essum magis kohlrabi welsh onion daikon amaranth | ||||
|         tatsoi tomatillo melon azuki bean garlic. | ||||
|       </p> | ||||
| 
 | ||||
|       <p> | ||||
|         Gumbo beet greens corn soko endive gumbo gourd. Parsley shallot courgette tatsoi pea sprouts | ||||
|         fava bean collard greens dandelion okra wakame tomato. Dandelion cucumber earthnut pea | ||||
|         peanut soko zucchini. | ||||
|       </p> | ||||
| 
 | ||||
|       <p> | ||||
|         Turnip greens yarrow ricebean rutabaga endive cauliflower sea lettuce kohlrabi amaranth | ||||
|         water spinach avocado daikon napa cabbage asparagus winter purslane kale. Celery potato | ||||
|         scallion desert raisin horseradish spinach carrot soko. Lotus root water spinach fennel | ||||
|         kombu maize bamboo shoot green bean swiss chard seakale pumpkin onion chickpea gram corn | ||||
|         pea. Brussels sprout coriander water chestnut gourd swiss chard wakame kohlrabi beetroot | ||||
|         carrot watercress. Corn amaranth salsify bunya nuts nori azuki bean chickweed potato bell | ||||
|         pepper artichoke. | ||||
|       </p> | ||||
| 
 | ||||
|       <p> | ||||
|         Nori grape silver beet broccoli kombu beet greens fava bean potato quandong celery. Bunya | ||||
|         nuts black-eyed pea prairie turnip leek lentil turnip greens parsnip. Sea lettuce lettuce | ||||
|         water chestnut eggplant winter purslane fennel azuki bean earthnut pea sierra leone bologi | ||||
|         leek soko chicory celtuce parsley jícama salsify. | ||||
|       </p> | ||||
| 
 | ||||
|       <p> | ||||
|         Celery quandong swiss chard chicory earthnut pea potato. Salsify taro catsear garlic gram | ||||
|         celery bitterleaf wattle seed collard greens nori. Grape wattle seed kombu beetroot | ||||
|         horseradish carrot squash brussels sprout chard. | ||||
|       </p> | ||||
|     </article> | ||||
| 
 | ||||
|     <aside> | ||||
|       <h2>Photography</h2> | ||||
|       <ul class="photos"></ul> | ||||
|     </aside> | ||||
|   </main> | ||||
| </template> | ||||
| 
 | ||||
| <style> | ||||
| main { | ||||
|   width: 80%; | ||||
|   display: flex; | ||||
|   flex: 3 1; | ||||
| } | ||||
| </style> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user