ext5的主题是用SASS(点击进入)和Compass(点击进入)编写的。
在ext5中,仅仅通过更改SASS的变量值,就可以将几乎所有的组件样式定制了,包括颜色,字体,边框,背景。
本文介绍了如何创建一个在多应用中可分享的定制化主题。
这是一个命令行工具,用于部署Ext JS应用,创建一个Ext JS 5主题,你必须拥有Sencha Cmd 5 或更高版本
注意:Sencha Cmd 5 已经预安装了SASS和Compass,如果你的电脑已经安装了,请卸载掉自己的。
安装ruby环境(点击进入) 用1.9.3版本
如果你本地有Ext JS SDK,解压后在本地路径下执行Cmd命令就行。
不过我们已经不用下载Ext JS 了,你可以用“-ext”命令来自动下载最新版的Ext JS 5!我们这次就用这个命令来做。
如上所述 你需要安装ruby,cmd工具,就可以开始制作主题了
第一步是用Sencha Cmd创建一个你自己的工作空间
cd /d E:\ext
sencha generate workspace-ext my-workspace
如果你想使用一个下载好的SDK或本地的一个SDK副本,在命令前面加上你解压的Ext JS SDK的路径就可以了
sencha -sdk~/sencha-5.0.0 generate workspace my-workspace
cd my-workspace
如图:
“ext” --- 包含了Ext JS SDK
“packages” --- EXT JS语言环境和主题包
我们来生成一个App,在这个基础上来制作主题,在“my-workspace”路径下,用下面的命令来生成一个Ext JS应用的骨架:
sencha -sdk ext generate app ThemeDemoApp theme-demo-app
现在,我们生成了一个名字为ThemeDemoApp的应用,路径(也就是文件夹)为theme-demo-app。这个应用将用"ext"文件夹下的js文件作为引用源。
现在的结构为
theme-demo-app里面的结构为
进入后 用下面的命令启动app服务器 用网页查看
cd theme-demo-app
sencha app watch
这里有两种方式查看你的app:
打开"my-workspace/theme-demo-app/index.html"
方便调试,代码未压缩,我们的教程用的是这个模式。
运行命令
sencha app build
构建后,你可以用浏览器在下面的路径找到你的应用
my-workspace/build/production/ThemeDemoApp/index.html
使用压缩后的源文件,性能更好
在 theme-demo-app 文件夹下,运行
sencha generate theme my-custom-theme
它告诉senchacmd 生成一个名字为my-custom-theme的主题包
就在my-workspace\packages路径下
l "package.json" --- 包属性文件,它告诉 Sencha Cmd 这个包的一些信息,如 包名,版本,依赖(本包对其他包的依赖)等
l "sass/" --- 所有的主题SASS文件,里面分三部分:
n "sass/etc/" ---额外的工具函数或混入mixins
n "sass/src/" --- SASS规则和调用定义在“sass/var/”中的变量的UI mixin
n "sass/var/" --- SASS变量
"sass/var/" 和 "sass/src"是结构化的,也就是说,是按照你编写样式组件的类路径方式来匹配的。举个例子,更改Ext.panel.Panel外观的变量应该放在一个文件名为"sass/var/panel/Panel.scss"的文件中
l "resources/" --- 图片和其它静态资源
l "overrides/" --- 包含任意修改主题组件类所需覆写的js
每一个主题包都继承自基本主题包,你创建自己的主题首先要指出你继承自哪个主题,你能从my-workspace\ext\packages路径下看到所有的主题包
"ext-theme-base"
"ext-theme-neutral"
"ext-theme-neptune"
"ext-theme-crisp-touch"
"ext-theme-crisp"
"ext-theme-crisp-touch"
"ext-theme-classic"
"ext-theme-gray"
"ext-theme-aria"
我们的自定义主题应该继承哪一个作为开始呢?我们的建议是使用
"ext-theme-neptune" 或"ext-theme-classic"作为起点,因为这些主题包含所有创建一个有吸引力的主题的必要代码。Neutral主题是一个比较抽象的主题,不容易直接继承。覆写一个Neutral主题可能需要你数个小时的工作,更改数百个变量值,而用一个neptune或classic主题你可能只需要花几分钟更改数个变量。当然,gray或aria主题也是相当不错的选择。
这个教程中,我们创建一个继承Neptune主题的自定义主题。打开
“packages/my-custom-theme/package.json”文件,找到
"extend": "ext-theme-classic"
更改为
"extend":"ext-theme-neptune"
刷新app,这样保证正确的主题js文件包含到bootstrap.js中了,运行刷新命令
sencha app refresh
好了 现在你的主题变成了Neptune主题了,你可以在
my-workspace\ext\packages\ext-theme-neptune中进行修改样式,编译后可看主题(编译在后面讲到)
首先讲解一下几个重要的命令行
sencha app watch
在app应用路径下执行。用于启动服务器,一旦启动,它将监控你的应用更改并自动构建和刷新你的应用。
Sencha app build
在app应用路径下执行。更改应用的某些参数后,需要重新构建一下来把参数导入
Sencha app refresh
在app应用路径下执行。更改内容写入bootstrap.js中,咱们这里是更改主题配参后运行一下。
Sencha package build
在主题包路径下执行。更改主题包某些参数后,需要重新构建
好,首先让我们先把默认主题更改为我们的自建主题
路径:theme-demo-app/app.json
/**
* The nameof the theme for this application.
*/
"theme": "ext-theme-neptune",
更改为
/**
* The nameof the theme for this application.
*/
"theme": "my-custom-theme",
我们把neptune主题包更改为了我们自定义的主题包,ext会自己去my-workspace下的package里面寻找。
让我们来修改一个变量---base color。
在 "my-custom-theme/sass/var/"中创建一个文件 Component.scss,增加如下代码
$base-color: #317040!default;
后面加!default提高其优先级,因为Sencha Cmd变量文件读取是“反向”的,先读取衍生主题,最后是base主题。更多的!default用法参见 Variable Defaults
完整的ext js全局SASS变量列表参见Global_CSS.
现在你已经修改了自有主题的base color,你需要为你的主题构建一个包含所有样式规则的升级版本css文件。到路径packages/my-custom-theme/下,运行
sencha package build
构建包将创建一个“build”文件夹,在"my-custom-theme/build/resources"中,你将找到一个 my-custom-theme-all.css,这个文件包含你的主题的所有组件的样式规则。你可以直接在你的应用中链接它,但是这样做并不推荐,因为“all”文件包含了每一个ext组件的所有样式,而许多app应用仅仅用了组件库中的子集,如果你想这么做,首先请先在你的应用中更改参数,指定好应用具体使用哪个主题,再开始构建,这样sencha cmd会自动过滤掉未使用的css样式规则。
接着我们来构建一下my-custom-theme,因为刚才我们更改了
theme-demo-app/app.json文件,并没有构建
到theme-demo-app路径下,运行
sencha app build
启动sencha app watch,刷新浏览器"theme-demo-app/index.html"。
你应该看到了更改的样子了。
背景变绿了
每一个Ext JS组件都有一系列的主题全局变量可供你修改。让我们来改变panel headers的font-family。创建文件 "packages/my-custom-theme/sass/var/panel/Panel.scss"
,增加如下代码
$panel-header-font-family: Times New Roman!default;
运行
sencha app build
可以看到字体变化了
注:其实这里我测试后发现这里字体是不会发生变化的,panel只有加了frame后 字体才会发生变化
Ext中 每个组件都拥有自己的UI设置参数,缺省下都是default,这个属性可以给予单独实体组件拥有自己的UI配参,可以让你在同一类型组件下给予不同的样式,比如,panel的“default UI”是黑蓝色的header,但它的“light UI”中,header是亮蓝色的,button也用UI来制作不同于普通按钮的工具条按钮。
Neutral主题为各种组件提供了很多SASS mixins混入,你可以用这些mixins来生成新的UI,这可以从API中找到它们,如,Ext.panel.Panel中,找到“CSS Mixins”部分,看看mixins需要哪些参数,现在,让我们来用mixins来创建一个Panel UI,创建一个文件packages/my-custom-theme/sass/src/panel/Panel.scss,写入如下代码
@include extjs-panel-ui(
$ui-label: 'highlight-framed',
$ui-header-background-color: red,
$ui-border-color: red,
$ui-header-border-color: red,
$ui-body-border-color: red,
$ui-border-width: 5px,
$ui-border-radius: 5px
);
这段代码创建了一个新Panel UI ,名称为highlight-framed,为了在项目中使用它,把Panel中的ui属性设置为highlight(“-framed”这个后缀在你把frame属性设置为true时会自动添加上)
打开"theme-demo-app/app/view/Main.js",替换一下代码:
items: [{
// custom "highlight" UI
xtype: 'panel',
ui: 'highlight',
frame: true, // Make sure to add thisconfig to see the frame highlight changes
bind: {
title: '{name}'
},
region: 'west',
html: '- This area isused for navigation, for example, using a "tree"component.
',
width: 250,
split: true,
tbar: [{
text: 'Button',
handler: 'onClickButton'
}]
},{
region: 'center',
xtype: 'tabpanel',
items:[{
title: 'Tab 1',
html: 'Content appropriatefor the current navigation.
'
}]
}]
效果如下:
虽然UI mixin是一个方便的方式为一个组件配置多个表象,他们不应该被过度使用。每个调用UI mixin生成额外的CSS规则。随意调用UI mixin可能产生过大的CSS文件。
另一个重要的一点要记住当调用UI mixin时,是通过其命名参数调用mixin,而不是参数值的有序列表。尽管SASS支持两种形式,但是最好使用这种形式:
@includeextjs-component-ui(
$ui-foo: foo,
$ui-bar: bar
);
而不是
@includeextjs-component-ui(foo, bar);
所有的图片资源缺省下都继承自父主题,我们可以通过覆写方式来实现,把想覆写的图片放在"my-custom-theme/resources/images/中,给它们父主题中同样的名字即可。如,让我们改变MessageBox 组件的info icon,把下面的图片保存起来
"packages/my-custom-theme/resources/images/shared/icon-info.png"
在"theme-demo-app/app/view/Main.js"中写代码把其显示出来
...
tbar: [{
text: 'Button',
handler: 'onClickButton'
}],
items: [{
xtype: 'button',
text: 'Show Message',
handler: function() {
Ext.Msg.show({
title: 'Info',
msg: 'Message Box with customicon',
buttons: Ext.MessageBox.OK,
icon: Ext.MessageBox.INFO
});
}
}]
...
运行
sencha app build
看效果
覆写js的属性十分简单,让我们试着把Panels中的属性 titleAlign更改一下。
创建"packages/my-custom-theme/overrides/panel/Panel.js",写如下代码
Ext.define('MyCustomTheme.panel.Panel',{
override: 'Ext.panel.Panel',
titleAlign: 'center'
});
在 "packages/my-custom-theme/"路径下,运行
sencha package build
这是为了让 "packages/my-custom-theme/build/my-custom-theme.js"包含最新的覆写。
在"theme-demo-app"路径下,运行
sencha app refresh
这是为了覆写主题被包含进正在运行的项目。
现在在"theme-demo-app"路径下,重新构建项目
sencha app build
可以起服务看效果了 panel headers文字居中了~
如上所述,Sencha Cmd查找文件“sass / var”和“sass / src”相匹配的JavaScript类。
对于主题,在默认情况下,Ext名称空间被认为是顶级名称空间,所以主题的“sass/src/panel/Panel.scss”对应于 Ext.panel.Panel
对于Ext以外的主题名称空间,你必须改变在".sencha/package/app.json"中的名为package.sass.namespace的配置属性
为了统一配置 你需要这样写
/**
* Sass configuration properties.
*/
"sass": {
/**
* The root namespace to use when mapping*.scss files to classes in the
* sass/src and sass/var directories. Forexample, "MyApp.view.Foo" would
* map to"sass/src/view/Foo.scss". If we changed this to"MyApp.view" then
* it would map to"sass/src/Foo.scss". To style classes outside the app's
* root namespace, change this to"". Doing so would change the mapping of
* "MyApp.view.Foo" to"sass/src/MyApp/view/Foo.scss".
*/
/**
* "MyApp.view.Foo"对应"sass/src/view/Foo.scss",如果我们更改为"MyApp.view"
* 那么将对应"sass/src/Foo.scss",如果设置为"","MyApp.view.Foo"
* 将对应"sass/src/MyApp/view/Foo.scss"
*/
"namespace": ""
},
在这个设定中, Ext.panel.Panel对应的就是"sass/src/Ext/panel/Panel.scss"了
所有的自定义SASS都放在"sass/etc",你可以随意组织里面的代码,但是注意sencha cmd只构建 "sass/etc/all.scss",其他文件将导入到"all.scss"中,具体例子请参见"packages/ext-theme-base/sass/etc/“
这就是整个ext js 5的theme制作了,整个流程就是这样子的~