use default props
This commit is contained in:
@@ -60,7 +60,7 @@ import { useAIStore } from "oj/store/ai"
|
||||
import { parseTime } from "utils/functions"
|
||||
|
||||
const aiStore = useAIStore()
|
||||
const containerRef = ref<HTMLElement>()
|
||||
const containerRef = useTemplateRef<HTMLElement>("containerRef")
|
||||
|
||||
const CELL_SIZE = 12
|
||||
const CELL_GAP = 3
|
||||
|
||||
@@ -31,9 +31,7 @@ interface Props {
|
||||
isConnected?: boolean // WebSocket 实际的连接状态(已建立/未建立)
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
isConnected: false,
|
||||
})
|
||||
const { storageKey, isConnected = false } = defineProps<Props>()
|
||||
|
||||
// 注入同步状态
|
||||
const syncStatus = injectSyncStatus()
|
||||
@@ -102,7 +100,7 @@ const reset = () => {
|
||||
problem.value!.template[codeStore.code.language] ||
|
||||
SOURCES[codeStore.code.language],
|
||||
)
|
||||
storage.remove(props.storageKey)
|
||||
storage.remove(storageKey)
|
||||
message.success("代码重置成功")
|
||||
}
|
||||
|
||||
@@ -228,7 +226,7 @@ onMounted(() => {
|
||||
/>
|
||||
|
||||
<!-- 同步状态标签 -->
|
||||
<template v-if="props.isConnected">
|
||||
<template v-if="isConnected">
|
||||
<n-tag v-if="syncStatus.otherUser.value" type="info">
|
||||
{{ SYNC_MESSAGES.SYNCING_WITH(syncStatus.otherUser.value.name) }}
|
||||
</n-tag>
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
{{ content }}
|
||||
</n-form-item>
|
||||
<n-button
|
||||
v-if="hasCommented && props.showStatistics"
|
||||
v-if="hasCommented && showStatistics"
|
||||
type="primary"
|
||||
@click="getComments"
|
||||
>
|
||||
@@ -77,7 +77,7 @@
|
||||
提交
|
||||
</n-button>
|
||||
</n-form>
|
||||
<div v-if="props.showStatistics">
|
||||
<div v-if="showStatistics">
|
||||
<n-descriptions
|
||||
class="list"
|
||||
v-if="count"
|
||||
@@ -117,9 +117,7 @@ interface Props {
|
||||
showStatistics?: boolean
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
showStatistics: true,
|
||||
})
|
||||
const { showStatistics = true } = defineProps<Props>()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const problemStore = useProblemStore()
|
||||
|
||||
@@ -40,10 +40,7 @@ interface Props {
|
||||
problemSetId?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
contestID: "",
|
||||
problemSetId: "",
|
||||
})
|
||||
const { problemID, contestID = "", problemSetId = "" } = defineProps<Props>()
|
||||
|
||||
const errMsg = ref("无数据")
|
||||
const route = useRoute()
|
||||
@@ -67,7 +64,7 @@ const tabOptions = computed(() => {
|
||||
options.push("editor")
|
||||
}
|
||||
options.push("info")
|
||||
if (!props.contestID) {
|
||||
if (!contestID) {
|
||||
options.push("comment")
|
||||
}
|
||||
if (myFlowchartStore.showing) {
|
||||
@@ -110,7 +107,7 @@ watch(
|
||||
async function init() {
|
||||
screenModeStore.resetScreenMode()
|
||||
try {
|
||||
const res = await getProblem(props.problemID, props.contestID)
|
||||
const res = await getProblem(problemID, contestID)
|
||||
problem.value = res.data
|
||||
} catch (err: any) {
|
||||
problem.value = null
|
||||
@@ -120,7 +117,7 @@ async function init() {
|
||||
}
|
||||
}
|
||||
onMounted(init)
|
||||
watch(() => props.problemID, init)
|
||||
watch(() => problemID, init)
|
||||
onBeforeUnmount(() => {
|
||||
problem.value = null
|
||||
errMsg.value = "无数据"
|
||||
@@ -159,15 +156,15 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane
|
||||
name="info"
|
||||
tab="题目统计"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemInfo />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane
|
||||
v-if="!props.contestID"
|
||||
v-if="!contestID"
|
||||
name="comment"
|
||||
tab="题目点评"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemComment />
|
||||
</n-tab-pane>
|
||||
@@ -181,7 +178,7 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane
|
||||
name="submission"
|
||||
tab="我的提交"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemSubmission />
|
||||
</n-tab-pane>
|
||||
@@ -215,15 +212,15 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane
|
||||
name="info"
|
||||
tab="题目统计"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemInfo />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane
|
||||
v-if="!props.contestID"
|
||||
v-if="!contestID"
|
||||
name="comment"
|
||||
tab="题目点评"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemComment />
|
||||
</n-tab-pane>
|
||||
@@ -237,7 +234,7 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane
|
||||
name="submission"
|
||||
tab="我的提交"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemSubmission />
|
||||
</n-tab-pane>
|
||||
@@ -256,14 +253,14 @@ watch(isMobile, (value) => {
|
||||
<n-tab-pane name="editor" tab="代码">
|
||||
<component :is="inProblem ? ProblemEditor : ContestEditor" />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="info" tab="统计" :disabled="!!props.problemSetId">
|
||||
<n-tab-pane name="info" tab="统计" :disabled="!!problemSetId">
|
||||
<ProblemInfo />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane
|
||||
v-if="!props.contestID"
|
||||
v-if="!contestID"
|
||||
name="comment"
|
||||
tab="点评"
|
||||
:disabled="!!props.problemSetId"
|
||||
:disabled="!!problemSetId"
|
||||
>
|
||||
<ProblemComment />
|
||||
</n-tab-pane>
|
||||
@@ -274,7 +271,7 @@ watch(isMobile, (value) => {
|
||||
>
|
||||
<MyFlowchartTab />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="submission" tab="提交" :disabled="!!props.problemSetId">
|
||||
<n-tab-pane name="submission" tab="提交" :disabled="!!problemSetId">
|
||||
<ProblemSubmission />
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
|
||||
@@ -28,7 +28,7 @@ const isDefaultAvatar = computed(
|
||||
() => profile.value?.avatar.endsWith("default.png") ?? true,
|
||||
)
|
||||
|
||||
const problemsFlexRef = ref<HTMLElement | null>(null)
|
||||
const problemsFlexRef = useTemplateRef<HTMLElement>("problemsFlexRef")
|
||||
const itemsPerRow = ref(8)
|
||||
|
||||
function updateItemsPerRow() {
|
||||
|
||||
@@ -22,21 +22,19 @@ interface Props {
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
language: "Python3",
|
||||
fontSize: 20,
|
||||
height: "100%",
|
||||
readonly: false,
|
||||
placeholder: "",
|
||||
})
|
||||
|
||||
const { readonly, placeholder, height, fontSize } = toRefs(props)
|
||||
const {
|
||||
language = "Python3",
|
||||
fontSize = 20,
|
||||
height = "100%",
|
||||
readonly = false,
|
||||
placeholder = "",
|
||||
} = defineProps<Props>()
|
||||
const code = defineModel<string>("value")
|
||||
|
||||
const isDark = useDark()
|
||||
|
||||
const langExtension = computed(() => {
|
||||
return ["Python2", "Python3"].includes(props.language) ? python() : cpp()
|
||||
return ["Python2", "Python3"].includes(language) ? python() : cpp()
|
||||
})
|
||||
|
||||
const extensions = computed(() => [
|
||||
@@ -45,7 +43,7 @@ const extensions = computed(() => [
|
||||
bracketMatching(),
|
||||
closeBrackets(),
|
||||
autocompletion({
|
||||
override: [enhanceCompletion(props.language), completeAnyWord],
|
||||
override: [enhanceCompletion(language), completeAnyWord],
|
||||
}),
|
||||
isDark.value ? oneDark : smoothy,
|
||||
])
|
||||
|
||||
@@ -78,7 +78,7 @@ const emit = defineEmits<Emits>()
|
||||
const isHovered = ref(false)
|
||||
const isEditing = ref(false)
|
||||
const editText = ref("")
|
||||
const editInput = ref<HTMLInputElement>()
|
||||
const editInput = useTemplateRef<HTMLInputElement>("editInput")
|
||||
|
||||
// 定时器和事件处理器
|
||||
let hideTimeout: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
@@ -26,9 +26,7 @@ interface Props {
|
||||
height?: string
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
height: "calc(100vh - 133px)",
|
||||
})
|
||||
const { height = "calc(100vh - 133px)" } = defineProps<Props>()
|
||||
|
||||
// Vue Flow 实例
|
||||
const { addEdges, removeNodes, removeEdges } = useVueFlow()
|
||||
|
||||
@@ -17,7 +17,7 @@ const {
|
||||
loginLoading: isLoading,
|
||||
loginError: msg,
|
||||
} = storeToRefs(authStore)
|
||||
const loginRef = ref()
|
||||
const loginRef = useTemplateRef("loginRef")
|
||||
const classUserOptions = ref<SelectOption[]>([])
|
||||
const classUserLoading = ref(false)
|
||||
const isClassLogin = computed(() => Boolean(form.value.class))
|
||||
|
||||
@@ -7,17 +7,14 @@ interface Props {
|
||||
page: number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
limit: 10,
|
||||
page: 1,
|
||||
})
|
||||
const { total, limit: initialLimit = 10, page: initialPage = 1 } = defineProps<Props>()
|
||||
|
||||
const emit = defineEmits(["update:limit", "update:page"])
|
||||
|
||||
const { isDesktop } = useBreakpoints()
|
||||
|
||||
const limit = ref(props.limit)
|
||||
const page = ref(props.page)
|
||||
const limit = ref(initialLimit)
|
||||
const page = ref(initialPage)
|
||||
const sizes = [10, 30, 50]
|
||||
|
||||
watch(limit, () => emit("update:limit", limit))
|
||||
@@ -26,9 +23,9 @@ watch(page, () => emit("update:page", page))
|
||||
|
||||
<template>
|
||||
<n-pagination
|
||||
v-if="props.total"
|
||||
v-if="total"
|
||||
class="right margin"
|
||||
:item-count="props.total"
|
||||
:item-count="total"
|
||||
v-model:page="page"
|
||||
v-model:page-size="limit"
|
||||
:page-sizes="sizes"
|
||||
|
||||
@@ -12,7 +12,7 @@ const {
|
||||
signupError: msg,
|
||||
captchaSrc,
|
||||
} = storeToRefs(authStore)
|
||||
const signupRef = ref()
|
||||
const signupRef = useTemplateRef("signupRef")
|
||||
|
||||
const rules: FormRules = {
|
||||
username: [{ required: true, message: "用户名必填", trigger: "blur" }],
|
||||
|
||||
@@ -36,15 +36,15 @@ interface Props {
|
||||
placeholder?: string
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
language: "Python3",
|
||||
fontSize: 20,
|
||||
height: "100%",
|
||||
readonly: false,
|
||||
placeholder: "",
|
||||
})
|
||||
|
||||
const { readonly, placeholder, height, fontSize } = toRefs(props)
|
||||
const {
|
||||
sync,
|
||||
problem,
|
||||
language = "Python3",
|
||||
fontSize = 20,
|
||||
height = "100%",
|
||||
readonly = false,
|
||||
placeholder = "",
|
||||
} = defineProps<Props>()
|
||||
const code = defineModel<string>("value")
|
||||
|
||||
const emit = defineEmits<{
|
||||
@@ -57,7 +57,7 @@ const emit = defineEmits<{
|
||||
const { isDesktop } = useBreakpoints()
|
||||
|
||||
const langExtension = computed((): Extension => {
|
||||
return ["Python2", "Python3"].includes(props.language) ? python() : cpp()
|
||||
return ["Python2", "Python3"].includes(language) ? python() : cpp()
|
||||
})
|
||||
|
||||
const extensions = computed(() => [
|
||||
@@ -67,7 +67,7 @@ const extensions = computed(() => [
|
||||
closeBrackets(),
|
||||
isDark.value ? oneDark : smoothy,
|
||||
autocompletion({
|
||||
override: [enhanceCompletion(props.language), completeAnyWord],
|
||||
override: [enhanceCompletion(language), completeAnyWord],
|
||||
}),
|
||||
getInitialExtension(),
|
||||
])
|
||||
@@ -85,12 +85,12 @@ const cleanupSyncResources = () => {
|
||||
}
|
||||
|
||||
const initSync = async () => {
|
||||
if (!editorView.value || !props.problem || !isDesktop.value) return
|
||||
if (!editorView.value || !problem || !isDesktop.value) return
|
||||
|
||||
cleanupSyncResources()
|
||||
|
||||
cleanupSync = await startSync({
|
||||
problemId: props.problem,
|
||||
problemId: problem,
|
||||
editorView: editorView.value as EditorView,
|
||||
onStatusChange: (status) => {
|
||||
// 处理需要断开同步的情况
|
||||
@@ -108,13 +108,13 @@ const initSync = async () => {
|
||||
|
||||
const handleEditorReady = (payload: EditorReadyPayload) => {
|
||||
editorView.value = payload.view as EditorView
|
||||
if (props.sync) {
|
||||
if (sync) {
|
||||
initSync()
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.sync,
|
||||
() => sync,
|
||||
(shouldSync) => {
|
||||
if (shouldSync) {
|
||||
initSync()
|
||||
@@ -125,9 +125,9 @@ watch(
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.problem,
|
||||
() => problem,
|
||||
(newProblem, oldProblem) => {
|
||||
if (newProblem !== oldProblem && props.sync) {
|
||||
if (newProblem !== oldProblem && sync) {
|
||||
initSync()
|
||||
}
|
||||
},
|
||||
|
||||
@@ -17,10 +17,7 @@ interface Props {
|
||||
const rawHtml = defineModel<string>("value")
|
||||
type InsertFnType = (url: string, alt: string, href: string) => void
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
minHeight: 0,
|
||||
simple: false,
|
||||
})
|
||||
const { title, minHeight = 0, simple = false } = defineProps<Props>()
|
||||
|
||||
const message = useMessage()
|
||||
|
||||
@@ -112,17 +109,17 @@ async function customUpload(file: File, insertFn: InsertFnType) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="title" v-if="props.title">{{ props.title }}</div>
|
||||
<div class="title" v-if="title">{{ title }}</div>
|
||||
<div class="editorWrapper">
|
||||
<Toolbar
|
||||
class="toolbar"
|
||||
:editor="toolbarEditorRef"
|
||||
:defaultConfig="props.simple ? toolbarConfigSimple : toolbarConfig"
|
||||
:defaultConfig="simple ? toolbarConfigSimple : toolbarConfig"
|
||||
mode="simple"
|
||||
/>
|
||||
<Editor
|
||||
@click="onClick"
|
||||
:style="{ minHeight: props.minHeight + 'px' }"
|
||||
:style="{ minHeight: minHeight + 'px' }"
|
||||
v-model="rawHtml"
|
||||
:defaultConfig="editorConfig"
|
||||
mode="simple"
|
||||
|
||||
Reference in New Issue
Block a user