1、框架简介

这两天在Github上发现了xlua的作者车雄生前辈开源的一个框架—XUUI,于是下载下来学习了一下。XUUI基于xlua,又借鉴了mvvm的设计概念。xlua是目前很火的unity热更方案,不仅支持纯lua脚本热更,也可以做 C# 代码的bug hotfix,而mvvm框架呢,在前端开发中应用很广,我周围同事在做wpf开发时也用到了mvvm框架,mvvm模式在unity开发中也同样适用,github上可以找到不少开源案例。XUUI主要有两大核心能力:一是支持MVVM的单向、双向绑定,二是框架应用时可以做模块加载、模块刷新、模块间数据隔离、模块间可控交互。
 

2、框架特点

作者在文档中介绍了XUUI框架的特点:一是可以和任意UI库配合,ugui,ngui,fairyGUI,你自己倒腾的UI库都可以;二是支持把本框架作为一个mvvm驱动器,纯用C#写逻辑;三是支持“计算属性”:“计算属性”依赖的各属性发生改变会触发“计算属性”的重计算;四是可随时绑定View以及解绑定。
 

3、使用示例

下载项目到本地,可以看到作者提供了几个使用示例。使用时要设置好绑定信息,给各个UI元素(比如Button、Text、InputField等)添加适配器,可以通过Component/XUUI菜单或者手动到XUUI\Scripts\UGUIAdapter目录找脚本拖放到UI上,然后设置BindTo属性即可,XUUI作者已经提供了Button、Text、Dropdown、InputField的适配器,其他ui元素比如Toggle就需要自己去编写了,作者已经提供了接口模板,自己实现其他适配器也不难。先来看一下Helloworld示例:

这个示例中,有三个ui元素,绑定信息如下:InputField: info.name;Text      : message,这是个“计算属性”,计算时用了info.name,当info.name发生变化会触发message重新计算,并自动更新Text;Button    : click,这会绑定到一个click command上。C#代码如下:

