update
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<n-grid :cols="5" :x-gap="16" v-if="tutorial.id">
|
<div>
|
||||||
<n-gi :span="1">
|
<!-- 桌面端布局 -->
|
||||||
<n-card title="目录" :bordered="false" size="small">
|
<n-grid :cols="5" :x-gap="16" v-if="tutorial.id && isDesktop">
|
||||||
<n-scrollbar :style="{ maxHeight: 'calc(100vh - 180px)' }">
|
<n-gi :span="1">
|
||||||
|
<n-card title="教程目录" :bordered="false" size="small">
|
||||||
<n-list hoverable clickable>
|
<n-list hoverable clickable>
|
||||||
<n-list-item
|
<n-list-item
|
||||||
v-for="(item, index) in titles"
|
v-for="(item, index) in titles"
|
||||||
@@ -17,30 +18,86 @@
|
|||||||
</n-text>
|
</n-text>
|
||||||
</n-list-item>
|
</n-list-item>
|
||||||
</n-list>
|
</n-list>
|
||||||
</n-scrollbar>
|
</n-card>
|
||||||
</n-card>
|
</n-gi>
|
||||||
</n-gi>
|
|
||||||
|
|
||||||
<n-gi :span="tutorial.code ? 2 : 4">
|
<n-gi :span="tutorial.code ? 2 : 4">
|
||||||
<n-card
|
<n-card
|
||||||
:title="`第 ${step} 课:${titles[step - 1]?.title}`"
|
:title="`第 ${step} 课:${titles[step - 1]?.title}`"
|
||||||
:bordered="false"
|
:bordered="false"
|
||||||
size="small"
|
size="small"
|
||||||
>
|
>
|
||||||
<MdPreview
|
<MdPreview
|
||||||
preview-theme="vuepress"
|
preview-theme="vuepress"
|
||||||
:theme="isDark ? 'dark' : 'light'"
|
:theme="isDark ? 'dark' : 'light'"
|
||||||
:model-value="tutorial.content"
|
:model-value="tutorial.content"
|
||||||
/>
|
/>
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
|
|
||||||
<n-gi :span="2" v-if="tutorial.code">
|
<n-gi :span="2" v-if="tutorial.code">
|
||||||
<n-card title="示例代码" :bordered="false" size="small">
|
<n-card title="示例代码" :bordered="false" size="small">
|
||||||
<CodeEditor language="Python3" v-model="tutorial.code" />
|
<CodeEditor language="Python3" v-model="tutorial.code" />
|
||||||
</n-card>
|
</n-card>
|
||||||
</n-gi>
|
</n-gi>
|
||||||
</n-grid>
|
</n-grid>
|
||||||
|
|
||||||
|
<!-- 手机端布局 -->
|
||||||
|
<template v-if="tutorial.id && !isDesktop">
|
||||||
|
<n-tabs type="line" animated v-model:value="activeTab">
|
||||||
|
<n-tab-pane name="catalog" tab="目录">
|
||||||
|
<n-list hoverable clickable>
|
||||||
|
<n-list-item
|
||||||
|
v-for="(item, index) in titles"
|
||||||
|
:key="item.id"
|
||||||
|
@click="goToLesson(index + 1)"
|
||||||
|
>
|
||||||
|
<n-text
|
||||||
|
:type="step === index + 1 ? 'primary' : undefined"
|
||||||
|
:strong="step === index + 1"
|
||||||
|
>
|
||||||
|
{{ index + 1 }}. {{ item.title }}
|
||||||
|
</n-text>
|
||||||
|
</n-list-item>
|
||||||
|
</n-list>
|
||||||
|
</n-tab-pane>
|
||||||
|
|
||||||
|
<n-tab-pane name="content" :tab="`第 ${step} 课`">
|
||||||
|
<MdPreview
|
||||||
|
preview-theme="vuepress"
|
||||||
|
:theme="isDark ? 'dark' : 'light'"
|
||||||
|
:model-value="tutorial.content"
|
||||||
|
/>
|
||||||
|
</n-tab-pane>
|
||||||
|
|
||||||
|
<n-tab-pane name="code" tab="示例代码" v-if="tutorial.code">
|
||||||
|
<CodeEditor language="Python3" v-model="tutorial.code" />
|
||||||
|
</n-tab-pane>
|
||||||
|
</n-tabs>
|
||||||
|
|
||||||
|
<n-divider style="margin: 12px 0" />
|
||||||
|
|
||||||
|
<n-flex align="center" justify="space-between">
|
||||||
|
<n-button
|
||||||
|
secondary
|
||||||
|
type="primary"
|
||||||
|
:disabled="isFirstLesson"
|
||||||
|
@click="goToPrevLesson"
|
||||||
|
>
|
||||||
|
← 上一课
|
||||||
|
</n-button>
|
||||||
|
<n-text>{{ step }} / {{ titles.length }}</n-text>
|
||||||
|
<n-button
|
||||||
|
secondary
|
||||||
|
type="primary"
|
||||||
|
:disabled="isLastLesson"
|
||||||
|
@click="goToNextLesson"
|
||||||
|
>
|
||||||
|
下一课 →
|
||||||
|
</n-button>
|
||||||
|
</n-flex>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@@ -48,6 +105,7 @@ import { MdPreview } from "md-editor-v3"
|
|||||||
import "md-editor-v3/lib/preview.css"
|
import "md-editor-v3/lib/preview.css"
|
||||||
import { Tutorial } from "utils/types"
|
import { Tutorial } from "utils/types"
|
||||||
import { getTutorial, getTutorials } from "../api"
|
import { getTutorial, getTutorials } from "../api"
|
||||||
|
import { isDesktop } from "shared/composables/breakpoints"
|
||||||
|
|
||||||
const CodeEditor = defineAsyncComponent(
|
const CodeEditor = defineAsyncComponent(
|
||||||
() => import("shared/components/CodeEditor.vue"),
|
() => import("shared/components/CodeEditor.vue"),
|
||||||
@@ -72,12 +130,29 @@ const tutorial = ref<Partial<Tutorial>>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const titles = ref<{ id: number; title: string }[]>([])
|
const titles = ref<{ id: number; title: string }[]>([])
|
||||||
|
const activeTab = ref("content")
|
||||||
|
|
||||||
|
const isFirstLesson = computed(() => step.value === 1)
|
||||||
|
const isLastLesson = computed(() => step.value === titles.value.length)
|
||||||
|
|
||||||
function goToLesson(lessonNumber: number) {
|
function goToLesson(lessonNumber: number) {
|
||||||
|
activeTab.value = "content"
|
||||||
const dest = lessonNumber.toString().padStart(2, "0")
|
const dest = lessonNumber.toString().padStart(2, "0")
|
||||||
router.push("/learn/" + dest)
|
router.push("/learn/" + dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function goToPrevLesson() {
|
||||||
|
if (step.value > 1) {
|
||||||
|
goToLesson(step.value - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function goToNextLesson() {
|
||||||
|
if (step.value < titles.value.length) {
|
||||||
|
goToLesson(step.value + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
const res1 = await getTutorials()
|
const res1 = await getTutorials()
|
||||||
titles.value = res1.data
|
titles.value = res1.data
|
||||||
@@ -101,4 +176,12 @@ watch(
|
|||||||
:deep(.md-editor-preview .md-editor-code .md-editor-code-head) {
|
:deep(.md-editor-preview .md-editor-code .md-editor-code-head) {
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.md-editor-preview h1) {
|
||||||
|
font-size: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.md-editor-preview h2) {
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ const menus = computed<MenuOption[]>(() => [
|
|||||||
label: () => h(RouterLink, { to: "/learn/01" }, { default: () => "自学" }),
|
label: () => h(RouterLink, { to: "/learn/01" }, { default: () => "自学" }),
|
||||||
key: "learn",
|
key: "learn",
|
||||||
icon: renderIcon("streamline-emojis:snake"),
|
icon: renderIcon("streamline-emojis:snake"),
|
||||||
show: isDesktop.value,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: () => h(RouterLink, { to: "/" }, { default: () => "题库" }),
|
label: () => h(RouterLink, { to: "/" }, { default: () => "题库" }),
|
||||||
|
|||||||
Reference in New Issue
Block a user