fis3+jsptpl 开发组件实践
组件化,就是方便别人二次使用。js,css 模块组件化,已经很成熟,但一个业务模块组件化,也许方案就百花齐放了
问题
业务组件包含 js,css,html。别人使用组件,需要先引用js,再引用css,还要拷贝html。相当麻烦
解决方案
vue,react,angular 前端框架。再框架规则上开发组件,可以很好的复用
但我们有些项目是并不是这些框架的项目,一旦使用这些框架,拿模块也就限定了只能再这个框架上使用了。
框架本身比较大,我们只是开发了一个弹窗组件,最后要引入一个vue ,有点不划算
踩过的一些坑
我们想过,把html 弄成字符串,css,弄成字符串,拷贝到js 中,这样模块就是一个js 文件了。但试过的人都知道。维护性....
最理想的方法是:html,css,js 还是单独开发,最后通过打包工具打在一起。
解决这个问题这也是这篇文章的主题了,下面介绍一下
组件 html+css
我们新建一个文件 card.tpl (后缀无所谓,随便取)
里面包含组件的html,和css等
card.tpl
<tmplate name="gdpanel">
<div class="gd-panel">
<div class="gd-title">${title}</div>
<div class="gd-leftbar">
<ul>
<c:forEach items="${leftlist}" var="item">
<li>${item}</li>
</c:forEach>
</ul>
</div>
<div class="gd-list">
<ul>
<c:forEach items="${datalist}" var="d">
<li>
<div class="col-num" style="height:${d.per}%">
<div class="per-num">${d.num}</div>
</div>
</li>
</c:forEach>
</ul>
</div>
</div>
</tmplate>
<style type="text/scss">
body, ul, li {
margin: 0px;
padding: 0px;
list-style: none;
}
.gd-panel {
width: 500px;
height: 250px;
// 还有好多样式,先省略...
}
</style>
业务js,模块暴露api
demo.js
/**
* 引入组件 html,css
* */
__inline("card.tpl");
/**
* 传入 组件xuanran
* @funciton gdCard
* @param {Element} el 组件父容器
* @return {Object} data
* data[title] {String} 组件标题
* data[datalist] {Array} 原始数据list
* @constructor
*
* */
function gdCard(el, data) {
var edata = this.exchangData(data);
console.log(edata);
var str = TPL.getTpl("gdpanel")
// 获取模板对象
var strtmpl = new jsptpl(str);
// 模板与数据结合转换为字符串
var retstr = strtmpl.render(edata);
el.innerHTML = retstr;
console.log(retstr);
}
gdCard.prototype = {
constroctor: gdCard,
/**
* 将原始数据转换为 组件需要数据
* @param {Object} {title: "title", list: [89]}
* @return {Object} {title:"title",datalist:[{per:89,num:89}],leftlist:[100,75,50,25,0]}
*
* */
exchangData: function (data) {
var retdata = {};
var per = this.getPer(data.list);
var array = [];
for (var i = 4; i >= 0; i--) {
array.push(i * per)
}
var max = per * 4;
var objarray = [];
for (var i = 0; i < data.list.length; i++) {
var obj = {};
var tmp = data.list[i];
obj.num = tmp;
obj.per = (tmp / max * 100) | 0;
objarray.push(obj);
}
retdata["datalist"] = objarray
retdata["leftlist"] = array;
retdata["title"] = data.title;
return retdata;
},
/**
* 获取合适的阶差数值
* @param {Array} list [18, 8, 258, 86, 30, 25]
* @return {Number} 例如 传入最大258 则柱状最高为400 阶差为100
*
* */
getPer: function (list) {
var max = list[0];
for (var i = 0; i < list.length; i++) {
if (list[i] > max) {
max = list[i];
}
}
console.log(max);
var tmp = 10;
for (var i = 1; i < 10; i++) {
if (max / tmp > 10) {
tmp = tmp * 10;
} else {
break;
}
}
var per = max / tmp / 4;
var b = Math.floor(per)
var m = per % 1;
if (m > 0.5) {
b = b + 1;
} else {
b = b + 0.5;
}
return b * tmp;
}
}
fis3 配置
fis.match('*', {
release: false
});
fis.match('*(*.tpl)', {
release: "$1"
});
fis.match('*(*.js)', {
release: "$1"
});
var path = require('path');
fis.match("**.tpl", {
// 将模板文件解析为js 中html+css字符串,
parser: "jsptpl",// npm install fis3-parser-jsptpl --save
rExt: '.js',
})
fis.match('**.tpl:scss', {
rExt: 'css',
parser: [
// 官方的 node-sass 不好用,不支持node7以上了,自己封装了一个
fis.plugin('nodev8-scss', {})
],
});
// 设置产出目录
fis.match('/test/*{.tpl,.js}', {
deploy: fis.plugin('local-deliver', {
to: path.join(__dirname, './dist/')
})
});
配置号后,dist 文件夹就回产出,整个模块了,一个js 包含html,js,css。与各种框架无关。随引随用
使用
新建一个 demo.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsptpl demo</title>
</head>
<body>
<div id="main">
</div>
<!--jsp 模板引擎,主要是业务里面用了模板引擎,所以引了这个,这个不是必须的,和业务有关系-->
<script src="http://jsptpl.nln.me/dist/jsptpl.js"></script>
<!--组件js-->
<script src="../dist/demo.js"></script>
<script>
var data = {title: "各组待处理工单", list: [18, 8, 258, 86, 30, 25]}
var el = document.getElementById("main");
var cd = new gdCard(el, data);
</script>
</body>
</html>
demo查看地址
demo 源代码查看
jsptpl 模板引擎介绍
fis3-parser-jsptpl 基于fis3 组件化开发工具,git 地址