zheng 4 hours ago
parent
commit
2ef20bdb42

BIN
vue3/.DS_Store


+ 22 - 17
vue3/project3/src/Demo.vue

@@ -7,6 +7,7 @@
         :choose="handleChoose"
         :remove="handleDelete"
         :all="handleAll"
+        :allCompleted="allCompleted"
       ></TodoContent>
       <TodoFooter
         :count="countSelected()"
@@ -19,7 +20,7 @@
 </template>
 
 <script lang="ts" setup>
-import { ref, reactive } from "vue";
+import { ref, computed } from "vue";
 import TodoHeader from "./components/TodoHeader.vue";
 import TodoFooter from "./components/TodoFooter.vue";
 import TodoContent from "./components/TodoContent.vue";
@@ -42,16 +43,16 @@ const todoList = ref<Todo[]>([
   {
     id: 1,
     text: "吃饭",
-    completed: false,
+    completed: true,
   },
   {
     id: 2,
     text: "睡觉",
-    completed: true,
+    completed: false,
   },
 ]);
 // 过滤
-const filters = ref("all");
+const filters = ref<string>("all");
 // 未选中的数量
 function countSelected() {
   return todoList.value.filter((item) => !item.completed).length;
@@ -64,6 +65,10 @@ function handleChoose(val: number) {
     }
   }
 }
+// 计算属性:是否所有任务都已完成
+const allCompleted = computed<boolean>(() => {
+  return todoList.value.length > 0 && todoList.value.every(item => item.completed);
+});
 // 渲染数组
 const renderList = () => {
   if (filters.value == "all") return todoList.value;
@@ -82,22 +87,22 @@ const handleSelect = (val: string) => {
   filters.value = val;
 };
 // 删除单条数据
-const handleDelete = (val:number) => {
-  console.log("删除",val)
-  if(!window.confirm("确定删除该条信息么?")) return;
-  todoList.value =  todoList.value.filter((item)=>item.id != val);
-}
+const handleDelete = (val: number) => {
+  console.log("删除", val);
+  if (!window.confirm("确定删除该条信息么?")) return;
+  todoList.value = todoList.value.filter((item) => item.id != val);
+};
 // 删除所有完成项
-const handleRemove=() => {
-  if(!window.confirm("确定删除所有完成项目么?")) return;
-  todoList.value =  todoList.value.filter((item)=> !item.completed );
-}
+const handleRemove = () => {
+  if (!window.confirm("确定删除所有完成项目么?")) return;
+  todoList.value = todoList.value.filter((item) => !item.completed);
+};
 // 全选
-function handleAll(val:any) {
-  console.log("全选",val.checked)
+function handleAll(val: any) {
+  console.log("全选", val.checked);
   todoList.value.map((item) => {
-   return item.completed = val.checked
-  })
+    return (item.completed = val.checked);
+  });
 }
 </script>
 <!-- npm install sass -->

+ 25 - 18
vue3/project3/src/components/TodoContent.vue

@@ -1,19 +1,25 @@
 <template>
   <div>
     <section class="main">
-      <input id="toggle-all" 
-      type="checkbox" 
-      class="toggle-all" @change="(event)=>{
-        props.all(event.target)
-      }" />
+      <input
+        id="toggle-all"
+        type="checkbox"
+        v-model="props.allCompleted"
+        class="toggle-all"
+        @change="
+          (event) => {
+            props.all(event.target);
+          }
+        "
+      />
       <label for="toggle-all"></label>
       <ul class="todo-list">
-        <TodoItem 
-        v-for="item in todoList" 
-        :key="item.id" 
-        :obj="item"
-        :chooseMain="props.choose"
-        :del="props.remove"
+        <TodoItem
+          v-for="item in todoList"
+          :key="item.id"
+          :obj="item"
+          :chooseMain="props.choose"
+          :del="props.remove"
         ></TodoItem>
       </ul>
     </section>
@@ -23,14 +29,15 @@
 <script lang="ts" setup>
 import { ref } from "vue";
 import TodoItem from "./TodoItem.vue";
