Skip to content

VUE 题目

使用“VUE 题目”功能,允许你在题目编辑器中编写一个 VUE SFC。用以实现复杂的题目交互功能。

基本写法

在这之前……

你要在题目编辑器中,将“内容类型”设置为“题目是VUE SFC”。

我们知道,一般一个Vue SFC单文件组件分为 templatestylescript 三个部分。

你需要将 templatestyle 写在 “题目HTML” 里。

html
<template>
    <div class="test-a">{{ test }}</div>
</template>

<style>
.test-a {
    font-size: 60px;
}
</style>

注意

这里无法使用 style scoped。也无法使用 lang 属性。只能使用简单的 <style>

script 写在“题目脚本”里。无需带有 <script> 标签。

javascript
// 编辑器中无法使用 import,但是我们将 Vue 对象设置成了全局对象,
// 因此你可以写 const { xxx }= Vue 来代替。
const { ref, inject, onMounted } = Vue;

// script 中必须存在且只能存在一个 export default {}。
// 
// 这个对象将作为 Vue 的实例对象。
// 
// 因此,编辑器中只能使用 options 语法。
export default {
    // 尽管只能使用 options 语法,
    // 但是我们还是强烈推荐使用 setup 函数,并将所有逻辑都在 setup 函数内,
    // 以组合式语法实现。
    setup() {
        const test = ref(0);
        const backend = inject('backend');

        onMounted(async () => {
            const data = await backend("test-get-number", {
                current: test.value
            });
            test.value = data.number;
        });

        return {
            test
        }
    }
}

功能示例

可以查看 Vue 题目功能示例

该示例利用 Vue 题目与后端题目脚本功能,打造了一个可以实际运行的猜数字游戏。涵盖了 Vue 题目组件编写的一般方法。

引入功能

你可能已经注意到,在上面的代码中,我们引入了 inject 函数,并用此导入了一个名为 backend 的方法:

javascript
const backend = inject('backend');

这是由于在复杂题目交互中,一定存在一些只靠 Vue 组件自身难以实现的功能。我们使用 Vue 自身的依赖注入功能。在谜题渲染器中提供这些功能。

编写题目的时候就可以使用 inject('功能名') 来引入这个功能的方法了。

这里引入的 backend 方法正是调用后台题目脚本的方法。

除此之外还有一些其他的功能可以引入,请参考CCXC Vue SFC API

实时协作和同步

你可能有印象,CCBC 的部分题目中使用了实时协作功能。这是怎么做到的呢?

其实,CCXC Engine 中提供了一个基于 Y.js 的实时协作模块。

它的服务器是 ccxc-sync-server 实时同步服务。在题目渲染器中,也提供了一个已经连接好服务器的 Y.js Client 对象。

通过 inject('ysync') 可以在 Vue 题目中使用这个实时协作模块的功能。

javascript
const ysync = inject('ysync');

const yDoc = ysync.yDoc;
const yMap = yDoc.getMap("MY_CRDT");

关于详细的用法,可以参考 Y.js 文档

也可以参考 Y-Sync 同步功能示例题目

与上传题目模块的对比

Q:上面给出的两个示例,都是“上传题目模块”中使用的示例。它和直接填写在编辑器里的 Vue 题目有什么区别?

A:上传题目模块经过 Vite 编译后,与直接写在编辑器中的 Vue 题目几乎无区别。主要区别就是允许<script>不分开提交而是合并在一个文件中。

但是因为引入了 Vite 编译,所以编译前的写法更加灵活。

📊 功能对比表:

功能特性上传题目模块编辑器填写
import 语法import { xxx } from 'vue'const { xxx } = Vue
样式支持✅ 支持 <style scoped>❌ 仅支持普通 <style>
第三方库✅ 可通过 import 引入并打包❌ 无法使用第三方库
渲染器功能✅ 支持 inject 引入所有功能✅ 支持 inject 引入所有功能
组件语法⚠️ 仅支持 options 语法⚠️ 仅支持 options 语法
导出要求⚠️ 只能有一个 export default⚠️ 只能有一个 export default

Released under the MIT License. Powered by VitePress.