vue也支持声明式UI了,向移动端kotlin,swift看齐,抛弃html,pug升级版,进来看看新语法吧
2025年12月7日 02:48
众所周知,新生代的ui框架(如:kotlin,swift,flutter,鸿蒙)都已经抛弃了XML这类的结构化数据标记语言改为使用声明式UI
只有web端还没有支持此类ui语法,此次我开发的ovsjs为前端也带来了此类声明式UI语法的支持,语法如下
项目地址
语法插件地址:
marketplace.visualstudio.com/items?itemN…
新语法如下:
![]()
我认为更强的地方是我的新设计除了为前端带来了声明式UI,还支持了 #{ } 不渲染代码块的设计,支持在 声明式UI中编写代码,这样UI和逻辑之间的距离更近,维护更方便,抽象组件也更容易
对比kotlin,swift,flutter,鸿蒙语法如下:
kotlin的语法
import kotlinx.browser.*
import kotlinx.html.*
import kotlinx.html.dom.*
fun main() {
document.body!!.append.div {
h1 {
+"Welcome to Kotlin/JS!"
}
p {
+"Fancy joining this year's "
a("https://kotlinconf.com/") {
+"KotlinConf"
}
+"?"
}
}
}
swiftUI的语法
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(spacing: 16) {
Text("Hello SwiftUI")
.font(.largeTitle)
.fontWeight(.bold)
Text("Welcome to SwiftUI world")
Button("Click Me") {
print("Button clicked")
}
}
.padding()
}
}
flutter的语法
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
"Hello Flutter",
style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
const Text("Welcome to Flutter world"),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
print("Button clicked");
},
child: const Text("Click Me"),
)
],
),
),
),
);
}
}
鸿蒙 arkts
@Entry
@Component
struct Index {
@State message: string = 'Hello ArkUI'
build() {
Column() {
Text(this.message)
.fontSize(28)
.fontWeight(FontWeight.Bold)
Text('Welcome to HarmonyOS')
.margin({ top: 12 })
Button('Click Me')
.margin({ top: 16 })
.onClick(() => {
console.log('Button clicked')
})
}
.padding(20)
}
}
原理实现
简述一下实现原理,就是通过parser支持了新语法,然后将新语法转义为 iife包裹的vue的h函数
为什么要iife包裹
因为要支持不渲染代码块
ovs图中的代码对应的编译后的代码是这样的
import {defineOvsComponent} from "/@fs/D:/project/qkyproject/test-volar/ovs/ovs-runtime/src/index.ts";
import {$OvsHtmlTag} from "/@fs/D:/project/qkyproject/test-volar/ovs/ovs-runtime/src/index.ts";
import {ref} from "/node_modules/.vite/deps/vue.js?v=76ca4127";
export default defineOvsComponent(props => {
const msg = "You did it!";
let count = ref(0);
const timer = setInterval(() => {
count.value = count.value + 1;
},1000);
return $OvsHtmlTag.div({class:'greetings',onClick(){
count.value = 0;
}},[
$OvsHtmlTag.h1({class:'green'},[msg]),
count,
$OvsHtmlTag.h3({},[
"You've successfully created a project with ",
$OvsHtmlTag.a({href:'https://vite.dev/',target:'_blank',rel:'noopener'},['Vite']),
' + ',
$OvsHtmlTag.a({href:'https://vuejs.org/',target:'_blank',rel:'noopener'},['Vue 3']),
' + ',
$OvsHtmlTag.a({href:'https://github.com/alamhubb/ovsjs',target:'_blank',rel:'noopener'},['OVS']),
'.'
])
]);
});
parser是我自己写的,抄了 chevortain 的设计,写了个subhuti,支持定义peg语法
slimeparser,支持es2025语法的parser,基于subhuti,声明es2025语法就行
然后就是ovs继承slimeparser,添加了ovs的语法支持,并且在ast生成的时候将代码转为vue的渲染函数,运行时就是运行的vue的渲染函数的代码,所以完美支持vue的生态
感兴趣的可以试试,入门教程