-import {type Todo} from '../Demo.vue';
+import { type Todo } from "../Demo.vue";
 const props = defineProps<{
-  todoList:Todo[],
-  choose:(val:number)=>any,
-  remove:(val:number) =>void,
-  all:(val:any) => void
-}>()
-console.log(props.todoList,'新的')
+  todoList: Todo[];
+  choose: (val: number) => any;
+  remove: (val: number) => void;
+  all: (val: any) => void;
+  allCompleted: boolean;
+}>();
+console.log(props.todoList, "新的");
 </script>
 
 <style lang="scss" scoped>

+ 2 - 2
vue3/project4/src/App.vue

@@ -1,9 +1,9 @@
 <template>
   <div>
     <!-- push / replace -->
-    <RouterLink push to="/home">首页</RouterLink>
+    <!-- <RouterLink push to="/home">首页</RouterLink>
     <RouterLink push to="/list">列表</RouterLink>
-    <RouterLink push to="/my">我的</RouterLink>
+    <RouterLink push to="/my">我的</RouterLink> -->
     <RouterView></RouterView>
     <!-- newPart
     NewPart -->

+ 123 - 329
vue3/project4/src/views/My.vue

@@ -10,377 +10,171 @@ import {ref,reactive} from "vue"
 <style lang="scss" scoped>
 </style> -->
 <template>
-  <div class="weather-app">
-    
-    <!-- 搜索区域 -->
-    <div class="search-container">
+  <div class="guess-game">
+    <h1>数字猜谜游戏</h1>
+    <p>请猜一个 1-100 之间的数字</p>
+    <div class="game-container">
       <input
-        type="text"
-        v-model="searchQuery"
-        placeholder="输入城市名称..."
-        @keyup.enter="searchWeather"
+        type="number"
+        v-model.number="userGuess"
+        min="1"
+        max="100"
+        placeholder="输入猜测的数字"
+        @keyup.enter="checkGuess"
       >
-      <button @click="searchWeather">查询</button>
-    </div>
-    
-    <!-- 加载状态 -->
-    <div class="loading" v-if="isLoading">
-      正在查询天气数据...
-    </div>
-    
-    <!-- 错误提示 -->
-    <div class="error" v-if="errorMessage">
-      ⚠️ {{ errorMessage }}
-    </div>
-    
-    <!-- 天气信息展示 -->
-    <div class="weather-card" v-if="currentWeather && !isLoading && !errorMessage">
-      <div class="weather-header">
-        <h2>{{ currentWeather.city }}</h2>
-        <div class="date">{{ formattedDate }}</div>
+      <button @click="checkGuess">提交猜测</button>
+      <div class="message" v-if="message">
+        {{ message }}
       </div>
-      
-      <div class="weather-main">
-        <div class="temperature">
-          <span class="value">{{ currentTemp }}</span>
-          <span class="unit" @click="toggleUnit">
-            {{ isCelsius ? '°C' : '°F' }}
-          </span>
-        </div>
-        
-        <div class="condition">
-          <div class="icon">{{ weatherIcon }}</div>
-          <div class="text">{{ currentWeather.condition }}</div>
-        </div>
+      <div class="stats">
+        <p>已猜次数: {{ attempts }}</p>
+        <button @click="resetGame">重新开始</button>
       </div>
-      
-      <div class="weather-details">
-        <div class="detail">
-          <span class="label">湿度:</span>
-          <span class="value">{{ currentWeather.humidity }}%</span>
-        </div>
-        <div class="detail">
-          <span class="label">风速:</span>
-          <span class="value">{{ currentWeather.windSpeed }} km/h</span>
-        </div>
-        <div class="detail">
-          <span class="label">气压:</span>
-          <span class="value">{{ currentWeather.pressure }} hPa</span>
+      <div class="history" v-if="guessHistory.length > 0">
+        <h3>猜测历史:</h3>
+        <div class="history-items">
+          <span 
+            v-for="(guess, index) in guessHistory" 
+            :key="index"
+            :class="{ 
+              high: guess > targetNumber,
+              low: guess < targetNumber,
+              correct: guess === targetNumber
+            }"
+          >
+            {{ guess }}
+          </span>
         </div>
       </div>
     </div>
