一、前言
一个普通的web网站应用使用 html、xhml 等更具描述能力的 external dsl(domain-specific language)来描述界面,然后使用javascript代码来解决界面上的一些逻辑问题,使用css来描绘界面的样式。这些 external dsl 用于将数据配置跟代码逻辑分离开来
一些现代语言加入了 internal dsl 这种东西,它赋予你在代码中写 dsl 的能力:比如jsx
语法,vue语法。就是在javascript中使用类似于 html 的语法。
前端编程界的趋势是将 external dsl 混写 javascript 这类着重表达逻辑的语言里面。
分享一段flutter dart代码:
// 这段代码可以类比于`React.createElement`
class Drawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Drawer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
DrawerHeader(
decoration: BoxDecoration(color: Colors.green),
child: Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Icon(
Icons.account_circle,
color: Colors.green.shade800,
size: 96,
),
),
),
// Long drawer contents are often segmented.
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Divider(),
),
ListTile(
leading: SettingsTab.androidIcon,
title: Text(SettingsTab.title),
onTap: () {
Navigator.pop(context);
Navigator.push<void>(context,
MaterialPageRoute(builder: (context) => SettingsTab()));
},
),
],
),
)
}
}
从上面的Dart代码可以看出,使用OO的编程语言去描述界面,会显得代码语义不够直观(请注意BoxDecoration
, Padding
的使用)。
因此,描述界面我们更倾向于专门使用描述性质的语言,描述性语言可拓展性好,对人类友好,结构清晰易读。比如xml,从这个角度来看待React组件中的render
方法,和Vue组件中的<template></template>
就发现一切都明了了起来。
虽然React,Vue中的 DSL 会被框架本身转化成javascript代码。但其 DSL 部分的内容,对开发者的更友好,开发心智负担减少
另外的思考:html,xml 语言从控制流的角度来看,无法写条件分支和循环分支。而Vue内置的v-for
, v-if
关键字优雅的解决了这一问题。
二、从Vue看React
既然DSL语言描述界面有天然优势,我们更希望,在一个文件中,DSL的归DSL,OO的归OO。因此,对于如下的代码:
// Example.js
class