| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- <template>
- <div class="curriculum-selector">
- <!-- 教材 -->
- <div class="select-wrapper">
- <select
- :value="selectedTextbook"
- @change="$emit('update:selectedTextbook', ($event.target as HTMLSelectElement).value)"
- >
- <option v-for="tb in textbooks" :key="tb.id" :value="tb.id">{{ tb.name }}</option>
- </select>
- <svg class="select-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
- </div>
- <!-- 年级 -->
- <div class="select-wrapper">
- <select
- :value="selectedGrade"
- @change="$emit('update:selectedGrade', ($event.target as HTMLSelectElement).value)"
- >
- <option v-for="g in grades" :key="g.id" :value="g.id">{{ g.name }}{{ g.semester }}</option>
- </select>
- <svg class="select-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
- </div>
- <!-- 单元 -->
- <div class="select-wrapper">
- <select
- :value="selectedUnit"
- @change="$emit('update:selectedUnit', ($event.target as HTMLSelectElement).value)"
- >
- <option v-for="u in units" :key="u.id" :value="u.id">{{ u.number }}</option>
- </select>
- <svg class="select-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { computed } from 'vue'
- import curriculumData from '../data/curriculum.json'
- import type { CurriculumData } from '@/types/englishSpeaking'
- const props = defineProps<{
- selectedTextbook: string
- selectedGrade: string
- selectedUnit: string
- }>()
- defineEmits<{
- (e: 'update:selectedTextbook', value: string): void
- (e: 'update:selectedGrade', value: string): void
- (e: 'update:selectedUnit', value: string): void
- }>()
- const data = curriculumData as CurriculumData
- const textbooks = computed(() => data.textbooks)
- const grades = computed(() => {
- const tb = data.textbooks.find(t => t.id === props.selectedTextbook)
- return tb?.grades || []
- })
- const units = computed(() => {
- const tb = data.textbooks.find(t => t.id === props.selectedTextbook)
- const grade = tb?.grades.find(g => g.id === props.selectedGrade)
- return grade?.units || []
- })
- </script>
- <style lang="scss" scoped>
- .curriculum-selector {
- display: flex;
- align-items: center;
- gap: 10px;
- }
- .select-wrapper {
- position: relative;
- flex: 1;
- select {
- width: 100%;
- appearance: none;
- background: rgba(249, 250, 251, 0.8);
- border: 1px solid rgba(229, 231, 235, 0.8);
- border-radius: 12px;
- padding: 8px 28px 8px 12px;
- font-size: 13px;
- color: #1f2937;
- cursor: pointer;
- transition: all 0.2s;
- &:hover {
- background: #fff;
- border-color: #d1d5db;
- }
- &:focus {
- outline: none;
- border-color: #fb923c;
- box-shadow: 0 0 0 2px rgba(251, 146, 60, 0.1);
- background: #fff;
- }
- }
- }
- .select-arrow {
- position: absolute;
- right: 10px;
- top: 50%;
- transform: translateY(-50%);
- color: #9ca3af;
- pointer-events: none;
- }
- </style>
|