-    
-    <!-- 历史记录 -->
-    <div class="history-section" v-if="searchHistory.length > 0">
-      <h3>查询历史</h3>
-      <div class="history-tags">
-        <span 
-          class="history-tag" 
-          v-for="(item, index) in searchHistory" 
-          :key="index"
-          @click="searchWeather(item)"
-        >
-          {{ item }}
-          <button @click.stop="removeHistory(index)" class="remove-btn">×</button>
-        </span>
-      </div>
-    </div>
   </div>
 </template>
-
 <script setup lang="ts">
-import { ref, computed, watch } from 'vue';
-
-// 1. 定义天气数据类型接口
-interface WeatherData {
-  city: string;
-  temperature: number; // 摄氏度
-  condition: string; // 天气状况
-  humidity: number; // 湿度百分比
-  windSpeed: number; // 风速 km/h
-  pressure: number; // 气压 hPa
-  date: Date; // 日期
-}
-
-// 2. 响应式状态
-const searchQuery = ref<string>('');
-const currentWeather = ref<WeatherData | null>(null);
-const isLoading = ref<boolean>(false);
-const errorMessage = ref<string>('');
-const isCelsius = ref<boolean>(true);
-const searchHistory = ref<string[]>([]);
-
-// 3. 温度单位转换计算属性
-const currentTemp = computed<number>(() => {
-  if (!currentWeather.value) return 0;
-  
-  // 如果是华氏度,进行转换 (°F = °C × 1.8 + 32)
-  return isCelsius.value 
-    ? currentWeather.value.temperature 
-    : Math.round((currentWeather.value.temperature * 1.8 + 32) * 10) / 10;
-});
-
-// 4. 格式化日期
-const formattedDate = computed<string>(() => {
-  if (!currentWeather.value) return '';
-  
-  return currentWeather.value.date.toLocaleDateString('zh-CN', {
-    year: 'numeric',
-    month: 'long',
-    day: 'numeric',
-    weekday: 'long'
-  });
-});
-
-// 5. 根据天气状况显示对应图标
-const weatherIcon = computed<string>(() => {
-  if (!currentWeather.value) return '';
-  
-  const condition = currentWeather.value.condition.toLowerCase();
-  
-  if (condition.includes('晴')) return '☀️';
-  if (condition.includes('雨')) return '🌧️';
-  if (condition.includes('云')) return '☁️';
-  if (condition.includes('雪')) return '❄️';
-  if (condition.includes('雷')) return '⛈️';
-  return '🌤️';
-});
-
-// 6. 切换温度单位
-const toggleUnit = () => {
-  isCelsius.value = !isCelsius.value;
+import { ref } from 'vue';
+// 生成1-100之间的随机目标数字
+const generateTargetNumber = (): number => {
+  return Math.floor(Math.random() * 100) + 1;
 };
-
-// 7. 模拟天气数据查询(实际项目中会调用API)
-const searchWeather = async (city?: string) => {
-  // 清空错误信息
-  errorMessage.value = '';
-  
-  // 确定要查询的城市
-  const targetCity = city || searchQuery.value.trim();
-  if (!targetCity) {
-    errorMessage.value = '请输入城市名称';
+// 响应式状态定义(均指定类型)
+const targetNumber = ref<number>(generateTargetNumber());
+const userGuess = ref<number | null>(null);
+const message = ref<string>('');
+const attempts = ref<number>(0);
+const guessHistory = ref<number[]>([]);
+// 检查猜测结果
+const checkGuess = () => {
+  // 验证输入有效性
+  if (userGuess.value === null || userGuess.value < 1 || userGuess.value > 100) {
+    message.value = '请输入1-100之间的有效数字!';
     return;
   }
-  
-  try {
-    isLoading.value = true;
-    
-    // 模拟API请求延迟
-    await new Promise(resolve => setTimeout(resolve, 800));
-    
-    // 模拟返回的天气数据(实际项目中从API获取)
-    const mockWeatherData: WeatherData = {
-      city: targetCity,
-      temperature: Math.floor(Math.random() * 40) - 10, // -10到30度之间
-      condition: ['晴朗', '多云', '小雨', '中雨', '雷阵雨', '小雪'][Math.floor(Math.random() * 6)],
-      humidity: Math.floor(Math.random() * 50) + 30, // 30%到80%
-      windSpeed: Math.floor(Math.random() * 20) + 1, // 1到20 km/h
-      pressure: Math.floor(Math.random() * 50) + 1000, // 1000到1050 hPa
-      date: new Date()
-    };
-    
-    currentWeather.value = mockWeatherData;
-    
-    // 添加到历史记录(去重)
-    if (!searchHistory.value.includes(targetCity)) {
-      searchHistory.value.unshift(targetCity);
-      // 限制历史记录数量
-      if (searchHistory.value.length > 5) {
-        searchHistory.value.pop();
-      }
-    }
-    
-    // 清空搜索框
-    searchQuery.value = '';
-  } catch (err) {
-    errorMessage.value = '查询天气失败,请重试';
-    console.error('天气查询错误:', err);
-  } finally {
-    isLoading.value = false;
+  // 记录猜测次数和历史
+  attempts.value++;
+  guessHistory.value.push(userGuess.value);
+  // 判断猜测结果
+  if (userGuess.value === targetNumber.value) {
+    message.value = `恭喜你猜对了! 答案就是 ${targetNumber.value},共用了 ${attempts.value} 次`;
+  } else if (userGuess.value > targetNumber.value) {
+    message.value = '猜大了,再试试小的数字!';
+  } else {
+    message.value = '猜小了,再试试大的数字!';
   }
+  // 清空输入框
+  userGuess.value = null;
 };
-
-// 8. 移除历史记录
-const removeHistory = (index: number) => {
-  searchHistory.value.splice(index, 1);
+// 重置游戏
+const resetGame = () => {
+  targetNumber.value = generateTargetNumber();
+  userGuess.value = null;
+  message.value = '';
+  attempts.value = 0;
+  guessHistory.value = [];
 };
 </script>
-
 <style scoped>
-.weather-app {
-  max-width: 600px;
+.guess-game {
+  max-width: 500px;
   margin: 2rem auto;
   padding: 0 1rem;
-  font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
+  font-family: 'Arial', sans-serif;
+  text-align: center;
 }
-
-.search-container {
-  display: flex;
-  gap: 10px;
-  margin: 2rem 0;
+.game-container {
+  margin-top: 2rem;
+  padding: 2rem;
+  background-color: #f8fafc;
+  border-radius: 8px;
+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
 }
-
-.search-container input {
-  flex: 1;
-  padding: 10px;
-  border: 1px solid #e2e8f0;
+input {
+  padding: 0.75rem;
+  width: 150px;
+  margin-right: 0.5rem;
+  border: 1px solid #cbd5e1;
   border-radius: 4px;
   font-size: 1rem;
 }
-
-.search-container button {
-  padding: 10px 20px;
-  background-color: #3182ce;
+button {
+  padding: 0.75rem 1.5rem;
+  background-color: #3b82f6;
   color: white;
   border: none;
   border-radius: 4px;
   cursor: pointer;
+  font-size: 1rem;
+  transition: background-color 0.2s;
 }
-
-.loading, .error {
-  text-align: center;
+button:hover {
+  background-color: #2563eb;
+}
+.message {
+  margin: 1.5rem 0;
   padding: 1rem;
   border-radius: 4px;
-  margin-bottom: 1rem;
+  font-size: 1.1rem;
+  min-height: 48px;
 }
-
-.loading {
-  background-color: #ebf8ff;
-  color: #3182ce;
-}
-
-.error {
-  background-color: #fff5f5;
-  color: #e53e3e;
-}
-
-.weather-card {
-  background-color: white;
-  border-radius: 8px;
-  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
-  padding: 1.5rem;
-  margin-bottom: 2rem;
-}
-
-.weather-header {
+.stats {
+  margin: 1rem 0;
   display: flex;
-  justify-content: space-between;
+  justify-content: center;
+  gap: 1rem;
   align-items: center;
-  margin-bottom: 1.5rem;
-  padding-bottom: 1rem;
-  border-bottom: 1px solid #edf2f7;
 }
-
-.weather-header h2 {
-  margin: 0;
-  color: #2d3748;
-}
-
-.date {
-  color: #718096;
+.history {
+  margin-top: 1.5rem;
+  padding-top: 1.5rem;
+  border-top: 1px solid #e2e8f0;
 }
-
-.weather-main {
+.history-items {
+  margin-top: 0.5rem;
   display: flex;
-  justify-content: space-around;
-  align-items: center;
-  margin-bottom: 1.5rem;
-}
-
-.temperature {
-  display: flex;
-  align-items: baseline;
-}
-
-.temperature .value {
-  font-size: 4rem;
-  font-weight: bold;
-  color: #2d3748;
-}
-
-.temperature .unit {
-  font-size: 1.5rem;
-  color: #4a5568;
-  cursor: pointer;
-  margin-left: 0.5rem;
-  text-decoration: underline;
-}
-
-.condition {
-  text-align: center;
-}
-
-.condition .icon {
-  font-size: 3rem;
-  margin-bottom: 0.5rem;
-}
-
-.condition .text {
-  font-size: 1.2rem;
-  color: #4a5568;
-}
-
-.weather-details {
-  display: grid;
-  grid-template-columns: repeat(3, 1fr);
-  gap: 1rem;
-  padding-top: 1rem;
-  border-top: 1px solid #edf2f7;
-}
-
-.detail {
-  text-align: center;
-}
-
-.detail .label {
-  color: #718096;
-  font-size: 0.9rem;
+  flex-wrap: wrap;
+  gap: 0.5rem;
+  justify-content: center;
 }
-
-.detail .value {
-  color: #2d3748;
-  font-weight: 500;
+.history-items span {
+  padding: 0.5rem;
+  border-radius: 4px;
+  background-color: #e2e8f0;
 }
-
-.history-section {
-  margin-top: 2rem;
+.history-items .high {
+  background-color: #fee2e2;
+  color: #dc2626;
 }
-
-.history-section h3 {
-  color: #4a5568;
-  margin-bottom: 1rem;
+.history-items .low {
+  background-color: #dbeafe;
+  color: #1e40af;
 }
-
-.history-tags {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 0.5rem;
+.history-items .correct {
+  background-color: #dcfce7;
+  color: #059669;
+  font-weight: bold;
 }
-
-.history-tag {
-  background-color: #edf2f7;
-  padding: 0.5rem 1rem;
-  border-radius: 20px;
-  font-size: 0.9rem;
-  cursor: pointer;
-  display: inline-flex;
-  align-items: center;
-  gap: 0.5rem;
+.clear-completed-btn {
+  background-color: #ef4444;
 }
-
-.remove-btn {
-  background: none;
-  border: none;
-  color: #718096;
-  cursor: pointer;
-  font-size: 1rem;
-  padding: 0;
-  line-height: 1;
-}
-
-.remove-btn:hover {
-  color: #e53e3e;
+.clear-completed-btn:hover {
+  background-color: #dc2626;
 }
-</style>
-    
+</style>   

+ 8 - 0
vue3/project5/.vite/deps/_metadata.json

@@ -0,0 +1,8 @@
+{
+  "hash": "26319a97",
+  "configHash": "9b1f6261",
+  "lockfileHash": "e3b0c442",
+  "browserHash": "79395363",
+  "optimized": {},
+  "chunks": {}
+}

+ 3 - 0
vue3/project5/.vite/deps/package.json

@@ -0,0 +1,3 @@
+{
+  "type": "module"
+}