VUE 题目
使用“VUE 题目”功能,允许你在题目编辑器中编写一个 VUE SFC。用以实现复杂的题目交互功能。
基本写法
在这之前……
你要在题目编辑器中,将“内容类型”设置为“题目是VUE SFC”。
我们知道,一般一个Vue SFC单文件组件分为 template
、style
和 script
三个部分。
你需要将 template
和 style
写在 “题目HTML” 里。
<template>
<div class="test-a">{{ test }}</div>
</template>
<style>
.test-a {
font-size: 60px;
}
</style>
注意
这里无法使用 style scoped
。也无法使用 lang
属性。只能使用简单的 <style>
。
将 script
写在“题目脚本”里。无需带有 <script>
标签。
// 编辑器中无法使用 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
的方法:
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 题目中使用这个实时协作模块的功能。
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 |