Content Table

襁褓中的系统界面

是否还记得在开始的时候我们说过:

  • 给我一个 QPainter,我也能实现整个操作系统的图形界面
  • 操作系统的界面本质也是**画(Hua)**出来的
  • 图形界面的本质都是一样的,就是一张静态的画
  • 点击按钮,看到按钮动了

这里我们就用 QPainter 绘图来模拟实现一个系统的界面原型,为了简单说明问题,只绘制了 Button 和 CheckBox,其他的控件同理。当然 Button 是能够点击的,点击 CheckBox 也能够切换选中状态,没有点击到 Button 和 CheckBox 的时候它们不会接收到鼠标事件,点击一个控件也不会影响另一个控件,效果如下图:

异常处理

SpringMVC 提供了 3 种异常处理方法:

  1. 使用 @ExceptionHandler 注解实现异常处理
  2. 简单异常处理器 SimpleMappingExceptionResolver
  3. 实现异常处理接口 HandlerExceptionResolver,自定义异常处理器

通过比较,实现异常处理接口 HandlerExceptionResolver 是最合适的,可以给定更多的异常信息,可一自定义异常显示页面等,下面介绍使用这种方式处理异常。

服务器端参数验证

服务器端接收到前端传递过来的参数后,很多情况下如果不做校验就直接使用是非常危险的,例如造成 XSS 攻击,把无效数据保存到数据库导致业务出错等。传统的参数校验方式一般是取得每一个参数,然后一个一个的使用 if else 和规则比较进行校验,这样就会有大量的、简单重复的校验代码散布在代码中,不利于维护和阅读。这里介绍使用注解,根据 JSR-303 Validation 进行参数验证。

当我们在 SpringMVC 中需要使用到 JSR-303 的时候就需要我们提供一个对 JSR-303 规范的实现,Hibernate Validator 实现了这一规范,下面将以它作为 JSR-303 的实现来讲解 SpringMVC 对 JSR-303 的支持。

使用方法:

  • Bean 中使用 @NotNull 等定义验证规则
  • Controller 中使用 @Valid 进行参数校验
  • 如有参数错误,则返回错误信息给客户端

自定义类型与 QVariant

QVariant 非常重要,可以存储很多种不同的类型,例如 int, QString, QRect, QPoint 等,其构造函数有很多个,参数是很多种不同的常用类型,还内置了可以直接转换 QVaraint 到某些类型的函数,如 toInt(), toString(), toPoint(), toSize() 等,还是 QObject 动态 property 机制的关键,除了支持内置的类型外,QVariant 还被设计成可以存储我们自己定义的类型。

关键术语:

  • Q_DECLARE_METATYPE
  • qRegisterMetaType
  • qRegisterMetaTypeStreamOperators
  • operator QVariant()

使用 LESS 代替 CSS

使用 Less 最直接的好处是可以使用层级的风格写样式,当然它还可以定义变量、函数等,比 CSS 好管理,而且语法和 CSS 差别不大,这里介绍 HTML 里使用 Less 代替 CSS:

方法一: less.js 解析 Less 文件为 CSS

  1. 写 Less 样式

  2. HTML 中引入 Less 文件

    1
    <link href="style.less" rel="stylesheet/less" type="text/css"/>
  3. HTML 中引入 less.js,它的作用是把上面引入的 Less 文件解析为 CSS,放到 HTML 的 head 中,less.js 会自动的把 Less 样式翻译为 css

    1
    <script src="https://cdn.staticfile.org/less.js/2.7.1/less.min.js"></script>

方法二: Atom 在保存 Less 文件时自动编译为 CSS 文件

使用 Atom 的插件 less-autocompile,在保存 less 文件时 Atom 会自动生成对应的 css 文件,那么就可以直接在 HTML 里引用 css 了,这样就不需要担心像上面这个方法造成的性能,网络访问等问题了,90% 的情况下没啥问题,只是理论上的问题而已。

需要在 Less 文件的第一行添加下面的内容,告诉生成文件的路径,规则等:

1
2
3
4
5
6
7
8
9
10
11
// out: style.css, sourcemap: false, compress: false

// 定义变量
@borderWidth: 2px;
@borderColor: #BBB;

.card {
padding: 10px;
border: @borderWidth solid @borderColor;
border-radius: 4px;
......

Semantic Ui Validation

Semantic Ui 自带了表单验证功能,使用起来很简单:

  • 可以使用预定义的校验函数
  • 可以自定义校验函数
    • 自定义校验函数里发送同步的 AJAX 请求使用服务器端进行参数校验
  • 可以自定义错误提示
  • 可以在 onSuccess 中禁止表单自动提交,然后使用 Ajax 提交

Semantic Ui Tab

Semantic Ui 中创建 Tab,需要 2 步:

  1. 定义 Tab 的 HTML 结构

    关键是 .item.tab 中的属性 data-tab 的定义,用于关联跳转

    有 class active 的 .item 和 .tab 是当前的 Tab,其他的隐藏

  2. JS 实现点击切换 Tab

Semantic Ui 侧边栏

侧边栏在页面打开后就一直存在需要使用 class visible,并且间隔和内容区域的间隔不要太大,可以使用 CSS 调整一下 pusher 的 translate3d 的位置,icon menu 的文本都是居中的,如果不想居中,也需要自己调整,效果如下