using UnityEngine;
using XUUI; public class Helloworld : MonoBehaviour
{
Context context = null; void Start()
{
context = new Context(@"
return {
data = {
info = {
name = 'John',
},
},
computed = {
message = function(data)
return 'Hello ' .. data.info.name .. '~!'
end
},
commands = {
click = function(data)
print(data.info.name..'哈哈')
end,
},
}
"); context.Attach(gameObject);
} void OnDestroy()
{
context.Dispose();
}
}
如上面C#代码所示,首先要new一个Context,参数是个lua脚本,该lua脚本返回一个table,table需要包含几个特殊的字段: data就是ViewModle(VM);computed中引用到的VM元素,在其依赖的VM元素发生改变会自动重新计算并同步到各个绑定了它(比如上例的message)的节点;commands是类似按钮点击事件绑定的响应方法,随后,调用Context的Attach方法进行绑定。
 

4、XUUI中几个重要的类

(1)Context:启动框架的方法就是new一个Context实例,并传入lua脚本,在Context的构造函数中,会初始化好lua运行环境(即LuaEnv),并解析传入的lua脚本,对框架各模块进行配置,Context实现了IDisposable接口,以便对一些非托管资源进行手动的垃圾回收。
(2)DataConsumer:如果ui Adapter需要监听VM变化,须实现DataConsumer接口(可以不显式声明实现,只要有DataConsumer声明的接口即可)
(3)DataProducer:如果ui Adapter需要把数据同步回VM,须实现DataProducer接口
(4)EventEmitter:如果ui Adapter需要产生一个事件,须实现EventEmitter接口
 

5、XUUI框架的应用

在实际使用中,并不会像上面HelloWorld实例那么简单,作者也提供了在实际使用时的示例,首先new一个Context,Context的构造函数传入的是一个含modules字段以及name字段的table:

context = new Context(@"
return {
name = 'myapp',
modules = {'module1', 'module2'},
}
");
执行上面代码,框架会做这些事情: 加载myapp.module1,myapp.module2,加载的规则和require是一致的;为这两个设置独立的沙盒,各模块即使定义了全局变量也互不影响,一定程度上减轻不同模块开发者由于沟通不足或者笔误引发的模块间冲突;模块间数据隔离:模块也可以定义data、commands、computed,在模块定义的commands和computed只能看到本模块的data; 模块间调用:通过exports字段可以导出一些函数供其它模块调用,其它模块可以通过“模块名.函数名”调用
* 支持模块刷新(reload),reload后data变动会更新UI,监听原先commands也会自动更新到新的commands,computed会自动重新计算并更新UI。
module1代码如下:

return {
data = {
name = "haha",
select = , -- ui通过 module1.select来绑定
}, commands = {
click = function(data)
module2.set_select(data.select) -- 可以调用别的模块exports的接口
data.select = data.select == and or -- command只能看到/修改自己的数据
end,
}, computed = {
info = function(data)
return string.format('i am %s, my select is %d', data.name, data.select)
end,
}, exports = {
hello = function(p) -- 可以被其它module调用
print('hello, p = '.. p)
end,
},
}
module2代码如下:

local data = {
message = "hehe",
select = ,
} return {
data = data, commands = {
click = function(data)
module1.hello()
data.select = data.select == and or
end,
}, computed = {
info = function(data)
return string.format('message is %s, select is %d', data.message, data.select)
end,
}, exports = {
set_select = function(p)
data.select = p
end,
},
}
需要注意的是:这里的UI不像逻辑那样划分模块,通过“模块名.模块内路径”去进行数据/响应的绑定,比如moudle1.select,module2.click等等。
 

6、最后

昨天才接触到这个框架,XUUI框架下载量并不多,今天大概学习了一下,分享一下学习成果,总的来说,这个框架集成了xlua和mvvm,有很多值得借鉴的地方,很适合ui模块的开发。博客内容有部分是从作者文档里抄下来的,因为怕自己描述不准确。分享一下,希望这个框架能像基于ulua的SimpleFramework一样被更多开发者使用~
项目地址:https://github.com/chexiongsheng/XUUI
如有错误,欢迎指正,谢谢!

 
 
 
 
 
 
 
 

基于xlua和mvvm的unity框架的更多相关文章

  1. 转-基于NodeJS的14款Web框架

    基于NodeJS的14款Web框架 2014-10-16 23:28 作者: NodeJSNet 来源: 本站 浏览: 1,399 次阅读 我要评论暂无评论 字号: 大 中 小 摘要: 在几年的时间里 ...

  2. 基于 Vue.js 之 iView UI 框架非工程化实践记要

    像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引用一下,不需要就删除.故观念使然,尽管 Nuget 和 Maven ...

  3. 开发模式 MVC、MVP、MVVM和MVX框架模式

    MVX框架模式的了解 MVX框架模式:MVC+MVP+MVVM 1.MVC: Model(模型)+View(视图)+controller(控制器),主要是基于分层的目的,让彼此的职责分开.View通过 ...

  4. 基于NodeJS的14款Web框架

    摘要: 在几年的时间里,Node.js逐渐发展成一个成熟的开发平台,吸引了许多开发者.有许多大型高流量网站都采用Node.js进行开发,像PayPal, 此外,开发人员还可以使用它来开发一些快速移动W ...

  5. Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)

    jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...

  6. 基于 Vue.js 之 iView UI 框架非工程化实践记要 使用 Newtonsoft.Json 操作 JSON 字符串 基于.net core实现项目自动编译、并生成nuget包 webpack + vue 在dev和production模式下的小小区别 这样入门asp.net core 之 静态文件 这样入门asp.net core,如何

    基于 Vue.js 之 iView UI 框架非工程化实践记要   像我们平日里做惯了 Java 或者 .NET 这种后端程序员,对于前端的认识还常常停留在 jQuery 时代,包括其插件在需要时就引 ...

  7. 第三篇 基于.net搭建热插拔式web框架(重造Controller)

    由于.net MVC 的controller 依赖于HttpContext,而我们在上一篇中的沙箱模式已经把一次http请求转换为反射调用,并且http上下文不支持跨域,所以我们要重造一个contro ...

  8. 第二篇 基于.net搭建热插拔式web框架(沙箱的构建)

    上周五写了一个实现原理篇,在评论中看到有朋友也遇到了我的问题,真的是有种他乡遇知己的感觉,整个系列我一定会坚持写完,并在最后把代码开源到git中.上一篇文章很多人看了以后,都表示不解,觉得不知道我到底 ...

  9. 基于.net搭建热插拔式web框架(实现原理)

    第一节:我们为什么需要一个热插拔式的web框架? 模块之间独立开发 假设我们要做一个后台管理系统,其中包括“用户活跃度”.“产品管理”."账单管理"等模块.每个模块中有自己的业务特 ...

随机推荐

  1. 相对于父元素的fixed定位的实现

    问题描述 之前在项目中,遇到了一个场景,需要实现相对于父元素的fixed定位:在父元素内拖动滚动条时,"fixed"定位的元素不能滑动,在外层拖动滚动条时,父元素及父元素内的所有元 ...

  2. pip更换国内源

    学习Python开发,据说pip是很好用的一个Python包管理工具,于是尝试使用,但源异常慢,于是切换至国内的源(清华源). 在~/.pip/pip.conf (如果没有此文件则自行新建) 内容 [ ...

  3. IPv6下网络编程socket, TCP和UDP例子,以及兼容IPV4和IPV6的类

    一.TCP socket ipv6与ipv4的区别 服务器端源代码如下: #include <stdio.h> #include <stdlib.h> #include < ...

  4. mysql 地理位置定位

    SET @pt2 = ST_GeomFromText('POINT(116.405289 39.904987)'); SELECT *,ST_Distance_Sphere(ST_GeomFromTe ...

  5. 将JSON数据转换成JAVA的实体类

    思路:首先将JSON格式的数据转换成JSONObject,然后将JSONObject转换成Java的实体类(其中类属性包括List等类型) Java实体类: SearchFilter 类 1 publ ...

  6. log4j控制台乱码解决办法

    1.控制台编码问题 这两天碰到一个问题,在windows启动tomcat的时候tomcat控制台日志突然乱码了, 我发现在log4j.properties文件中加了一行配置log4j.appender ...

  7. fcitx4.2.0自定义中文标点符号

    +fcitx 定制标点 http://forum.ubuntu.com.cn/viewtopic.PHP?t=376701&p=2755636 下载punc.mb.gz放到~/.config/ ...

  8. vue-学习系列之vue双向绑定原理

    一.访问器属性 访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过 defineProperty() 方法单独定义. var obj = { }; // 为obj定义一个名为 hel ...

  9. docker安装镜像

    CMD 容器启动命令 CMD指令用于为执行容器提供默认值.每个Dockerfile只有一个CMD命令,如果指定了多个CMD命令,那么只有最后一条会被执行,如果启动容器的时候指定了运行的命令,则会覆盖掉 ...

  10. 关于SGA中的granule size

    1.什么是granule? granule直译为颗粒,ORACLE为SGA 中的组件(eg:log buffer/db buffer/large pool等)分配的最小单元为一个granule. 所以 ...