README
XAML 扩展应用标示语言
满足系统中动态内容的即时更新需求。
适合应用场景
- 运营活动页面(需要灵活的页面(模板)响应不同的运营内容)
- 动态子系统(广告、消息推送)
- 可视化非技术页面搭建(流程系统、表单系统、基于模板的宣传页面)
特点
- 领域描述:使用DSL描述页面布局、数据与交互。
- 框架独立:支持Vue/React/JSX/JS组件嵌入(当前暂未实现React)。
- 独立容器:只在需要支持动态内容地方插入即可。
- 数据绑定:支持组件与本地或远程数据源的绑定。
- 层级视图:视图元素采用树结构组织
- 数据同一:同一容器Portal数据集共享,方便数据绑定
总体结构
页面由多个Portal构成,功能紧密的部分构成一个Portal,Portal采用扁平的管理结构,但是视图结构采用组件树多层结构。Portal的组织结构图如下
页面布局解构
一个页面被划分为多个部分,每个模块之间应该是数据相对独立、交互关联少。 一个内部关联紧密,功能相似部分的模块我们用一个统一的Portal组件统一管理。 Portal是一个组件容器,内部组件在数据和值域上直属Portal管理,层级结构可以是多层结构
Portal
- Portal 统一了模块内数据、行为和组件引用的管理,子组件的配置方法可以方便的获取数据,调用方法。
- 统一模块内交互方式,比如可以直接修改数据和调用portal行为
- this.$emit('change', {value: 123})
- this.changeList([])
- 统一组件的引用, 比如可以获取任意组件引用
this.$refs.table
{
state: { // 公共数据字段
weight: 0
},
children: [
{
html: '<p><b>温馨提示</b>:不要吃太多!</p>',
},
{
type: 'component',
uiType: 'NumberBox',
field: 'weight',
config: {
value: 0.8,
unit: 'kg'
},
on: {
changeValue (e) {
if (this.validate(e.value, 'weight')) {
// 通过事件通知容器组件捕获变化
this.$emit('change', {value: e.value})
// 或者直接修改state
this.setState({weight: e.value})
}
}
}
}
]
}
类型
html片段
{
html: '<p><b>温馨提示</b>:不要吃太多!</p>'
}
text片段
{
text: '提示:你的余额不足1千万'
}
组件
- 组件配置
{
type: 'component',
uiType: 'DatePicker',
field: 'range',
config: {
maxDates: 365
},
on: {
'model-change': 'change',
'value-change': 'change'
}
}
- 组件注册
对于Vue组件,需要提前全局注册好组件,或者在Portal注册组件即可。
import {DatePicker, RichTable} from 'smui'
export default {
type: 'component',
uiType: 'Portal',
state: {},
components: {
DatePicker,
RichTable
}
}
- 组件事件
通过
on
和dispatch
属性进行事件注册。处理函数的this
被绑定为Portal
容器,因此可以调用portal
的方法和获取相关数据.
on
一般用于注册事件处理函数,如果是字符串也被处理为事件别名转发。dispatch
一般用于注册事件别名转发,也可注册为处理函数。与on
用法无本质区别- 为了支持多次注册,事件注册方法被压入事件队列,顺序触发。
{
on: {
'model-change': 'change',
'range-change': function (e) {
this.$emit('change', {value: e.value})
}
}
}
容器
通过指定
type
为container
, 容器对象如果有children
顺序将children内的元素/组件渲染。 容器可以包含容器,因此可以构成组件/元素树。 但是组件扩展的行为和事件函数内的this
都将指向portal
对象。
{
type: 'container',
children: [...]
}
扩展类型
为了减少相似组件的重复配置项,使用
plugin
作为扩展组件。
{
plugin: {
CutomType: {
type: 'uiType',
uiType: 'NumberBox',
config: {
validate: {
max: 1000,
min: 10
}
}
}
},
children: [
{
type: 'CustomType',
field: 'bid'
}
]
}