阅读本小节,你需要先了解webpack。
前面我们提到了 业务逻辑 与 视图逻辑 的分离,是为了解决JS逻辑过分膨胀的问题。通过前面的例子我们发现一个不够优雅的地方,那就是模板中使用的组件必须在组件逻辑中注入。其实模板要使用什么组件跟组件的逻辑没有一点关系,秉着业务逻辑与视图逻辑分离的原则,我们应该将组件的注入移入模板。
利用webpack可以很方便地做到。首先你需要安装以下编译工具
npm install webpack babel-core babel-loader \
babel-preset-env \
vdt vdt-loader --save-dev
如果你要使用修饰器decorator
已经类的静态属性static
等新语法,还需要使用以下包
npm install babel-preset-stage-0 babel-plugin-transform-decorators-legacy --save-dev
.babelrc
配置如下:
{
"presets": ["env", "stage-0"],
"plugins": [
"transform-decorators-legacy"
]
}
vdt-loader
vdt-loader用于将Vdt模板编译成模板函数,webpack配置如下:
module.exports = {
...
module: {
rules: [
{
test: /\.vdt$/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'vdt-loader',
options: {
// 去掉with语法
noWith: true,
// 去掉标签间的空白字符
skipWhitespace: true,
// 定义模板分隔符
// delimiters: ['{{', '}}']
}
}
]
}
]
}
...
};
将模板经过babel-loader
处理,我们可以在vdt
模板中使用es6语法
模板文件
有了vdt-loader,我们可以将vdt定义成单独的文件,并在模板中引入所需的组件。例如:user.vdt
定义如下:
// @file user.vdt
// 可以直接使用import引入模板所需依赖
import Button from './components/buttton';
import Menu from './components/menu';
<div>
<Button>按钮</Button>
<Menu />
</div>
然后user.js
文件中引入模板文件:
// @file user.js
import template from './user.vdt';
export defaults extends Intact {
@Intact.template()
static template = template;
// 或者,不使用static属性
// get template() { return template; }
}
除了在模板中引入组件外,你还可以引入另一个模板,例如,在继承layout.vdt
时:
import layout from './layout.vdt';
<t:layout>
<b:content>content</b:content>
</t:layout>
CSS文件
css文件,可以通过css-loader & style-loader
引入,如果你需要可编译css工具,例如:stylus,还可以使用stylus-loader
。首先安装它们。
npm install css-loader style-loader stylus-loader --save-dev
然后加入以下配置:
module.exports = {
...
module: {
rules: [
...
{
test: /\.(styl|css)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'stylus-loader',
options: {
'include css': true
}
},
]
}
]
}
...
};
在组件逻辑文件user.js
中引入样式文件,假设为user.styl
:
import template from './user.vdt';
import css from './user.styl';
...
你甚至可以在模板文件中引入样式文件,这对于纯模板组件很有用,例如:layout.vdt
需要定义全局样式,假设样式文件为layout.styl
:
// @file layout.vdt
import './layout.styl';
<div>
<b:content />
</div>