UNPKG

react-admin-lte

Version:

简单封装的 AdminLTE react 类库,并包含一个编译配置。

608 lines (423 loc) 13.5 kB
# AdminLTE 模板的 react 化 [AdminLTE](https://github.com/almasaeed2010/AdminLTE) 是后台管理模板! 本项目就是将他常用的 html 进行了 react 化,项目本身并未包含 AdminLTE 的任何内容,css,js 等需要你从你的项目中引入。 使用方法 ``` npm i react-admin-lte --save-dev ``` UI 组件的导入方式是: ```javascript import DataTable from 'react-admin-lte/lib/DataTable'; ``` ## 目录 * [正确的打开方式](#right-way) * [在 webpack 的 config 中使用 Make](#make) * [热开发] (#hot-dev) * [Tools 工具集](#tools) --------- * [LayoutMain 主模板](#layout-main) * [PanelList 列表框](#panel-list) * PanelEdit 编辑框 * [DataTable 数据表](#datatable) * Pager 分页器 * [LoginBox/RegisterBox 登录框/注册框](#login-box) * Dialog * [UserAvatarMenu 用户头像菜单](#user-avatar-menu) --------------- * [InputRadio](#input-radio) * [InputSelect](#input-select) * [InputText](#input-text) * [InputDateRange](#input-daterange) 以上组件都带有 label 属性,可以输入类似这样的 html ```html <div class="form-group"> <label for="goods_info" class="col-sm-2 control-label">设备信息</label> <div class="col-sm-10"> <textarea class="form-control" id="goods_info" rows="4" name="goods_info" placeholder="设备信息"></textarea> </div> </div> ``` 并且提供了一个方便的事件属性: onValueChange(key, value) key 是控件的 name 属性, value 是值,string 类型。 双向绑定的时候,建议使用此方法。 没有特殊写明的还会有一个 onChange 的属性,这个是直接返回基础控件的 onChange 事件。 onChange(e) --------------- <a name="right-way" /> ## 正确的打开方式 在开发目录下建立一个 layout.html 模板, 因为在配置中使用了 HtmlWebpackPlugin 的 template: 'layout.html' 了。 建议使用路由 react-router bla.. 等我把手里的项目忙完,再写个例子传到这个 git 上。 <a name="make" /> ## 在 webpack 的 config 中使用 Make 这个包内置了一个 webpack 的配置文件,只需要在 webpack config 中引用 Make。 部署环境下只需运行 webpack ```javascript const Make = require("react-admin-lte").Make; const path = require('path'); const devPath = path.resolve('./dev'); var mm = new Make({ devMode : false, devPath : devPath, buildPath: path.resolve('./dist'), libAlias : { AdminLTE : path.join(devPath, 'res/lib/AdminLTE/'), bootstrap: path.join(devPath, 'res/lib/bootstrap/') } }); module.exports = mm.createWebpackConfig(); ``` <a name='hot-dev' /> ## 热开发模式 请看例子 //index.js ```javascript var cloudoll = require('cloudoll'); var serve = require('koa-static'); var middles = [ ]; if (process.env.debug) { console.log("react 热加载启动"); const path = require('path'); const Make = require("react-admin-lte").Make; const webpack = require("webpack"); const devPath = path.resolve('./dev'); var mm = new Make({ devMode: true, devPath: devPath, buildPath: __dirname, libAlias: { AdminLTE: path.join(devPath, 'res/lib/AdminLTE'), bootstrap: path.join(devPath, 'res/lib/bootstrap') } }); let webpackConf = mm.createWebpackConfig(); webpackConf.resolveLoader = { root: path.join(__dirname, 'node_modules') }; let compiler = webpack(webpackConf); var webpackDevMiddleware = require("koa-webpack-dev-middleware")(compiler, { hot: true, noInfo: false, publicPath: webpackConf.output.publicPath, headers: { "X-Custom-Header": "yes" }, stats: { colors: true } }); middles.push(webpackDevMiddleware); var hotMiddleware = require('koa-webpack-hot-middleware')(compiler); middles.push(hotMiddleware); } else { // 生产模式下,这部分内容会被 nginx 代理,所以这个中间件是多余的。 middles.push(serve('./dist')); } var app = new cloudoll.KoaApplication({ middles: middles }); ``` <a name="tools" /> ## Tools 工具集 * Tools.parseRouter() 可以直接从 window 对象中解析出路径和 router。 ```javascript //URL 是 "http://localhost:3000/#/login?a=1&b=2"; Tools.parseRouter() ``` 返回值为: ```javascript { path: '/login', query: { a: "1", b: "2" } } ``` ------------- <a name="layout-main" /> ## LayoutMain 主模板 和 Dashboard 一样,改了个名字,现在把 Dashboard 废弃... 示例: ```jsx <LayoutMain logoMini={<string>U<sup>+</sup></string>} logoLarge={<div>U<sup>+</sup> 优服务</div>} topMenus={topMenus} mainSidebarContent={<MainMenus/>} rightContent={rightContent} footerContent="版权所有 @ 合一集团" > {this.props.children} </LayoutMain> ``` <a name="datatable" /> ## DataTable 数据表 这是数据表格 ```javascript import DataTable from 'react-admin-lte/lib/DataTable'; ``` 删除和修改的行操作已经内置。 onItemEdit, onItemDel 均绑定了一个主键_id/id 作为第一个参数。 onMoreActionHandle 是自定义按钮的事件,绑定了两个参数 id/_id 和 tag。具体参考下面的说明。 ```jsx <DataTable cols={renderCols} list={this.state.list} onItemEdit={this.edit} onItemDel={this.onItemDel} noFooter={true} noDel={false} noEdit={true} actionColStyle={myStyles.actionSize} onMoreActionHandle={this.onMoreActionHandle} moreActions={ [{ tag: 'aprrove',label: '审批', iconClass: 'fa fa-thumbs-up' }] } /> ``` 上面的例子中的 onItemDel 如下: ``` onItemDel(_id) { console.log(_id); } ``` ### 如何 render 数据? 首选,你需要一个 list, 这个list 可能是你从远程 ajax 中查询回来的。格式如下: ```javascript [ {_id: 1, b: "x"} {_id: 2, b: "y"} {_id: 3, b: "z"} ] ``` 需要注意,这个list 中必须包含 id 或者 _id,否则,主键传不出来。 然后,你要指定你需要 render 的 列 ```javascript let renderCols = { _id : "编号", b : "列名" }; ``` 如果要格式化显示,那么需要指定 format 函数,请看下面的例子: ```javascript let renderCols = { happend_date : { label: '日期' }, xamount : { label : '未收款', format: function (obj) { if (!obj) { return 0 } var xsum = obj.list.reduce(function (prev, curr) { return prev + curr.amount }, 0); return <label className="text-red">¥{xsum.toFixed(2)}</label> } } } ``` 还有一个让整行参与计算的参数哦,fullData: true。 ```javascript xtotal: { label: '小计', fullData: true, format: function(trData){return sum(trData);} } ``` ### 如果需要自定义按钮? 使用 moreActions 参数: ```javascript [ { tag: 'aprrove',label: '审批', iconClass: 'fa fa-thumbs-up' } ] ``` 这个按钮对应的事件是: onMoreActionHandle 按照上面的例子,事件函数的例子如下: ```javascript onMoreActionHandle(_id, tag) { console.log(_id, tag); if (tag == 'approve'){ //这里做审批按钮的事儿。 } } ``` 其中 _id 是数据的主键,tag 是你在按钮中指定的 tag。 ### 如果某些行需要隐藏某些操作按钮呢? 指定 hideHandle 就可以了。 ```javascript { tag: 'aprrove', label: '审批', iconClass: 'fa fa-thumbs-up', hideHandle: function(ele){ if (ele.xxx) { return true; } return false; } } ``` noFooter={true} 可以指定不渲染底部的表头 footerRows 属性可以自定义底部表格,比如显示个小计什么的。 <a name="login-box" /> ## LoginBox/RegisterBox 登录框/注册框 ```jsx <LoginBox title="大阿里" vtitle="登录吧,骚年,进入享受你的权利!" onLogin={this.login}> <p>注册,点击这个连接</p> <p>忘记密码,点击这个连接</p> </LoginBox> ``` ```jsx <RegisterBox title={<a href="#/"><b>A<sup>+</sup></b> 大阿里</a>} vtitle="没有帐号吗?来注册吧!" onRegister={this.register} > <br/> 我有帐号呢,现在 <a href="#/login" className="text-center">登录。</a> </RegisterBox> ``` 登录框的按钮事件是 onLogin(passport, password, rememberMe) 注册框的按钮事件是 onRegister(email, mobile, nick, password) <a name="panel-list" /> ## PanelList 列表框 列表框包含了分页控件,创建按钮,搜索区域等。 搜索区域需要自定义。 通常 列表框里会 包含一个数据显示的组件 DataTable ```jsx <PanelList onCreate={this.create} searchPanel={ <div className="has-feedback"> <input type="text" className="form-control input-sm" name="qKeyword" onChange={this.handleTextChange} placeholder="输入搜索,然后等等"/> <span className="glyphicon glyphicon-search form-control-feedback"/> </div> } limit={this.state.limit} skip={this.state.skip} total={this.state.total} onPagerChange={this.pagerChanged} > <DataTable cols={ renderCols} list={this.state.list} onItemEdit={this.edit} onItemDel={this.del} actionColStyle={myStyles.actionSize} /> </PanelList> ``` <a name='user-avatar-menu' /> ## UserAvatarMenu 用户头像菜单 示例 ```jsx <UserAvatarMenu cookie={cookie} userMenus={[ { label: "粉丝", href: "#fans" }, { label: "关注", href: "#fowllers" }, { label: "朋友", href: "#friends" } ]} profileUrl="#profile" nick="啤酒云" slogan="不会做饭的歌手不是好程序员。" avatar="http://www.maczapp.com/uploads/icons/mac_20130504102327_2f0330fff1.png" /> ``` 会输出如下的 html 代码, 通常放在 顶部菜单里 ```html <li class="dropdown user user-menu"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" aria-expanded="true"><img src="http://www.maczapp.com/uploads/icons/mac_20130504102327_2f0330fff1.png" class="user-image" alt="啤酒云"><span class="hidden-xs">啤酒云</span></a> <ul class="dropdown-menu"> <li class="user-header"><img src="http://www.maczapp.com/uploads/icons/mac_20130504102327_2f0330fff1.png" class="img-circle" alt="啤酒云"> <p> <!--react-text: 26 -->啤酒云 <!-- /react-text--><small>不会做饭的歌手不是好程序员。</small></p> </li> <li class="user-body"> <div class="row"> <div class="col-xs-4 text-center"><a href="#fans">粉丝</a></div> <div class="col-xs-4 text-center"><a href="#fowllers">关注</a></div> <div class="col-xs-4 text-center"><a href="#friends">朋友</a></div> </div> </li> <li class="user-footer"> <div class="pull-left"><a href="#profile" class="btn btn-default btn-flat">我的资料</a></div> <div class="pull-right"><a class="btn btn-default btn-flat">退出</a></div> </li> </ul> </li> ``` 属性有: nick, avatar, slogan, profileUrl, userMenus, cookie 其中 userMenus 的格式为 ```javascript [ {label: "粉丝", href: "#fans"}, {label: "关注", href: "#fowllers"}, {label: "朋友", href: "#friends"} ] ``` cookie 是 这个 库: https://github.com/florian https://github.com/florian/cookie.js 如果指定了 cookie 这个属性,那么会在 logout 中自动移除 ticket 这个 cookie (这个是 cloudark 体系中约定的用户票据)。 ```javascript var cookie = require('your/path/to/this/lib/cookie'); ``` 属性事件有: onLogout() ----------------- <a name="input-datetime" /> ## InputDatetime 这是一个可以选择时间的日期选择器,参考 https://github.com/YouCanBookMe/react-datetime 别忘记引入 css,还有 中文的话,需要引入 moment 的 locales 。 此控件不提供 onChange 事件属性 <a name="input-radio" /> ## InputRadio radio 输入框 属性: onValueChange(key, value) options json数组,示例: ``` [ { label: '上门', value: 1 }, { label: '邮寄维修', value: 2 } ] ``` value 可以直接指定此值,将会默认选中。 <a name="input-select" /> ## InputSelect select 输入框 ``` <InputSelect name="test" multiple={false} value="21" options={[ { label: '上门', value: 1 }, { label: '邮寄维修', value: 2 }, { label: '上门1', value: 11 }, { label: '邮寄维修1', value: 12 }, { label: '上门2', value: 21 }, { label: '邮寄维修2', value: 22 } ]} onValueChange={ function (key, val) { console.log(key, val); } } /> ``` 属性: * multiple boolean 是否可以多选 * value(defaultValue) 如果是多选则是数组,单选则是字符串 如果没有指定 options 属性,那么就取 children。 <a name="input-daterange"/> # InputDateRange 这是一个可以选择日期范围的控件 onValueChange 的 value 参数是一个数组,第一个是开始日期, 第二个是结束日期 ``` onValueChange(key, value){ console.log("开始日期", value[0]); console.log("结束日期", value[1]); } ```