├── .babelrc
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── gulpfile.js
├── imgs
├── 1.jpg
├── 2.jpg
├── 3.jpg
├── 4.jpg
├── 5.jpg
├── 6.jpg
├── 7.jpg
└── 8.jpg
├── miniprogram_dev
├── app.js
├── app.json
├── app.wxss
├── components
│ ├── assets
│ │ ├── copy.wxss
│ │ └── icon.png
│ ├── common.wxss
│ ├── index.js
│ ├── index.js.map
│ ├── index.json
│ ├── index.wxml
│ ├── index.wxss
│ ├── lib.js
│ ├── lib.js.map
│ ├── reset.wxss
│ └── utils.js
├── package.json
├── pages
│ └── index
│ │ ├── config.js
│ │ ├── index.js
│ │ ├── index.json
│ │ ├── index.wxml
│ │ └── index.wxss
├── project.config.json
└── sitemap.json
├── miniprogram_dist
├── index.js
├── index.js.map
├── index.json
├── index.wxml
├── index.wxss
├── lib.js
└── lib.js.map
├── package.json
├── src
├── index.js
├── index.json
├── index.wxml
├── index.wxss
└── lib.ts
├── test
├── index.test.js
├── utils.js
└── wx.test.js
├── tools
├── build.js
├── checkcomponents.js
├── checkwxss.js
├── config.js
├── demo
│ ├── app.js
│ ├── app.json
│ ├── app.wxss
│ ├── package.json
│ ├── pages
│ │ └── index
│ │ │ ├── index.js
│ │ │ ├── index.json
│ │ │ ├── index.wxml
│ │ │ └── index.wxss
│ └── project.config.json
└── utils.js
└── tsconfig.json
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | ["module-resolver", {
4 | "root": ["./src"],
5 | "alias": {}
6 | }]
7 | ],
8 | "presets": [
9 | ["env", {"loose": true, "modules": "commonjs"}]
10 | ]
11 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | package-lock.json
4 |
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 |
11 | node_modules
12 | coverage
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .DS_Store
3 | package-lock.json
4 |
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 |
11 | test
12 | tools
13 | docs
14 | miniprogram_dev
15 | node_modules
16 | coverage
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 wechat-miniprogram
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # miniprogram-table-component
2 |
3 | 微信小程序自定义组件 - table组件 - 支持第三方npm包使用
4 |
5 | > 使用此组件需要依赖小程序基础库 2.2.2 版本,同时依赖开发者工具的 npm 构建。具体详情可查阅[官方 npm 文档](https://github.com/wechat-miniprogram/miniprogram-custom-component/blob/master/README.md)。
6 |
7 | ## table组件
8 |
9 | 实现了table的以下功能:
10 |
11 | - 1.基础表格
12 | - 2.带斑马纹表格
13 | - 3.带间隔边框表格
14 | - 4.自定义无数据的提示文案
15 | - 5.自定义表格头样式
16 | - 6.固定表头
17 | - 7.表格横向滑动
18 | - 8.自定义表格行和单元格样式
19 | - 9.某一行被点击时会触发对外事件
20 |
21 | ## 快速上手
22 |
23 | 一个简易的微信小程序 `table组件`诞生了。使用很简单,就是按照npm包和微信自定组件的用法使用。
24 |
25 | ### 1、安装和引入
26 | - 安装组件:
27 | ```
28 | npm install --save miniprogram-table-component
29 | ```
30 | - 引入table自定义组件
31 |
32 | 在页面的 json 配置文件中添加 recycle-view 和 recycle-item 自定义组件的配置
33 |
34 | ```json
35 | {
36 | "usingComponents": {
37 | "table-view": "../../../miniprogram_npm/miniprogram-table-component"
38 | }
39 | }
40 | ```
41 |
42 | > 注意:npm包的路径。如果这里遇到找不到包的问题,可以查看下方的 `微信小程序 npm 找到不到npm包的坑?`
43 |
44 | ### 2、使用table组件
45 |
46 | 在wxml页面需要用到的地方使用,如下:
47 |
48 | ```html
49 |
55 | ```
56 |
57 | 在js页面需要用到的地方使用,如下:
58 |
59 | ```javascript
60 | Page({
61 | /**
62 | * 页面的初始数据
63 | */
64 | data: {
65 | tableHeader: [
66 | {
67 | prop: 'datetime',
68 | width: 150,
69 | label: '日期',
70 | color: '#55C355'
71 | },
72 | {
73 | prop: 'sign_in',
74 | width: 152,
75 | label: '上班时间'
76 | },
77 | {
78 | prop: 'sign_out',
79 | width: 152,
80 | label: '下班时间'
81 | },
82 | {
83 | prop: 'work_hour',
84 | width: 110,
85 | label: '工时'
86 | },
87 | {
88 | prop: 'statusText',
89 | width: 110,
90 | label: '状态'
91 | }
92 | ],
93 | stripe: true,
94 | border: true,
95 | outBorder: true,
96 | row: [
97 | {
98 | "id": 1,
99 | "status": '正常',
100 | "datetime": "04-01",
101 | "sign_in_time": '09:30:00',
102 | "sign_out_time": '18:30:00',
103 | "work_hour": 8,
104 | }, {
105 | "id": 2,
106 | "status": '迟到',
107 | "datetime": "04-02",
108 | "sign_in_time": '10:30:00',
109 | "sign_out_time": '18:30:00',
110 | "work_hour": 7,
111 | }, {
112 | "id": 29,
113 | "status": '正常',
114 | "datetime": "04-03",
115 | "sign_in_time": '09:30:00',
116 | "sign_out_time": '18:30:00',
117 | "work_hour": 8,
118 | }, {
119 | "id": 318,
120 | "status": '休息日',
121 | "datetime": "04-04",
122 | "sign_in_time": '',
123 | "sign_out_time": '',
124 | "work_hour": '',
125 | }, {
126 | "id": 319,
127 | "status": '正常',
128 | "datetime": "04-05",
129 | "sign_in_time": '09:30:00',
130 | "sign_out_time": '18:30:00',
131 | "work_hour": 8,
132 | }
133 | ],
134 | msg: '暂无数据'
135 | },
136 |
137 | /**
138 | * 点击表格一行
139 | */
140 | onRowClick: function(e) {
141 | console.log('e: ', e)
142 | }
143 | })
144 | ```
145 |
146 |
147 | ### 3、配置
148 |
149 | 配置部分主要配置这么几个属性,分别是:
150 |
151 | 配置项 | 说明 | 类型 | 可选值 | 默认值 | 必填
152 | ---|---|---|---|---|---
153 | headers | 表格头部标题、列宽度、列属性 | Array | `{prop: 'datetime', width: 150, label: '日期'}` | [] | yes
154 | data | 表格列表数据 | Array | | [] | no
155 | stripe | 是否为斑马纹 | boolean | true/false | false | no
156 | border | 是否有间隔线 | boolean | true/false | false | no
157 | height | 纵向内容过多时,可选择设置高度固定表头。 | string | | auto | no
158 | msg | 固定无数据情况,展示文案 | string | | `暂无数据~` | no
159 | header-row-class-name | 自定义表格头样式 | string | | | no
160 | row-class-name | 自定义表格行样式 | string | | | no
161 | cell-class-name | 自定义单元格样式 | string | | | no
162 | bind:rowHandle | 行被点击时会触发该事件 | string | | | no
163 |
164 | 配置相关代码🌰:
165 |
166 | ```javascript
167 |
180 | ```
181 | > `header-row-class-name`、`row-class-name`、`cell-class-name` 是通过externalClasses支持外部样式,在父组件中控制表格的样式,[externalClasses外部样式类, 官方说明](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/wxml-wxss.html)。例子源码通过[github地址](https://github.com/habc0807/miniprogram-table-component)查看。
182 |
183 | ## 实现一个自定义表格组件遇到的坑
184 |
185 | ### npm 登录不上和发布不了的问题?
186 |
187 | 之前也发布过 npm 包,遗忘了 `npm login` 登录不上需要将淘宝镜像改回npm的。还有一点需要注意的是,每次发布都需要更新 `package.json` 文件里的版本号。
188 |
189 | ### 微信小程序 npm 找到不到npm包的坑?
190 |
191 | 组件开发完,引入使用的时候,发现npm的包,找不到了?这里比较坑的是小程序的npm有特殊的使用方式。
192 |
193 | - 首先在项目的根目录初始化 npm:
194 |
195 | ```
196 | npm init -f
197 | ```
198 | - 然后安装对应的自定义组件包
199 |
200 | ```
201 | npm install -production miniprogram-table-component
202 | ```
203 | > npm/cnpm/yarn add 均可
204 |
205 | - 在微信开发者工具中,设置 —> 项目设置—> 勾选使用npm模块。
206 |
207 | - 在微信开发者工具中,工具 —> 构建npm,构建完成会生成 `miniprogram_npm` 文件夹,项目用到的npm包都在这里。
208 | - 按照自己的使用路径,从 `miniprogram_npm` 引入需要的包。
209 |
210 |
211 | ## 源码
212 |
213 | - [npm地址](https://www.npmjs.com/package/miniprogram-table-component)
214 | - [github地址](https://github.com/habc0807/miniprogram-table-component)
215 |
216 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | const gulp = require('gulp')
2 | const clean = require('gulp-clean')
3 |
4 | const config = require('./tools/config')
5 | const BuildTask = require('./tools/build')
6 | const id = require('./package.json').name || 'miniprogram-custom-component'
7 |
8 | // 构建任务实例
9 | // eslint-disable-next-line no-new
10 | new BuildTask(id, config.entry)
11 |
12 | // 清空生成目录和文件
13 | gulp.task('clean', gulp.series(() => gulp.src(config.distPath, {read: false, allowEmpty: true}).pipe(clean()), done => {
14 | if (config.isDev) {
15 | return gulp.src(config.demoDist, {read: false, allowEmpty: true})
16 | .pipe(clean())
17 | }
18 |
19 | return done()
20 | }))
21 | // 监听文件变化并进行开发模式构建
22 | gulp.task('watch', gulp.series(`${id}-watch`))
23 | // 开发模式构建
24 | gulp.task('dev', gulp.series(`${id}-dev`))
25 | // 生产模式构建
26 | gulp.task('default', gulp.series(`${id}-default`))
27 |
--------------------------------------------------------------------------------
/imgs/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/1.jpg
--------------------------------------------------------------------------------
/imgs/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/2.jpg
--------------------------------------------------------------------------------
/imgs/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/3.jpg
--------------------------------------------------------------------------------
/imgs/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/4.jpg
--------------------------------------------------------------------------------
/imgs/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/5.jpg
--------------------------------------------------------------------------------
/imgs/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/6.jpg
--------------------------------------------------------------------------------
/imgs/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/7.jpg
--------------------------------------------------------------------------------
/imgs/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/imgs/8.jpg
--------------------------------------------------------------------------------
/miniprogram_dev/app.js:
--------------------------------------------------------------------------------
1 | App({})
2 |
--------------------------------------------------------------------------------
/miniprogram_dev/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/index/index"
4 | ],
5 | "window": {
6 | "backgroundTextStyle": "light",
7 | "navigationBarBackgroundColor": "#fff",
8 | "navigationBarTitleText": "WeChat",
9 | "navigationBarTextStyle": "black"
10 | },
11 | "sitemapLocation": "sitemap.json"
12 | }
--------------------------------------------------------------------------------
/miniprogram_dev/app.wxss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/miniprogram_dev/app.wxss
--------------------------------------------------------------------------------
/miniprogram_dev/components/assets/copy.wxss:
--------------------------------------------------------------------------------
1 | page {
2 | width: 100%;
3 | }
4 |
--------------------------------------------------------------------------------
/miniprogram_dev/components/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/miniprogram_dev/components/assets/icon.png
--------------------------------------------------------------------------------
/miniprogram_dev/components/common.wxss:
--------------------------------------------------------------------------------
1 | @import "./reset.wxss";
2 |
3 | .other {
4 | font-size: 20px;
5 | }
6 |
--------------------------------------------------------------------------------
/miniprogram_dev/components/index.js:
--------------------------------------------------------------------------------
1 | module.exports =
2 | /******/ (function(modules) { // webpackBootstrap
3 | /******/ // The module cache
4 | /******/ var installedModules = {};
5 | /******/
6 | /******/ // The require function
7 | /******/ function __webpack_require__(moduleId) {
8 | /******/
9 | /******/ // Check if module is in cache
10 | /******/ if(installedModules[moduleId]) {
11 | /******/ return installedModules[moduleId].exports;
12 | /******/ }
13 | /******/ // Create a new module (and put it into the cache)
14 | /******/ var module = installedModules[moduleId] = {
15 | /******/ i: moduleId,
16 | /******/ l: false,
17 | /******/ exports: {}
18 | /******/ };
19 | /******/
20 | /******/ // Execute the module function
21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22 | /******/
23 | /******/ // Flag the module as loaded
24 | /******/ module.l = true;
25 | /******/
26 | /******/ // Return the exports of the module
27 | /******/ return module.exports;
28 | /******/ }
29 | /******/
30 | /******/
31 | /******/ // expose the modules object (__webpack_modules__)
32 | /******/ __webpack_require__.m = modules;
33 | /******/
34 | /******/ // expose the module cache
35 | /******/ __webpack_require__.c = installedModules;
36 | /******/
37 | /******/ // define getter function for harmony exports
38 | /******/ __webpack_require__.d = function(exports, name, getter) {
39 | /******/ if(!__webpack_require__.o(exports, name)) {
40 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41 | /******/ }
42 | /******/ };
43 | /******/
44 | /******/ // define __esModule on exports
45 | /******/ __webpack_require__.r = function(exports) {
46 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48 | /******/ }
49 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
50 | /******/ };
51 | /******/
52 | /******/ // create a fake namespace object
53 | /******/ // mode & 1: value is a module id, require it
54 | /******/ // mode & 2: merge all properties of value into the ns
55 | /******/ // mode & 4: return value when already ns object
56 | /******/ // mode & 8|1: behave like require
57 | /******/ __webpack_require__.t = function(value, mode) {
58 | /******/ if(mode & 1) value = __webpack_require__(value);
59 | /******/ if(mode & 8) return value;
60 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61 | /******/ var ns = Object.create(null);
62 | /******/ __webpack_require__.r(ns);
63 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65 | /******/ return ns;
66 | /******/ };
67 | /******/
68 | /******/ // getDefaultExport function for compatibility with non-harmony modules
69 | /******/ __webpack_require__.n = function(module) {
70 | /******/ var getter = module && module.__esModule ?
71 | /******/ function getDefault() { return module['default']; } :
72 | /******/ function getModuleExports() { return module; };
73 | /******/ __webpack_require__.d(getter, 'a', getter);
74 | /******/ return getter;
75 | /******/ };
76 | /******/
77 | /******/ // Object.prototype.hasOwnProperty.call
78 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79 | /******/
80 | /******/ // __webpack_public_path__
81 | /******/ __webpack_require__.p = "";
82 | /******/
83 | /******/
84 | /******/ // Load entry module and return exports
85 | /******/ return __webpack_require__(__webpack_require__.s = 0);
86 | /******/ })
87 | /************************************************************************/
88 | /******/ ([
89 | /* 0 */
90 | /***/ (function(module, exports, __webpack_require__) {
91 |
92 | "use strict";
93 |
94 |
95 | var _ = __webpack_require__(1);
96 |
97 | Component({
98 | /**
99 | * 外部样式类
100 | */
101 | externalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-name'],
102 |
103 | /**
104 | * 组件样式隔离
105 | */
106 | options: {
107 | styleIsolation: "isolated",
108 | multipleSlots: true // 支持多个slot
109 | },
110 |
111 | /**
112 | * 组件的属性列表
113 | */
114 | properties: {
115 | data: {
116 | type: Array,
117 | value: []
118 | },
119 | headers: {
120 | type: Array,
121 | value: []
122 | },
123 | // table的高度, 溢出可滚动
124 | height: {
125 | type: String,
126 | value: 'auto'
127 | },
128 | width: {
129 | type: Number || String,
130 | value: '100%'
131 | },
132 | // 单元格的宽度
133 | tdWidth: {
134 | type: Number,
135 | value: 35
136 | },
137 | // 固定表头 thead达到Header的位置时就应该被fixed了
138 | offsetTop: {
139 | type: Number,
140 | value: 150
141 | },
142 | // 是否带有纵向边框
143 | stripe: {
144 | type: Boolean,
145 | value: false
146 | },
147 | // 是否带有纵向边框
148 | border: {
149 | type: Boolean,
150 | value: false
151 | },
152 | msg: {
153 | type: String,
154 | value: '暂无数据~'
155 | }
156 | },
157 |
158 | /**
159 | * 组件的初始数据
160 | */
161 | data: {
162 | scrolWidth: '100%'
163 | },
164 |
165 | /**
166 | * 组件的监听属性
167 | */
168 | observers: {
169 | // 在 numberA 或者 numberB 被设置时,执行这个函数
170 | 'headers': function headers(_headers) {
171 | var reducer = function reducer(accumulator, currentValue) {
172 | return accumulator + Number(currentValue.width);
173 | };
174 | var scrolWidth = _headers.reduce(reducer, 0);
175 |
176 | this.setData({
177 | scrolWidth: scrolWidth
178 | });
179 | }
180 | },
181 |
182 | /**
183 | * 组件的方法列表
184 | */
185 | methods: {
186 | onRowClick: function onRowClick(e) {
187 | this.triggerEvent('rowClick', e, e.currentTarget.dataset.it);
188 | }
189 | }
190 | });
191 |
192 | /***/ }),
193 | /* 1 */
194 | /***/ (function(module, exports, __webpack_require__) {
195 |
196 | "use strict";
197 |
198 |
199 | module.exports = {
200 | getFlag: function getFlag() {
201 | return true;
202 | }
203 | };
204 |
205 | /***/ })
206 | /******/ ]);
207 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/miniprogram_dev/components/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.js","webpack:///./src/utils.js"],"names":["_","require","Component","externalClasses","options","styleIsolation","multipleSlots","properties","data","type","Array","value","headers","height","String","width","Number","tdWidth","offsetTop","stripe","Boolean","border","msg","scrolWidth","observers","reducer","accumulator","currentValue","reduce","setData","methods","onRowClick","e","triggerEvent","currentTarget","dataset","it","module","exports","getFlag"],"mappings":";;QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;AClFA,IAAMA,IAAIC,mBAAOA,CAACA,CAASA,CAA3B;;AAEAC,UAAU;AACR;;;AAGAC,mBAAiB,CAAC,uBAAD,EAA0B,gBAA1B,EAA4C,iBAA5C,CAJT;;AAMR;;;AAGAC,WAAS;AACPC,oBAAgB,UADT;AAEPC,mBAAe,IAFR,CAEc;AAFd,GATD;;AAcR;;;AAGAC,cAAY;AACVC,UAAM;AACJC,YAAMC,KADF;AAEJC,aAAO;AAFH,KADI;AAKVC,aAAS;AACPH,YAAMC,KADC;AAEPC,aAAO;AAFA,KALC;AASV;AACAE,YAAQ;AACNJ,YAAMK,MADA;AAENH,aAAO;AAFD,KAVE;AAcVI,WAAO;AACLN,YAAMO,UAAUF,MADX;AAELH,aAAO;AAFF,KAdG;AAkBV;AACAM,aAAS;AACPR,YAAMO,MADC;AAEPL,aAAO;AAFA,KAnBC;AAuBV;AACAO,eAAW;AACTT,YAAMO,MADG;AAETL,aAAO;AAFE,KAxBD;AA4BV;AACAQ,YAAQ;AACNV,YAAMW,OADA;AAENT,aAAO;AAFD,KA7BE;AAiCV;AACAU,YAAQ;AACNZ,YAAMW,OADA;AAENT,aAAO;AAFD,KAlCE;AAsCVW,SAAK;AACHb,YAAMK,MADH;AAEHH,aAAO;AAFJ;AAtCK,GAjBJ;;AA6DR;;;AAGAH,QAAM;AACJe,gBAAY;AADR,GAhEE;;AAoER;;;AAGAC,aAAW;AACT;AACA,eAAW,iBAAUZ,QAAV,EAAmB;AAC5B,UAAMa,UAAU,SAAVA,OAAU,CAACC,WAAD,EAAcC,YAAd,EAA+B;AAC7C,eAAOD,cAAcV,OAAOW,aAAaZ,KAApB,CAArB;AACD,OAFD;AAGA,UAAMQ,aAAaX,SAAQgB,MAAR,CAAeH,OAAf,EAAwB,CAAxB,CAAnB;;AAEA,WAAKI,OAAL,CAAa;AACXN,oBAAYA;AADD,OAAb;AAGD;AAXQ,GAvEH;;AAqFR;;;AAGAO,WAAS;AACPC,cADO,sBACIC,CADJ,EACO;AACZ,WAAKC,YAAL,CAAkB,UAAlB,EAA8BD,CAA9B,EAAiCA,EAAEE,aAAF,CAAgBC,OAAhB,CAAwBC,EAAzD;AACD;AAHM;AAxFD,CAAV,E;;;;;;;;;ACFAC,OAAOC,OAAP,GAAiB;AACfC,SADe,qBACL;AACR,WAAO,IAAP;AACD;AAHc,CAAjB,C","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","const _ = require('./utils')\n\nComponent({\n /**\n * 外部样式类\n */\n externalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-name'], \n\n /**\n * 组件样式隔离\n */\n options: {\n styleIsolation: \"isolated\", \n multipleSlots: true, // 支持多个slot\n },\n\n /**\n * 组件的属性列表\n */\n properties: {\n data: {\n type: Array,\n value: []\n },\n headers: {\n type: Array,\n value: []\n },\n // table的高度, 溢出可滚动\n height: { \n type: String,\n value: 'auto'\n },\n width: {\n type: Number || String,\n value: '100%'\n },\n // 单元格的宽度\n tdWidth: {\n type: Number,\n value: 35\n },\n // 固定表头 thead达到Header的位置时就应该被fixed了\n offsetTop: {\n type: Number,\n value: 150\n },\n // 是否带有纵向边框\n stripe: {\n type: Boolean,\n value: false\n },\n // 是否带有纵向边框\n border: {\n type: Boolean,\n value: false\n }, \n msg: {\n type: String,\n value: '暂无数据~'\n }\n },\n\n /**\n * 组件的初始数据\n */\n data: {\n scrolWidth: '100%'\n },\n\n /**\n * 组件的监听属性\n */\n observers: {\n // 在 numberA 或者 numberB 被设置时,执行这个函数\n 'headers': function (headers) {\n const reducer = (accumulator, currentValue) => {\n return accumulator + Number(currentValue.width)\n };\n const scrolWidth = headers.reduce(reducer, 0)\n\n this.setData({\n scrolWidth: scrolWidth\n })\n }\n },\n\n /**\n * 组件的方法列表\n */\n methods: {\n onRowClick(e) {\n this.triggerEvent('rowClick', e, e.currentTarget.dataset.it)\n },\n }\n})","module.exports = {\n getFlag() {\n return true\n },\n}\n"],"sourceRoot":""}
--------------------------------------------------------------------------------
/miniprogram_dev/components/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {},
4 | "componentGenerics": {
5 | "genericsTest": true
6 | }
7 | }
--------------------------------------------------------------------------------
/miniprogram_dev/components/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
19 |
24 |
31 |
32 |
42 | {{it[head["prop"]]}}
43 |
44 |
45 |
46 |
47 |
48 | {{ msg }}
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/miniprogram_dev/components/index.wxss:
--------------------------------------------------------------------------------
1 | @import "./common.wxss";
2 | @import "./reset.wxss";
3 |
4 | .table {
5 | position: relative;
6 | font-size: 28rpx;
7 | background: #fff;
8 | border-right:none;
9 | border-radius: 8rpx;
10 | overflow: hidden;
11 | }
12 | .thead{
13 | border-bottom: none;
14 | display: flex;
15 | justify-content: flex-start;
16 | border-top-right-radius: 8rpx;
17 | border-top-left-radius: 8rpx;
18 | overflow: visible;
19 | color: #909399;
20 | border: 1px solid #ebeef5;
21 | box-sizing: border-box;
22 | }
23 | .thead .td {
24 | padding: 20rpx 10rpx;
25 | font-weight: bold;
26 | display: inline-block;
27 | white-space:nowrap;
28 | text-align: center;
29 | border-right: 1rpx solid #fff;
30 | }
31 | .thead .td:last-child {
32 | border-right: none;
33 | }
34 | .thead-border .td {
35 | border-right: 1rpx solid #ebeef5;
36 | }
37 | .thead-border .td:last-child {
38 | border-right: none;
39 | }
40 | /* .tr{
41 | display: flex;
42 | white-space:nowrap;
43 | } */
44 | .tbody {
45 | box-sizing: border-box;
46 | font-size: 28rpx;
47 | color: #666;
48 | border: 1px solid #ebeef5;
49 | border-top: none;
50 | border-bottom-left-radius: 8rpx;
51 | border-bottom-right-radius: 8rpx;
52 | }
53 | .tbody-tr {
54 | display: flex;
55 | border-bottom: 1px solid #ebeef5;
56 | }
57 | .tbody-tr:last-child {
58 | border-bottom-left-radius: 8rpx;
59 | border-bottom-right-radius: 8rpx;
60 | }
61 |
62 | .tbody-tr-stripe {
63 | background: #fff;
64 | border-bottom: none;
65 | }
66 | .tbody-tr-stripe:nth-child(2n) {
67 | background: #F6F6F6;
68 | }
69 | .tbody-tr .td {
70 | white-space: wrap;
71 | padding:20rpx 10rpx;
72 | text-align: center;
73 | }
74 |
75 | .tbody-tr-border .td {
76 | border-right: 1rpx solid #F6F6F6;
77 | }
78 | .tbody-tr-border .td:last-child {
79 | border-right: none;
80 | }
81 | .no-data {
82 | display: flex;
83 | padding: 50rpx;
84 | color: #666;
85 | justify-content: center;
86 | }
--------------------------------------------------------------------------------
/miniprogram_dev/components/lib.js:
--------------------------------------------------------------------------------
1 | module.exports =
2 | /******/ (function(modules) { // webpackBootstrap
3 | /******/ // The module cache
4 | /******/ var installedModules = {};
5 | /******/
6 | /******/ // The require function
7 | /******/ function __webpack_require__(moduleId) {
8 | /******/
9 | /******/ // Check if module is in cache
10 | /******/ if(installedModules[moduleId]) {
11 | /******/ return installedModules[moduleId].exports;
12 | /******/ }
13 | /******/ // Create a new module (and put it into the cache)
14 | /******/ var module = installedModules[moduleId] = {
15 | /******/ i: moduleId,
16 | /******/ l: false,
17 | /******/ exports: {}
18 | /******/ };
19 | /******/
20 | /******/ // Execute the module function
21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22 | /******/
23 | /******/ // Flag the module as loaded
24 | /******/ module.l = true;
25 | /******/
26 | /******/ // Return the exports of the module
27 | /******/ return module.exports;
28 | /******/ }
29 | /******/
30 | /******/
31 | /******/ // expose the modules object (__webpack_modules__)
32 | /******/ __webpack_require__.m = modules;
33 | /******/
34 | /******/ // expose the module cache
35 | /******/ __webpack_require__.c = installedModules;
36 | /******/
37 | /******/ // define getter function for harmony exports
38 | /******/ __webpack_require__.d = function(exports, name, getter) {
39 | /******/ if(!__webpack_require__.o(exports, name)) {
40 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41 | /******/ }
42 | /******/ };
43 | /******/
44 | /******/ // define __esModule on exports
45 | /******/ __webpack_require__.r = function(exports) {
46 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48 | /******/ }
49 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
50 | /******/ };
51 | /******/
52 | /******/ // create a fake namespace object
53 | /******/ // mode & 1: value is a module id, require it
54 | /******/ // mode & 2: merge all properties of value into the ns
55 | /******/ // mode & 4: return value when already ns object
56 | /******/ // mode & 8|1: behave like require
57 | /******/ __webpack_require__.t = function(value, mode) {
58 | /******/ if(mode & 1) value = __webpack_require__(value);
59 | /******/ if(mode & 8) return value;
60 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61 | /******/ var ns = Object.create(null);
62 | /******/ __webpack_require__.r(ns);
63 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65 | /******/ return ns;
66 | /******/ };
67 | /******/
68 | /******/ // getDefaultExport function for compatibility with non-harmony modules
69 | /******/ __webpack_require__.n = function(module) {
70 | /******/ var getter = module && module.__esModule ?
71 | /******/ function getDefault() { return module['default']; } :
72 | /******/ function getModuleExports() { return module; };
73 | /******/ __webpack_require__.d(getter, 'a', getter);
74 | /******/ return getter;
75 | /******/ };
76 | /******/
77 | /******/ // Object.prototype.hasOwnProperty.call
78 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79 | /******/
80 | /******/ // __webpack_public_path__
81 | /******/ __webpack_require__.p = "";
82 | /******/
83 | /******/
84 | /******/ // Load entry module and return exports
85 | /******/ return __webpack_require__(__webpack_require__.s = 2);
86 | /******/ })
87 | /************************************************************************/
88 | /******/ ({
89 |
90 | /***/ 2:
91 | /***/ (function(module, exports, __webpack_require__) {
92 |
93 | "use strict";
94 |
95 |
96 | exports.__esModule = true;
97 | exports.default = {
98 | printf: function printf() {
99 | return 'miniprogram-custom-component api demo';
100 | }
101 | };
102 |
103 | /***/ })
104 |
105 | /******/ });
106 | //# sourceMappingURL=lib.js.map
--------------------------------------------------------------------------------
/miniprogram_dev/components/lib.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/lib.ts"],"names":[],"mappings":";;QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;kBClFe;AACb,UADa,oBACP;AACJ,eAAO,uCAAP;AACD;AAHY,C","file":"lib.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","export default {\r\n printf() {\r\n return 'miniprogram-custom-component api demo'\r\n }\r\n}\r\n"],"sourceRoot":""}
--------------------------------------------------------------------------------
/miniprogram_dev/components/reset.wxss:
--------------------------------------------------------------------------------
1 | .reset {
2 | background: white;
3 | }
4 |
--------------------------------------------------------------------------------
/miniprogram_dev/components/utils.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | getFlag() {
3 | return true
4 | },
5 | }
6 |
--------------------------------------------------------------------------------
/miniprogram_dev/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {}
3 | }
4 |
--------------------------------------------------------------------------------
/miniprogram_dev/pages/index/config.js:
--------------------------------------------------------------------------------
1 | export const tableHeader = [
2 | {
3 | prop: 'datetime',
4 | width: 150,
5 | label: '日期',
6 | },
7 | {
8 | prop: 'sign_in_time',
9 | width: 152,
10 | label: '上班时间'
11 | },
12 | {
13 | prop: 'sign_out_time',
14 | width: 152,
15 | label: '下班时间'
16 | },
17 | {
18 | prop: 'work_hour',
19 | width: 110,
20 | label: '工时'
21 | },
22 | {
23 | prop: 'status',
24 | width: 110,
25 | label: '状态'
26 |
27 | }
28 | ];
29 |
30 | export const tableHeader2 = [
31 | {
32 | prop: 'datetime',
33 | width: 150,
34 | label: '日期',
35 | color: '#55C355'
36 | },
37 | {
38 | prop: 'sign_in_time',
39 | width: 152,
40 | label: '上班时间'
41 | },
42 | {
43 | prop: 'sign_out_time',
44 | width: 152,
45 | label: '下班时间'
46 | },
47 | {
48 | prop: 'work_hour',
49 | width: 110,
50 | label: '工时'
51 | },
52 | {
53 | prop: 'status',
54 | width: 110,
55 | label: '状态'
56 |
57 | },
58 | {
59 | prop: 'sign_out_time',
60 | width: 200,
61 | label: '下班时间'
62 | },
63 | {
64 | prop: 'work_hour',
65 | width: 200,
66 | label: '工时'
67 | },
68 | {
69 | prop: 'status',
70 | width: 200,
71 | label: '状态'
72 | },
73 | ]
74 |
75 | export const row = [{
76 | "id": 1,
77 | "status": '正常',
78 | "datetime": "04-01",
79 | "sign_in_time": '09:30:00',
80 | "sign_out_time": '18:30:00',
81 | "work_hour": 8,
82 | }, {
83 | "id": 2,
84 | "status": '迟到',
85 | "datetime": "04-02",
86 | "sign_in_time": '10:30:00',
87 | "sign_out_time": '18:30:00',
88 | "work_hour": 7,
89 | }, {
90 | "id": 29,
91 | "status": '正常',
92 | "datetime": "04-03",
93 | "sign_in_time": '09:30:00',
94 | "sign_out_time": '18:30:00',
95 | "work_hour": 8,
96 | }, {
97 | "id": 318,
98 | "status": '休息日',
99 | "datetime": "04-04",
100 | "sign_in_time": '',
101 | "sign_out_time": '',
102 | "work_hour": '',
103 | }, {
104 | "id": 319,
105 | "status": '正常',
106 | "datetime": "04-05",
107 | "sign_in_time": '09:30:00',
108 | "sign_out_time": '18:30:00',
109 | "work_hour": 8,
110 | }]
--------------------------------------------------------------------------------
/miniprogram_dev/pages/index/index.js:
--------------------------------------------------------------------------------
1 | import { tableHeader, tableHeader2, row } from './config.js'
2 |
3 | Page({
4 | /**
5 | * 页面的初始数据
6 | */
7 | data: {
8 | month: '',
9 | user_name: '',
10 | tableHeader,
11 | tableHeader2,
12 | stripe: true,
13 | border: true,
14 | outBorder: true,
15 | height: '150px',
16 | row,
17 | row2: [],
18 | msg: '没有打卡记录哦~'
19 | },
20 | /**
21 | * 生命周期函数--监听页面加载
22 | */
23 | onLoad: function (options) {
24 |
25 | },
26 | /**
27 | * 点击表格一行
28 | */
29 | onRowClick: function(e) {
30 | console.log('e: ', e)
31 |
32 | wx.showToast({
33 | title: '您点击了这一行:',
34 | icon: 'none'
35 | })
36 | }
37 | })
38 |
--------------------------------------------------------------------------------
/miniprogram_dev/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "table": "../../components/index"
4 | }
5 | }
--------------------------------------------------------------------------------
/miniprogram_dev/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 1.基础表格
4 | 基础的表格展示用例。
5 |
6 |
10 |
11 |
12 |
13 |
14 | 2.带斑马纹表格
15 | 使用带斑马纹的表格,可以更容易区分出不同行的数据。
16 |
17 |
22 |
23 |
24 |
25 |
26 | 3.带间隔边框表格
27 |
28 |
33 |
34 |
35 |
36 |
37 | 4.自定义无数据的提示文案
38 | 表格没有数据的情况,可自定义展示文案。
39 |
40 |
41 |
46 |
47 |
48 |
49 |
50 | 5.自定义表格头样式
51 | 可自定义表格头的样式。
52 |
53 |
54 |
61 |
62 |
63 |
64 |
65 | 6.固定表头
66 | 纵向内容过多时,可选择固定表头。
67 |
68 |
75 |
76 |
77 |
78 |
79 | 7.表格横向滑动
80 | 横向内容过多时,可选择左右滑动。
81 |
82 |
88 |
89 |
90 |
91 |
92 | 8.自定义表格行和单元格样式
93 |
94 |
95 |
100 |
101 |
102 |
103 |
104 | 9.当某一行被点击时会触发该事件
105 |
106 |
107 |
112 |
113 |
114 |
115 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/miniprogram_dev/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | .container {
2 | padding: 30rpx;
3 | }
4 | .group {
5 | margin-bottom: 60rpx;
6 | }
7 | .group .group-title {
8 | margin-bottom: 30rpx;
9 | font-size: 34rpx;
10 | font-weight: 700;
11 | color: #333;
12 | }
13 | .group .group-explain {
14 | margin-bottom: 20rpx;
15 | font-size: 28rpx;
16 | color: #666;
17 | }
18 |
19 |
20 | .header-class {
21 | border: 1rpx solid #55C355;
22 | background-color: #55C355;
23 | color: #fff!important;
24 | }
25 | .header-class .td:first-child {
26 | color: #55C355;
27 | }
28 | .row-class:nth-child(2n) {
29 | background-color: #c1e4c175;
30 | }
31 | /* .cell-class {
32 | border-right: 1rpx solid #fff!important;
33 | }
34 | .cell-class:last-child {
35 | border-right: none!important;
36 | } */
37 |
38 |
39 |
--------------------------------------------------------------------------------
/miniprogram_dev/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "packOptions": {
4 | "ignore": []
5 | },
6 | "setting": {
7 | "urlCheck": true,
8 | "es6": true,
9 | "postcss": true,
10 | "minified": true,
11 | "newFeature": true,
12 | "nodeModules": true
13 | },
14 | "compileType": "miniprogram",
15 | "libVersion": "2.10.4",
16 | "appid": "wxd53c182e8d8edcb0",
17 | "projectname": "miniprogram-demo",
18 | "isGameTourist": false,
19 | "simulatorType": "wechat",
20 | "simulatorPluginLibVersion": {},
21 | "condition": {
22 | "search": {
23 | "current": -1,
24 | "list": []
25 | },
26 | "conversation": {
27 | "current": -1,
28 | "list": []
29 | },
30 | "game": {
31 | "currentL": -1,
32 | "list": []
33 | },
34 | "miniprogram": {
35 | "current": -1,
36 | "list": []
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/miniprogram_dev/sitemap.json:
--------------------------------------------------------------------------------
1 | {
2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
3 | "rules": [{
4 | "action": "allow",
5 | "page": "*"
6 | }]
7 | }
--------------------------------------------------------------------------------
/miniprogram_dist/index.js:
--------------------------------------------------------------------------------
1 | module.exports =
2 | /******/ (function(modules) { // webpackBootstrap
3 | /******/ // The module cache
4 | /******/ var installedModules = {};
5 | /******/
6 | /******/ // The require function
7 | /******/ function __webpack_require__(moduleId) {
8 | /******/
9 | /******/ // Check if module is in cache
10 | /******/ if(installedModules[moduleId]) {
11 | /******/ return installedModules[moduleId].exports;
12 | /******/ }
13 | /******/ // Create a new module (and put it into the cache)
14 | /******/ var module = installedModules[moduleId] = {
15 | /******/ i: moduleId,
16 | /******/ l: false,
17 | /******/ exports: {}
18 | /******/ };
19 | /******/
20 | /******/ // Execute the module function
21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22 | /******/
23 | /******/ // Flag the module as loaded
24 | /******/ module.l = true;
25 | /******/
26 | /******/ // Return the exports of the module
27 | /******/ return module.exports;
28 | /******/ }
29 | /******/
30 | /******/
31 | /******/ // expose the modules object (__webpack_modules__)
32 | /******/ __webpack_require__.m = modules;
33 | /******/
34 | /******/ // expose the module cache
35 | /******/ __webpack_require__.c = installedModules;
36 | /******/
37 | /******/ // define getter function for harmony exports
38 | /******/ __webpack_require__.d = function(exports, name, getter) {
39 | /******/ if(!__webpack_require__.o(exports, name)) {
40 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41 | /******/ }
42 | /******/ };
43 | /******/
44 | /******/ // define __esModule on exports
45 | /******/ __webpack_require__.r = function(exports) {
46 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48 | /******/ }
49 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
50 | /******/ };
51 | /******/
52 | /******/ // create a fake namespace object
53 | /******/ // mode & 1: value is a module id, require it
54 | /******/ // mode & 2: merge all properties of value into the ns
55 | /******/ // mode & 4: return value when already ns object
56 | /******/ // mode & 8|1: behave like require
57 | /******/ __webpack_require__.t = function(value, mode) {
58 | /******/ if(mode & 1) value = __webpack_require__(value);
59 | /******/ if(mode & 8) return value;
60 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61 | /******/ var ns = Object.create(null);
62 | /******/ __webpack_require__.r(ns);
63 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65 | /******/ return ns;
66 | /******/ };
67 | /******/
68 | /******/ // getDefaultExport function for compatibility with non-harmony modules
69 | /******/ __webpack_require__.n = function(module) {
70 | /******/ var getter = module && module.__esModule ?
71 | /******/ function getDefault() { return module['default']; } :
72 | /******/ function getModuleExports() { return module; };
73 | /******/ __webpack_require__.d(getter, 'a', getter);
74 | /******/ return getter;
75 | /******/ };
76 | /******/
77 | /******/ // Object.prototype.hasOwnProperty.call
78 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79 | /******/
80 | /******/ // __webpack_public_path__
81 | /******/ __webpack_require__.p = "";
82 | /******/
83 | /******/
84 | /******/ // Load entry module and return exports
85 | /******/ return __webpack_require__(__webpack_require__.s = 0);
86 | /******/ })
87 | /************************************************************************/
88 | /******/ ([
89 | /* 0 */
90 | /***/ (function(module, exports, __webpack_require__) {
91 |
92 | "use strict";
93 |
94 |
95 | Component({
96 | /**
97 | * 外部样式类
98 | */
99 | externalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-name'],
100 |
101 | /**
102 | * 组件样式隔离
103 | */
104 | options: {
105 | styleIsolation: "isolated",
106 | multipleSlots: true // 支持多个slot
107 | },
108 |
109 | /**
110 | * 组件的属性列表
111 | */
112 | properties: {
113 | data: {
114 | type: Array,
115 | value: []
116 | },
117 | headers: {
118 | type: Array,
119 | value: []
120 | },
121 | // table的高度, 溢出可滚动
122 | height: {
123 | type: String,
124 | value: 'auto'
125 | },
126 | width: {
127 | type: Number || String,
128 | value: '100%'
129 | },
130 | // 单元格的宽度
131 | tdWidth: {
132 | type: Number,
133 | value: 35
134 | },
135 | // 固定表头 thead达到Header的位置时就应该被fixed了
136 | offsetTop: {
137 | type: Number,
138 | value: 150
139 | },
140 | // 是否带有纵向边框
141 | stripe: {
142 | type: Boolean,
143 | value: false
144 | },
145 | // 是否带有纵向边框
146 | border: {
147 | type: Boolean,
148 | value: false
149 | },
150 | msg: {
151 | type: String,
152 | value: '暂无数据~'
153 | }
154 | },
155 |
156 | /**
157 | * 组件的初始数据
158 | */
159 | data: {
160 | scrolWidth: '100%'
161 | },
162 |
163 | /**
164 | * 组件的监听属性
165 | */
166 | observers: {
167 | // 在 numberA 或者 numberB 被设置时,执行这个函数
168 | 'headers': function headers(_headers) {
169 | var reducer = function reducer(accumulator, currentValue) {
170 | return accumulator + Number(currentValue.width);
171 | };
172 | var scrolWidth = _headers.reduce(reducer, 0);
173 |
174 | this.setData({
175 | scrolWidth: scrolWidth
176 | });
177 | }
178 | },
179 |
180 | /**
181 | * 组件的方法列表
182 | */
183 | methods: {
184 | onRowClick: function onRowClick(e) {
185 | this.triggerEvent('rowClick', e, e.currentTarget.dataset.it);
186 | }
187 | }
188 | });
189 |
190 | /***/ })
191 | /******/ ]);
192 | //# sourceMappingURL=index.js.map
--------------------------------------------------------------------------------
/miniprogram_dist/index.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/index.js"],"names":["Component","externalClasses","options","styleIsolation","multipleSlots","properties","data","type","Array","value","headers","height","String","width","Number","tdWidth","offsetTop","stripe","Boolean","border","msg","scrolWidth","observers","reducer","accumulator","currentValue","reduce","setData","methods","onRowClick","e","triggerEvent","currentTarget","dataset","it"],"mappings":";;QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;AClFAA,UAAU;AACR;;;AAGAC,mBAAiB,CAAC,uBAAD,EAA0B,gBAA1B,EAA4C,iBAA5C,CAJT;;AAMR;;;AAGAC,WAAS;AACPC,oBAAgB,UADT;AAEPC,mBAAe,IAFR,CAEc;AAFd,GATD;;AAcR;;;AAGAC,cAAY;AACVC,UAAM;AACJC,YAAMC,KADF;AAEJC,aAAO;AAFH,KADI;AAKVC,aAAS;AACPH,YAAMC,KADC;AAEPC,aAAO;AAFA,KALC;AASV;AACAE,YAAQ;AACNJ,YAAMK,MADA;AAENH,aAAO;AAFD,KAVE;AAcVI,WAAO;AACLN,YAAMO,UAAUF,MADX;AAELH,aAAO;AAFF,KAdG;AAkBV;AACAM,aAAS;AACPR,YAAMO,MADC;AAEPL,aAAO;AAFA,KAnBC;AAuBV;AACAO,eAAW;AACTT,YAAMO,MADG;AAETL,aAAO;AAFE,KAxBD;AA4BV;AACAQ,YAAQ;AACNV,YAAMW,OADA;AAENT,aAAO;AAFD,KA7BE;AAiCV;AACAU,YAAQ;AACNZ,YAAMW,OADA;AAENT,aAAO;AAFD,KAlCE;AAsCVW,SAAK;AACHb,YAAMK,MADH;AAEHH,aAAO;AAFJ;AAtCK,GAjBJ;;AA6DR;;;AAGAH,QAAM;AACJe,gBAAY;AADR,GAhEE;;AAoER;;;AAGAC,aAAW;AACT;AACA,eAAW,iBAAUZ,QAAV,EAAmB;AAC5B,UAAMa,UAAU,SAAVA,OAAU,CAACC,WAAD,EAAcC,YAAd,EAA+B;AAC7C,eAAOD,cAAcV,OAAOW,aAAaZ,KAApB,CAArB;AACD,OAFD;AAGA,UAAMQ,aAAaX,SAAQgB,MAAR,CAAeH,OAAf,EAAwB,CAAxB,CAAnB;;AAEA,WAAKI,OAAL,CAAa;AACXN,oBAAYA;AADD,OAAb;AAGD;AAXQ,GAvEH;;AAqFR;;;AAGAO,WAAS;AACPC,cADO,sBACIC,CADJ,EACO;AACZ,WAAKC,YAAL,CAAkB,UAAlB,EAA8BD,CAA9B,EAAiCA,EAAEE,aAAF,CAAgBC,OAAhB,CAAwBC,EAAzD;AACD;AAHM;AAxFD,CAAV,E","file":"index.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","Component({\n /**\n * 外部样式类\n */\n externalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-name'], \n\n /**\n * 组件样式隔离\n */\n options: {\n styleIsolation: \"isolated\", \n multipleSlots: true, // 支持多个slot\n },\n\n /**\n * 组件的属性列表\n */\n properties: {\n data: {\n type: Array,\n value: []\n },\n headers: {\n type: Array,\n value: []\n },\n // table的高度, 溢出可滚动\n height: { \n type: String,\n value: 'auto'\n },\n width: {\n type: Number || String,\n value: '100%'\n },\n // 单元格的宽度\n tdWidth: {\n type: Number,\n value: 35\n },\n // 固定表头 thead达到Header的位置时就应该被fixed了\n offsetTop: {\n type: Number,\n value: 150\n },\n // 是否带有纵向边框\n stripe: {\n type: Boolean,\n value: false\n },\n // 是否带有纵向边框\n border: {\n type: Boolean,\n value: false\n }, \n msg: {\n type: String,\n value: '暂无数据~'\n }\n },\n\n /**\n * 组件的初始数据\n */\n data: {\n scrolWidth: '100%'\n },\n\n /**\n * 组件的监听属性\n */\n observers: {\n // 在 numberA 或者 numberB 被设置时,执行这个函数\n 'headers': function (headers) {\n const reducer = (accumulator, currentValue) => {\n return accumulator + Number(currentValue.width)\n };\n const scrolWidth = headers.reduce(reducer, 0)\n\n this.setData({\n scrolWidth: scrolWidth\n })\n }\n },\n\n /**\n * 组件的方法列表\n */\n methods: {\n onRowClick(e) {\n this.triggerEvent('rowClick', e, e.currentTarget.dataset.it)\n },\n }\n})"],"sourceRoot":""}
--------------------------------------------------------------------------------
/miniprogram_dist/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {},
4 | "componentGenerics": {
5 | "genericsTest": true
6 | }
7 | }
--------------------------------------------------------------------------------
/miniprogram_dist/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
19 |
24 |
31 |
32 |
42 | {{it[head["prop"]]}}
43 |
44 |
45 |
46 |
47 |
48 | {{ msg }}
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/miniprogram_dist/index.wxss:
--------------------------------------------------------------------------------
1 | .table {
2 | position: relative;
3 | font-size: 28rpx;
4 | background: #fff;
5 | border-right:none;
6 | border-radius: 8rpx;
7 | overflow: hidden;
8 | }
9 | .thead{
10 | border-bottom: none;
11 | display: flex;
12 | justify-content: flex-start;
13 | border-top-right-radius: 8rpx;
14 | border-top-left-radius: 8rpx;
15 | overflow: visible;
16 | color: #909399;
17 | border: 1px solid #ebeef5;
18 | box-sizing: border-box;
19 | }
20 | .thead .td {
21 | padding: 20rpx 10rpx;
22 | font-weight: bold;
23 | display: inline-block;
24 | text-align: center;
25 | border-right: 1rpx solid #fff;
26 | }
27 | .thead .td:last-child {
28 | border-right: none;
29 | }
30 | .thead-border .td {
31 | border-right: 1rpx solid #ebeef5;
32 | }
33 | .thead-border .td:last-child {
34 | border-right: none;
35 | }
36 | /* .tr{
37 | display: flex;
38 | white-space:nowrap;
39 | } */
40 | .tbody {
41 | box-sizing: border-box;
42 | font-size: 28rpx;
43 | color: #666;
44 | border: 1px solid #ebeef5;
45 | border-top: none;
46 | border-bottom-left-radius: 8rpx;
47 | border-bottom-right-radius: 8rpx;
48 | }
49 | .tbody-tr {
50 | display: flex;
51 | border-bottom: 1px solid #ebeef5;
52 | }
53 | .tbody-tr:last-child {
54 | border-bottom-left-radius: 8rpx;
55 | border-bottom-right-radius: 8rpx;
56 | }
57 |
58 | .tbody-tr-stripe {
59 | background: #fff;
60 | border-bottom: none;
61 | }
62 | .tbody-tr-stripe:nth-child(2n) {
63 | background: #F6F6F6;
64 | }
65 | .tbody-tr .td {
66 | white-space: wrap;
67 | padding:20rpx 10rpx;
68 | text-align: center;
69 | }
70 |
71 | .tbody-tr-border .td {
72 | border-right: 1rpx solid #F6F6F6;
73 | }
74 | .tbody-tr-border .td:last-child {
75 | border-right: none;
76 | }
77 | .no-data {
78 | display: flex;
79 | padding: 50rpx;
80 | color: #666;
81 | justify-content: center;
82 | }
--------------------------------------------------------------------------------
/miniprogram_dist/lib.js:
--------------------------------------------------------------------------------
1 | module.exports =
2 | /******/ (function(modules) { // webpackBootstrap
3 | /******/ // The module cache
4 | /******/ var installedModules = {};
5 | /******/
6 | /******/ // The require function
7 | /******/ function __webpack_require__(moduleId) {
8 | /******/
9 | /******/ // Check if module is in cache
10 | /******/ if(installedModules[moduleId]) {
11 | /******/ return installedModules[moduleId].exports;
12 | /******/ }
13 | /******/ // Create a new module (and put it into the cache)
14 | /******/ var module = installedModules[moduleId] = {
15 | /******/ i: moduleId,
16 | /******/ l: false,
17 | /******/ exports: {}
18 | /******/ };
19 | /******/
20 | /******/ // Execute the module function
21 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
22 | /******/
23 | /******/ // Flag the module as loaded
24 | /******/ module.l = true;
25 | /******/
26 | /******/ // Return the exports of the module
27 | /******/ return module.exports;
28 | /******/ }
29 | /******/
30 | /******/
31 | /******/ // expose the modules object (__webpack_modules__)
32 | /******/ __webpack_require__.m = modules;
33 | /******/
34 | /******/ // expose the module cache
35 | /******/ __webpack_require__.c = installedModules;
36 | /******/
37 | /******/ // define getter function for harmony exports
38 | /******/ __webpack_require__.d = function(exports, name, getter) {
39 | /******/ if(!__webpack_require__.o(exports, name)) {
40 | /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
41 | /******/ }
42 | /******/ };
43 | /******/
44 | /******/ // define __esModule on exports
45 | /******/ __webpack_require__.r = function(exports) {
46 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
47 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
48 | /******/ }
49 | /******/ Object.defineProperty(exports, '__esModule', { value: true });
50 | /******/ };
51 | /******/
52 | /******/ // create a fake namespace object
53 | /******/ // mode & 1: value is a module id, require it
54 | /******/ // mode & 2: merge all properties of value into the ns
55 | /******/ // mode & 4: return value when already ns object
56 | /******/ // mode & 8|1: behave like require
57 | /******/ __webpack_require__.t = function(value, mode) {
58 | /******/ if(mode & 1) value = __webpack_require__(value);
59 | /******/ if(mode & 8) return value;
60 | /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
61 | /******/ var ns = Object.create(null);
62 | /******/ __webpack_require__.r(ns);
63 | /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
64 | /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
65 | /******/ return ns;
66 | /******/ };
67 | /******/
68 | /******/ // getDefaultExport function for compatibility with non-harmony modules
69 | /******/ __webpack_require__.n = function(module) {
70 | /******/ var getter = module && module.__esModule ?
71 | /******/ function getDefault() { return module['default']; } :
72 | /******/ function getModuleExports() { return module; };
73 | /******/ __webpack_require__.d(getter, 'a', getter);
74 | /******/ return getter;
75 | /******/ };
76 | /******/
77 | /******/ // Object.prototype.hasOwnProperty.call
78 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
79 | /******/
80 | /******/ // __webpack_public_path__
81 | /******/ __webpack_require__.p = "";
82 | /******/
83 | /******/
84 | /******/ // Load entry module and return exports
85 | /******/ return __webpack_require__(__webpack_require__.s = 1);
86 | /******/ })
87 | /************************************************************************/
88 | /******/ ([
89 | /* 0 */,
90 | /* 1 */
91 | /***/ (function(module, exports, __webpack_require__) {
92 |
93 | "use strict";
94 |
95 |
96 | exports.__esModule = true;
97 | exports.default = {
98 | printf: function printf() {
99 | return 'miniprogram-custom-component api demo';
100 | }
101 | };
102 |
103 | /***/ })
104 | /******/ ]);
105 | //# sourceMappingURL=lib.js.map
--------------------------------------------------------------------------------
/miniprogram_dist/lib.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/lib.ts"],"names":[],"mappings":";;QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA,0CAA0C,gCAAgC;QAC1E;QACA;;QAEA;QACA;QACA;QACA,wDAAwD,kBAAkB;QAC1E;QACA,iDAAiD,cAAc;QAC/D;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,yCAAyC,iCAAiC;QAC1E,gHAAgH,mBAAmB,EAAE;QACrI;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;;QAGA;QACA;;;;;;;;;;;;kBClFe;AACb,UADa,oBACP;AACJ,eAAO,uCAAP;AACD;AAHY,C","file":"lib.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","export default {\r\n printf() {\r\n return 'miniprogram-custom-component api demo'\r\n }\r\n}\r\n"],"sourceRoot":""}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "miniprogram-table-component",
3 | "version": "1.1.0",
4 | "description": "",
5 | "main": "miniprogram_dist/index.js",
6 | "scripts": {
7 | "dev": "gulp dev --develop",
8 | "watch": "gulp watch --develop --watch",
9 | "build": "gulp",
10 | "dist": "npm run build",
11 | "clean-dev": "gulp clean --develop",
12 | "clean": "gulp clean",
13 | "test": "jest --bail",
14 | "test-debug": "node --inspect-brk ./node_modules/jest/bin/jest.js --runInBand --bail",
15 | "coverage": "jest ./test/* --coverage --bail",
16 | "lint": "eslint \"src/**/*.js\" --fix",
17 | "lint-tools": "eslint \"tools/**/*.js\" --rule \"import/no-extraneous-dependencies: false\" --fix"
18 | },
19 | "miniprogram": "miniprogram_dist",
20 | "jest": {
21 | "testEnvironment": "jsdom",
22 | "testURL": "https://jest.test",
23 | "collectCoverageFrom": [
24 | "miniprogram_dist/**/*.js"
25 | ],
26 | "moduleDirectories": [
27 | "node_modules",
28 | "miniprogram_dist"
29 | ]
30 | },
31 | "repository": {
32 | "type": "git",
33 | "url": "https://github.com/habc0807/miniprogram-table-component"
34 | },
35 | "author": "wechat-miniprogram",
36 | "license": "MIT",
37 | "devDependencies": {
38 | "@typescript-eslint/eslint-plugin": "^2.28.0",
39 | "@typescript-eslint/parser": "^2.28.0",
40 | "babel-core": "^6.26.3",
41 | "babel-loader": "^7.1.5",
42 | "babel-plugin-module-resolver": "^3.2.0",
43 | "babel-preset-env": "^1.7.0",
44 | "colors": "^1.3.1",
45 | "eslint": "^5.14.1",
46 | "eslint-config-airbnb-base": "13.1.0",
47 | "eslint-loader": "^2.1.2",
48 | "eslint-plugin-import": "^2.16.0",
49 | "eslint-plugin-node": "^7.0.1",
50 | "eslint-plugin-promise": "^3.8.0",
51 | "gulp": "^4.0.0",
52 | "gulp-clean": "^0.4.0",
53 | "gulp-if": "^2.0.2",
54 | "gulp-install": "^1.1.0",
55 | "gulp-less": "^4.0.1",
56 | "gulp-rename": "^1.4.0",
57 | "gulp-sourcemaps": "^2.6.5",
58 | "jest": "^23.5.0",
59 | "miniprogram-api-typings": "^2.10.3-1",
60 | "miniprogram-simulate": "^1.2.0",
61 | "thread-loader": "^2.1.3",
62 | "through2": "^2.0.3",
63 | "ts-loader": "^7.0.0",
64 | "typescript": "^3.8.3",
65 | "vinyl": "^2.2.0",
66 | "webpack": "^4.29.5",
67 | "webpack-node-externals": "^1.7.2"
68 | },
69 | "dependencies": {}
70 | }
71 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | Component({
2 | /**
3 | * 外部样式类
4 | */
5 | externalClasses: ['header-row-class-name', 'row-class-name', 'cell-class-name'],
6 |
7 | /**
8 | * 组件样式隔离
9 | */
10 | options: {
11 | styleIsolation: "isolated",
12 | multipleSlots: true, // 支持多个slot
13 | },
14 |
15 | /**
16 | * 组件的属性列表
17 | */
18 | properties: {
19 | data: {
20 | type: Array,
21 | value: []
22 | },
23 | headers: {
24 | type: Array,
25 | value: []
26 | },
27 | // table的高度, 溢出可滚动
28 | height: {
29 | type: String,
30 | value: 'auto'
31 | },
32 | width: {
33 | type: Number || String,
34 | value: '100%'
35 | },
36 | // 单元格的宽度
37 | tdWidth: {
38 | type: Number,
39 | value: 35
40 | },
41 | // 固定表头 thead达到Header的位置时就应该被fixed了
42 | offsetTop: {
43 | type: Number,
44 | value: 150
45 | },
46 | // 是否带有纵向边框
47 | stripe: {
48 | type: Boolean,
49 | value: false
50 | },
51 | // 是否带有纵向边框
52 | border: {
53 | type: Boolean,
54 | value: false
55 | },
56 | msg: {
57 | type: String,
58 | value: '暂无数据~'
59 | }
60 | },
61 |
62 | /**
63 | * 组件的初始数据
64 | */
65 | data: {
66 | scrolWidth: '100%'
67 | },
68 |
69 | /**
70 | * 组件的监听属性
71 | */
72 | observers: {
73 | // 在 numberA 或者 numberB 被设置时,执行这个函数
74 | 'headers': function (headers) {
75 | const reducer = (accumulator, currentValue) => {
76 | return accumulator + Number(currentValue.width)
77 | };
78 | const scrolWidth = headers.reduce(reducer, 0)
79 |
80 | this.setData({
81 | scrolWidth: scrolWidth
82 | })
83 | }
84 | },
85 |
86 | /**
87 | * 组件的方法列表
88 | */
89 | methods: {
90 | onRowClick(e) {
91 | this.triggerEvent('rowClick', e, e.currentTarget.dataset.it)
92 | },
93 | }
94 | })
--------------------------------------------------------------------------------
/src/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "component": true,
3 | "usingComponents": {},
4 | "componentGenerics": {
5 | "genericsTest": true
6 | }
7 | }
--------------------------------------------------------------------------------
/src/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
16 |
17 |
18 |
19 |
24 |
31 |
32 |
42 | {{it[head["prop"]]}}
43 |
44 |
45 |
46 |
47 |
48 | {{ msg }}
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/index.wxss:
--------------------------------------------------------------------------------
1 | .table {
2 | position: relative;
3 | font-size: 28rpx;
4 | background: #fff;
5 | border-right:none;
6 | border-radius: 8rpx;
7 | overflow: hidden;
8 | }
9 | .thead{
10 | border-bottom: none;
11 | display: flex;
12 | justify-content: flex-start;
13 | border-top-right-radius: 8rpx;
14 | border-top-left-radius: 8rpx;
15 | overflow: visible;
16 | color: #909399;
17 | border: 1px solid #ebeef5;
18 | box-sizing: border-box;
19 | }
20 | .thead .td {
21 | padding: 20rpx 10rpx;
22 | font-weight: bold;
23 | display: inline-block;
24 | text-align: center;
25 | border-right: 1rpx solid #fff;
26 | }
27 | .thead .td:last-child {
28 | border-right: none;
29 | }
30 | .thead-border .td {
31 | border-right: 1rpx solid #ebeef5;
32 | }
33 | .thead-border .td:last-child {
34 | border-right: none;
35 | }
36 | /* .tr{
37 | display: flex;
38 | white-space:nowrap;
39 | } */
40 | .tbody {
41 | box-sizing: border-box;
42 | font-size: 28rpx;
43 | color: #666;
44 | border: 1px solid #ebeef5;
45 | border-top: none;
46 | border-bottom-left-radius: 8rpx;
47 | border-bottom-right-radius: 8rpx;
48 | }
49 | .tbody-tr {
50 | display: flex;
51 | border-bottom: 1px solid #ebeef5;
52 | }
53 | .tbody-tr:last-child {
54 | border-bottom-left-radius: 8rpx;
55 | border-bottom-right-radius: 8rpx;
56 | }
57 |
58 | .tbody-tr-stripe {
59 | background: #fff;
60 | border-bottom: none;
61 | }
62 | .tbody-tr-stripe:nth-child(2n) {
63 | background: #F6F6F6;
64 | }
65 | .tbody-tr .td {
66 | white-space: wrap;
67 | padding:20rpx 10rpx;
68 | text-align: center;
69 | }
70 |
71 | .tbody-tr-border .td {
72 | border-right: 1rpx solid #F6F6F6;
73 | }
74 | .tbody-tr-border .td:last-child {
75 | border-right: none;
76 | }
77 | .no-data {
78 | display: flex;
79 | padding: 50rpx;
80 | color: #666;
81 | justify-content: center;
82 | }
--------------------------------------------------------------------------------
/src/lib.ts:
--------------------------------------------------------------------------------
1 | export default {
2 | printf() {
3 | return 'miniprogram-custom-component api demo'
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/index.test.js:
--------------------------------------------------------------------------------
1 | const _ = require('./utils')
2 |
3 | test('render', async () => {
4 | const componentId = _.load('index', 'comp')
5 | const component = _.render(componentId, {prop: 'index.test.properties'})
6 |
7 | const parent = document.createElement('parent-wrapper')
8 | component.attach(parent)
9 |
10 | expect(_.match(component.dom, 'index.test.properties-falseother.properties-other')).toBe(true)
11 |
12 | await _.sleep(10)
13 |
14 | expect(_.match(component.dom, 'index.test.properties-trueother.properties-other')).toBe(true)
15 | })
16 |
--------------------------------------------------------------------------------
/test/utils.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 | const simulate = require('miniprogram-simulate')
4 | const config = require('../tools/config')
5 |
6 | // const dir = config.srcPath // 使用源码进行测试,对于 debug 和代码覆盖率检测会比较友好
7 | const dir = config.distPath // 使用构建后代码进行测试,如果使用了 typescript 进行开发,必须选择此目录
8 |
9 | try {
10 | fs.accessSync(dir)
11 | } catch (err) {
12 | console.error('请先执行 npm run build 再进行单元测试!!!')
13 | }
14 |
15 | const oldLoad = simulate.load
16 | simulate.load = function (componentPath, ...args) {
17 | if (typeof componentPath === 'string') componentPath = path.join(dir, componentPath)
18 | return oldLoad(componentPath, ...args)
19 | }
20 |
21 | module.exports = simulate
22 |
23 | // adjust the simulated wx api
24 | const oldGetSystemInfoSync = global.wx.getSystemInfoSync
25 | global.wx.getSystemInfoSync = function() {
26 | const res = oldGetSystemInfoSync()
27 | res.SDKVersion = '2.4.1'
28 |
29 | return res
30 | }
31 |
--------------------------------------------------------------------------------
/test/wx.test.js:
--------------------------------------------------------------------------------
1 | const _ = require('./utils')
2 |
3 | test('wx.getSystemInfo', async () => {
4 | wx.getSystemInfo({
5 | success(res) {
6 | expect(res.errMsg).toBe('getSystemInfo:ok')
7 | },
8 | complete(res) {
9 | expect(res.errMsg).toBe('getSystemInfo:ok')
10 | },
11 | })
12 | })
13 |
14 | test('wx.getSystemInfoSync', async () => {
15 | const info = wx.getSystemInfoSync()
16 | expect(info.SDKVersion).toBe('2.4.1')
17 | expect(info.version).toBe('6.6.3')
18 | })
19 |
--------------------------------------------------------------------------------
/tools/build.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const fs = require('fs')
3 |
4 | const gulp = require('gulp')
5 | const clean = require('gulp-clean')
6 | const less = require('gulp-less')
7 | const rename = require('gulp-rename')
8 | const gulpif = require('gulp-if')
9 | const sourcemaps = require('gulp-sourcemaps')
10 | const webpack = require('webpack')
11 | const gulpInstall = require('gulp-install')
12 |
13 | const config = require('./config')
14 | const checkComponents = require('./checkcomponents')
15 | const checkWxss = require('./checkwxss')
16 | const _ = require('./utils')
17 |
18 | const jsConfig = config.js || {}
19 | const wxssConfig = config.wxss || {}
20 | const srcPath = config.srcPath
21 | const distPath = config.distPath
22 |
23 | /**
24 | * 获取 wxss 流
25 | */
26 | function wxss(wxssFileList) {
27 | if (!wxssFileList.length) return false
28 |
29 | return gulp.src(wxssFileList, {cwd: srcPath, base: srcPath})
30 | .pipe(checkWxss.start()) // 开始处理 import
31 | .pipe(gulpif(wxssConfig.less && wxssConfig.sourcemap, sourcemaps.init()))
32 | .pipe(gulpif(wxssConfig.less, less({paths: [srcPath]})))
33 | .pipe(checkWxss.end()) // 结束处理 import
34 | .pipe(rename({extname: '.wxss'}))
35 | .pipe(gulpif(wxssConfig.less && wxssConfig.sourcemap, sourcemaps.write('./')))
36 | .pipe(_.logger(wxssConfig.less ? 'generate' : undefined))
37 | .pipe(gulp.dest(distPath))
38 | }
39 |
40 | /**
41 | * 获取 js 流
42 | */
43 | function js(jsFileMap, scope) {
44 | const webpackConfig = config.webpack
45 | const webpackCallback = (err, stats) => {
46 | if (!err) {
47 | // eslint-disable-next-line no-console
48 | console.log(stats.toString({
49 | assets: true,
50 | cached: false,
51 | colors: true,
52 | children: false,
53 | errors: true,
54 | warnings: true,
55 | version: true,
56 | modules: false,
57 | publicPath: true,
58 | }))
59 | } else {
60 | // eslint-disable-next-line no-console
61 | console.log(err)
62 | }
63 | }
64 |
65 | webpackConfig.entry = jsFileMap
66 | webpackConfig.output.path = distPath
67 |
68 | if (scope.webpackWatcher) {
69 | scope.webpackWatcher.close()
70 | scope.webpackWatcher = null
71 | }
72 |
73 | if (config.isWatch) {
74 | scope.webpackWatcher = webpack(webpackConfig).watch({
75 | ignored: /node_modules/,
76 | }, webpackCallback)
77 | } else {
78 | webpack(webpackConfig).run(webpackCallback)
79 | }
80 | }
81 |
82 | /**
83 | * 拷贝文件
84 | */
85 | function copy(copyFileList) {
86 | if (!copyFileList.length) return false
87 |
88 | return gulp.src(copyFileList, {cwd: srcPath, base: srcPath})
89 | .pipe(_.logger())
90 | .pipe(gulp.dest(distPath))
91 | }
92 |
93 | /**
94 | * 安装依赖包
95 | */
96 | function install() {
97 | return gulp.series(async () => {
98 | const demoDist = config.demoDist
99 | const demoPackageJsonPath = path.join(demoDist, 'package.json')
100 | const packageJson = _.readJson(path.resolve(__dirname, '../package.json'))
101 | const dependencies = packageJson.dependencies || {}
102 |
103 | await _.writeFile(demoPackageJsonPath, JSON.stringify({dependencies}, null, '\t')) // write dev demo's package.json
104 | }, () => {
105 | const demoDist = config.demoDist
106 | const demoPackageJsonPath = path.join(demoDist, 'package.json')
107 |
108 | return gulp.src(demoPackageJsonPath)
109 | .pipe(gulpInstall({production: true}))
110 | })
111 | }
112 |
113 | class BuildTask {
114 | constructor(id, entry) {
115 | if (!entry) return
116 |
117 | this.id = id
118 | this.entries = Array.isArray(config.entry) ? config.entry : [config.entry]
119 | this.copyList = Array.isArray(config.copy) ? config.copy : []
120 | this.componentListMap = {}
121 | this.cachedComponentListMap = {}
122 |
123 | this.init()
124 | }
125 |
126 | init() {
127 | const id = this.id
128 |
129 | /**
130 | * 清空目标目录
131 | */
132 | gulp.task(`${id}-clean-dist`, () => gulp.src(distPath, {read: false, allowEmpty: true}).pipe(clean()))
133 |
134 | /**
135 | * 拷贝 demo 到目标目录
136 | */
137 | let isDemoExists = false
138 | gulp.task(`${id}-demo`, gulp.series(async () => {
139 | const demoDist = config.demoDist
140 |
141 | isDemoExists = await _.checkFileExists(path.join(demoDist, 'project.config.json'))
142 | }, done => {
143 | if (!isDemoExists) {
144 | const demoSrc = config.demoSrc
145 | const demoDist = config.demoDist
146 |
147 | return gulp.src('**/*', {cwd: demoSrc, base: demoSrc})
148 | .pipe(gulp.dest(demoDist))
149 | }
150 |
151 | return done()
152 | }))
153 |
154 | /**
155 | * 安装依赖包
156 | */
157 | gulp.task(`${id}-install`, install())
158 |
159 | /**
160 | * 检查自定义组件
161 | */
162 | gulp.task(`${id}-component-check`, async () => {
163 | const entries = this.entries
164 | const mergeComponentListMap = {}
165 | for (let i = 0, len = entries.length; i < len; i++) {
166 | let entry = entries[i]
167 | entry = path.join(srcPath, `${entry}.json`)
168 | const newComponentListMap = await checkComponents(entry)
169 |
170 | _.merge(mergeComponentListMap, newComponentListMap)
171 | }
172 |
173 | this.cachedComponentListMap = this.componentListMap
174 | this.componentListMap = mergeComponentListMap
175 | })
176 |
177 | /**
178 | * 写 json 文件到目标目录
179 | */
180 | gulp.task(`${id}-component-json`, done => {
181 | const jsonFileList = this.componentListMap.jsonFileList
182 |
183 | if (jsonFileList && jsonFileList.length) {
184 | return copy(this.componentListMap.jsonFileList)
185 | }
186 |
187 | return done()
188 | })
189 |
190 | /**
191 | * 拷贝 wxml 文件到目标目录
192 | */
193 | gulp.task(`${id}-component-wxml`, done => {
194 | const wxmlFileList = this.componentListMap.wxmlFileList
195 |
196 | if (wxmlFileList &&
197 | wxmlFileList.length &&
198 | !_.compareArray(this.cachedComponentListMap.wxmlFileList, wxmlFileList)) {
199 | return copy(wxmlFileList)
200 | }
201 |
202 | return done()
203 | })
204 |
205 | /**
206 | * 生成 wxss 文件到目标目录
207 | */
208 | gulp.task(`${id}-component-wxss`, done => {
209 | const wxssFileList = this.componentListMap.wxssFileList
210 |
211 | if (wxssFileList &&
212 | wxssFileList.length &&
213 | !_.compareArray(this.cachedComponentListMap.wxssFileList, wxssFileList)) {
214 | return wxss(wxssFileList, srcPath, distPath)
215 | }
216 |
217 | return done()
218 | })
219 |
220 | /**
221 | * 生成 js 文件到目标目录
222 | */
223 | gulp.task(`${id}-component-js`, done => {
224 | const jsFileList = this.componentListMap.jsFileList
225 |
226 | if (jsFileList &&
227 | jsFileList.length &&
228 | !_.compareArray(this.cachedComponentListMap.jsFileList, jsFileList)) {
229 | if (jsConfig.webpack) {
230 | js(this.componentListMap.jsFileMap, this)
231 | } else {
232 | return copy(jsFileList)
233 | }
234 | }
235 |
236 | return done()
237 | })
238 |
239 | /**
240 | * 拷贝相关资源到目标目录
241 | */
242 | gulp.task(`${id}-copy`, gulp.parallel(done => {
243 | const copyList = this.copyList
244 | const copyFileList = copyList.map(copyFilePath => {
245 | try {
246 | if (fs.statSync(path.join(srcPath, copyFilePath)).isDirectory()) {
247 | return path.join(copyFilePath, '**/*.!(wxss)')
248 | } else {
249 | return copyFilePath
250 | }
251 | } catch (err) {
252 | // eslint-disable-next-line no-console
253 | console.error(err)
254 | return null
255 | }
256 | }).filter(copyFilePath => !!copyFilePath)
257 |
258 | if (copyFileList.length) return copy(copyFileList)
259 |
260 | return done()
261 | }, done => {
262 | const copyList = this.copyList
263 | const copyFileList = copyList.map(copyFilePath => {
264 | try {
265 | if (fs.statSync(path.join(srcPath, copyFilePath)).isDirectory()) {
266 | return path.join(copyFilePath, '**/*.wxss')
267 | } else if (copyFilePath.slice(-5) === '.wxss') {
268 | return copyFilePath
269 | } else {
270 | return null
271 | }
272 | } catch (err) {
273 | // eslint-disable-next-line no-console
274 | console.error(err)
275 | return null
276 | }
277 | }).filter(copyFilePath => !!copyFilePath)
278 |
279 | if (copyFileList.length) return wxss(copyFileList, srcPath, distPath)
280 |
281 | return done()
282 | }))
283 |
284 | /**
285 | * 监听 js 变化
286 | */
287 | gulp.task(`${id}-watch-js`, done => {
288 | if (!jsConfig.webpack) {
289 | return gulp.watch(this.componentListMap.jsFileList, {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-js`))
290 | }
291 |
292 | return done()
293 | })
294 |
295 | /**
296 | * 监听 json 变化
297 | */
298 | gulp.task(`${id}-watch-json`, () => gulp.watch(this.componentListMap.jsonFileList, {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-check`, gulp.parallel(`${id}-component-wxml`, `${id}-component-wxss`, `${id}-component-js`, `${id}-component-json`))))
299 |
300 | /**
301 | * 监听 wxml 变化
302 | */
303 | gulp.task(`${id}-watch-wxml`, () => {
304 | this.cachedComponentListMap.wxmlFileList = null
305 | return gulp.watch(this.componentListMap.wxmlFileList, {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-wxml`))
306 | })
307 |
308 | /**
309 | * 监听 wxss 变化
310 | */
311 | gulp.task(`${id}-watch-wxss`, () => {
312 | this.cachedComponentListMap.wxssFileList = null
313 | return gulp.watch('**/*.wxss', {cwd: srcPath, base: srcPath}, gulp.series(`${id}-component-wxss`))
314 | })
315 |
316 | /**
317 | * 监听相关资源变化
318 | */
319 | gulp.task(`${id}-watch-copy`, () => {
320 | const copyList = this.copyList
321 | const copyFileList = copyList.map(copyFilePath => {
322 | try {
323 | if (fs.statSync(path.join(srcPath, copyFilePath)).isDirectory()) {
324 | return path.join(copyFilePath, '**/*')
325 | } else {
326 | return copyFilePath
327 | }
328 | } catch (err) {
329 | // eslint-disable-next-line no-console
330 | console.error(err)
331 | return null
332 | }
333 | }).filter(copyFilePath => !!copyFilePath)
334 | const watchCallback = filePath => copy([filePath])
335 |
336 | return gulp.watch(copyFileList, {cwd: srcPath, base: srcPath})
337 | .on('change', watchCallback)
338 | .on('add', watchCallback)
339 | .on('unlink', watchCallback)
340 | })
341 |
342 | /**
343 | * 监听 demo 变化
344 | */
345 | gulp.task(`${id}-watch-demo`, () => {
346 | const demoSrc = config.demoSrc
347 | const demoDist = config.demoDist
348 | const watchCallback = filePath => gulp.src(filePath, {cwd: demoSrc, base: demoSrc})
349 | .pipe(gulp.dest(demoDist))
350 |
351 | return gulp.watch('**/*', {cwd: demoSrc, base: demoSrc})
352 | .on('change', watchCallback)
353 | .on('add', watchCallback)
354 | .on('unlink', watchCallback)
355 | })
356 |
357 | /**
358 | * 监听安装包列表变化
359 | */
360 | gulp.task(`${id}-watch-install`, () => gulp.watch(path.resolve(__dirname, '../package.json'), install()))
361 |
362 | /**
363 | * 构建相关任务
364 | */
365 | gulp.task(`${id}-build`, gulp.series(`${id}-clean-dist`, `${id}-component-check`, gulp.parallel(`${id}-component-wxml`, `${id}-component-wxss`, `${id}-component-js`, `${id}-component-json`, `${id}-copy`)))
366 |
367 | gulp.task(`${id}-watch`, gulp.series(`${id}-build`, `${id}-demo`, `${id}-install`, gulp.parallel(`${id}-watch-wxml`, `${id}-watch-wxss`, `${id}-watch-js`, `${id}-watch-json`, `${id}-watch-copy`, `${id}-watch-install`, `${id}-watch-demo`)))
368 |
369 | gulp.task(`${id}-dev`, gulp.series(`${id}-build`, `${id}-demo`, `${id}-install`))
370 |
371 | gulp.task(`${id}-default`, gulp.series(`${id}-build`))
372 | }
373 | }
374 |
375 | module.exports = BuildTask
376 |
--------------------------------------------------------------------------------
/tools/checkcomponents.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | const _ = require('./utils')
4 | const config = require('./config')
5 |
6 | const srcPath = config.srcPath
7 |
8 | /**
9 | * 获取 json 路径相关信息
10 | */
11 | function getJsonPathInfo(jsonPath) {
12 | const dirPath = path.dirname(jsonPath)
13 | const fileName = path.basename(jsonPath, '.json')
14 | const relative = path.relative(srcPath, dirPath)
15 | const fileBase = path.join(relative, fileName)
16 |
17 | return {
18 | dirPath, fileName, relative, fileBase
19 | }
20 | }
21 |
22 | /**
23 | * 检测是否包含其他自定义组件
24 | */
25 | const checkProps = ['usingComponents', 'componentGenerics']
26 | const hasCheckMap = {}
27 | async function checkIncludedComponents(jsonPath, componentListMap) {
28 | const json = _.readJson(jsonPath)
29 | if (!json) throw new Error(`json is not valid: "${jsonPath}"`)
30 |
31 | const {dirPath, fileName, fileBase} = getJsonPathInfo(jsonPath)
32 | if (hasCheckMap[fileBase]) return
33 | hasCheckMap[fileBase] = true
34 |
35 | for (let i = 0, len = checkProps.length; i < len; i++) {
36 | const checkProp = checkProps[i]
37 | const checkPropValue = json[checkProp] || {}
38 | const keys = Object.keys(checkPropValue)
39 |
40 | for (let j = 0, jlen = keys.length; j < jlen; j++) {
41 | const key = keys[j]
42 | let value = typeof checkPropValue[key] === 'object' ? checkPropValue[key].default : checkPropValue[key]
43 | if (!value || typeof value === 'boolean') continue
44 |
45 | value = _.transformPath(value, path.sep)
46 |
47 | // 检查相对路径
48 | const componentPath = `${path.join(dirPath, value)}.json`
49 | const isExists = await _.checkFileExists(componentPath)
50 | if (isExists) {
51 | await checkIncludedComponents(componentPath, componentListMap)
52 | }
53 | }
54 | }
55 |
56 | const wholeFileBase = path.join(dirPath, fileName)
57 | let jsExt = '.js'
58 | const isJsFileExists = await _.checkFileExists(wholeFileBase + '.ts')
59 | if (isJsFileExists) {
60 | jsExt = '.ts'
61 | }
62 |
63 | // 进入存储
64 | componentListMap.wxmlFileList.push(`${fileBase}.wxml`)
65 | componentListMap.wxssFileList.push(`${fileBase}.wxss`)
66 | componentListMap.jsonFileList.push(`${fileBase}.json`)
67 | componentListMap.jsFileList.push(`${fileBase}${jsExt}`)
68 |
69 | componentListMap.jsFileMap[fileBase] = `${wholeFileBase}${jsExt}`
70 | }
71 |
72 | module.exports = async function (entry) {
73 | const componentListMap = {
74 | wxmlFileList: [],
75 | wxssFileList: [],
76 | jsonFileList: [],
77 | jsFileList: [],
78 |
79 | jsFileMap: {}, // 为 webpack entry 所用
80 | }
81 |
82 | const isExists = await _.checkFileExists(entry)
83 | if (!isExists) {
84 | const {dirPath, fileName, fileBase} = getJsonPathInfo(entry)
85 |
86 | const wholeFileBase = path.join(dirPath, fileName)
87 | let jsExt = '.js'
88 | const isJsFileExists = await _.checkFileExists(wholeFileBase + '.ts')
89 | if (isJsFileExists) {
90 | jsExt = '.ts'
91 | }
92 | componentListMap.jsFileList.push(`${fileBase}${jsExt}`)
93 | componentListMap.jsFileMap[fileBase] = `${wholeFileBase}${jsExt}`
94 |
95 | return componentListMap
96 | }
97 |
98 | await checkIncludedComponents(entry, componentListMap)
99 |
100 | return componentListMap
101 | }
102 |
--------------------------------------------------------------------------------
/tools/checkwxss.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const through = require('through2')
3 | const Vinyl = require('vinyl')
4 |
5 | const _ = require('./utils')
6 |
7 | /**
8 | * 获取 import 列表
9 | */
10 | function getImportList(wxss, filePath) {
11 | const reg = /@import\s+(?:(?:"([^"]+)")|(?:'([^']+)'));/ig
12 | const importList = []
13 | let execRes = reg.exec(wxss)
14 |
15 | while (execRes && (execRes[1] || execRes[2])) {
16 | importList.push({
17 | code: execRes[0],
18 | path: path.join(path.dirname(filePath), execRes[1] || execRes[2]),
19 | })
20 | execRes = reg.exec(wxss)
21 | }
22 |
23 | return importList
24 | }
25 |
26 | /**
27 | * 获取 wxss 内容
28 | */
29 | async function getContent(wxss, filePath, cwd) {
30 | let importList = []
31 |
32 | if (wxss) {
33 | const currentImportList = getImportList(wxss, filePath)
34 |
35 | for (const item of currentImportList) {
36 | // 替换掉 import 语句,不让 less 编译
37 | wxss = wxss.replace(item.code, `/* *updated for miniprogram-custom-component* ${item.code} */`)
38 |
39 | // 处理依赖的 wxss
40 | const importWxss = await _.readFile(item.path)
41 | const importInfo = await getContent(importWxss, item.path, cwd)
42 |
43 | // 获取依赖列表
44 | importList.push(new Vinyl({
45 | cwd,
46 | path: item.path,
47 | contents: Buffer.from(importInfo.wxss, 'utf8'),
48 | }))
49 | importList = importList.concat(importInfo.importList)
50 | }
51 | }
52 |
53 | return {
54 | wxss,
55 | importList,
56 | }
57 | }
58 |
59 | module.exports = {
60 | start() {
61 | return through.obj(function (file, enc, cb) {
62 | if (file.isBuffer()) {
63 | getContent(file.contents.toString('utf8'), file.path, file.cwd).then(res => {
64 | const {wxss, importList} = res
65 |
66 | importList.forEach(importFile => this.push(importFile))
67 |
68 | file.contents = Buffer.from(wxss, 'utf8')
69 | this.push(file)
70 | // eslint-disable-next-line promise/no-callback-in-promise
71 | cb()
72 | }).catch(err => {
73 | // eslint-disable-next-line no-console
74 | console.warn(`deal with ${file.path} failed: ${err.stack}`)
75 | this.push(file)
76 | // eslint-disable-next-line promise/no-callback-in-promise
77 | cb()
78 | })
79 | } else {
80 | this.push(file)
81 | cb()
82 | }
83 | })
84 | },
85 |
86 | end() {
87 | return through.obj(function (file, enc, cb) {
88 | if (file.isBuffer) {
89 | const reg = /\/\*\s\*updated for miniprogram-custom-component\*\s(@import\s+(?:(?:"([^"]+)")|(?:'([^"]+)'));)\s\*\//ig
90 | const wxss = file.contents.toString('utf8').replace(reg, (all, $1) => $1)
91 |
92 | file.contents = Buffer.from(wxss, 'utf8')
93 | this.push(file)
94 | cb()
95 | } else {
96 | this.push(file)
97 | cb()
98 | }
99 | })
100 | },
101 | }
102 |
--------------------------------------------------------------------------------
/tools/config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 |
3 | const webpack = require('webpack')
4 | const nodeExternals = require('webpack-node-externals')
5 |
6 | const isDev = process.argv.indexOf('--develop') >= 0
7 | const isWatch = process.argv.indexOf('--watch') >= 0
8 | const demoSrc = path.resolve(__dirname, './demo')
9 | const demoDist = path.resolve(__dirname, '../miniprogram_dev')
10 | const src = path.resolve(__dirname, '../src')
11 | const dev = path.join(demoDist, 'components')
12 | const dist = path.resolve(__dirname, '../miniprogram_dist')
13 |
14 | module.exports = {
15 | entry: ['index', 'lib'],
16 |
17 | isDev,
18 | isWatch,
19 | srcPath: src, // 源目录
20 | distPath: isDev ? dev : dist, // 目标目录
21 |
22 | demoSrc, // demo 源目录
23 | demoDist, // demo 目标目录
24 |
25 | wxss: {
26 | less: false, // 使用 less 来编写 wxss
27 | sourcemap: false, // 生成 less sourcemap
28 | },
29 |
30 | js: {
31 | webpack: true, // 使用 webpack 来构建 js
32 | },
33 |
34 | webpack: {
35 | mode: 'production',
36 | output: {
37 | filename: '[name].js',
38 | libraryTarget: 'commonjs2',
39 | },
40 | target: 'node',
41 | externals: [nodeExternals()], // 忽略 node_modules
42 | module: {
43 | rules: [{
44 | test: /\.js$/i,
45 | use: [{
46 | loader: 'thread-loader',
47 | }, {
48 | loader: 'babel-loader',
49 | options: {
50 | cacheDirectory: true,
51 | },
52 | },
53 | ],
54 | exclude: /node_modules/
55 | }, {
56 | test: /\.ts$/,
57 | exclude: /node_modules/,
58 | use: [{
59 | loader: 'thread-loader',
60 | }, {
61 | loader: 'babel-loader',
62 | options: {
63 | cacheDirectory: true,
64 | },
65 | }, {
66 | loader: 'ts-loader',
67 | options: {
68 | appendTsSuffixTo: [/\.vue$/],
69 | happyPackMode: true,
70 | },
71 | },
72 | ],
73 | }],
74 | },
75 | resolve: {
76 | modules: [src, 'node_modules'],
77 | extensions: ['.js', '.json'],
78 | },
79 | plugins: [
80 | new webpack.DefinePlugin({}),
81 | new webpack.optimize.LimitChunkCountPlugin({maxChunks: 1}),
82 | ],
83 | optimization: {
84 | minimize: false,
85 | },
86 | devtool: 'source-map', // 生成 js sourcemap
87 | performance: {
88 | hints: 'warning',
89 | assetFilter: assetFilename => assetFilename.endsWith('.js')
90 | }
91 | },
92 |
93 | copy: ['./assets', './utils.js'], // 将会复制到目标目录
94 | }
95 |
--------------------------------------------------------------------------------
/tools/demo/app.js:
--------------------------------------------------------------------------------
1 | App({})
2 |
--------------------------------------------------------------------------------
/tools/demo/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":[
3 | "pages/index/index"
4 | ],
5 | "window":{
6 | "backgroundTextStyle":"light",
7 | "navigationBarBackgroundColor": "#fff",
8 | "navigationBarTitleText": "WeChat",
9 | "navigationBarTextStyle":"black"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tools/demo/app.wxss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/tools/demo/app.wxss
--------------------------------------------------------------------------------
/tools/demo/package.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/tools/demo/pages/index/index.js:
--------------------------------------------------------------------------------
1 | Page({})
2 |
--------------------------------------------------------------------------------
/tools/demo/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {
2 | "usingComponents": {
3 | "comp": "../../components/index"
4 | }
5 | }
--------------------------------------------------------------------------------
/tools/demo/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tools/demo/pages/index/index.wxss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/habc0807/miniprogram-table-component/be20af2c32e8616de021de2642e53ad5c8de15ac/tools/demo/pages/index/index.wxss
--------------------------------------------------------------------------------
/tools/demo/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "packOptions": {
4 | "ignore": []
5 | },
6 | "setting": {
7 | "urlCheck": true,
8 | "es6": true,
9 | "postcss": true,
10 | "minified": true,
11 | "newFeature": true,
12 | "nodeModules": true
13 | },
14 | "compileType": "miniprogram",
15 | "libVersion": "2.10.4",
16 | "appid": "",
17 | "projectname": "miniprogram-demo",
18 | "isGameTourist": false,
19 | "condition": {
20 | "search": {
21 | "current": -1,
22 | "list": []
23 | },
24 | "conversation": {
25 | "current": -1,
26 | "list": []
27 | },
28 | "game": {
29 | "currentL": -1,
30 | "list": []
31 | },
32 | "miniprogram": {
33 | "current": -1,
34 | "list": []
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/tools/utils.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs')
2 | const path = require('path')
3 |
4 | // eslint-disable-next-line no-unused-vars
5 | const colors = require('colors')
6 | const through = require('through2')
7 |
8 | /**
9 | * 异步函数封装
10 | */
11 | function wrap(func, scope) {
12 | return function (...args) {
13 | if (args.length) {
14 | const temp = args.pop()
15 | if (typeof temp !== 'function') {
16 | args.push(temp)
17 | }
18 | }
19 |
20 | return new Promise(function (resolve, reject) {
21 | args.push(function (err, data) {
22 | if (err) reject(err)
23 | else resolve(data)
24 | })
25 |
26 | func.apply((scope || null), args)
27 | })
28 | }
29 | }
30 |
31 | const accessSync = wrap(fs.access)
32 | const statSync = wrap(fs.stat)
33 | const renameSync = wrap(fs.rename)
34 | const mkdirSync = wrap(fs.mkdir)
35 | const readFileSync = wrap(fs.readFile)
36 | const writeFileSync = wrap(fs.writeFile)
37 |
38 | /**
39 | * 调整路径分隔符
40 | */
41 | function transformPath(filePath, sep = '/') {
42 | return filePath.replace(/[\\/]/g, sep)
43 | }
44 |
45 | /**
46 | * 检查文件是否存在
47 | */
48 | async function checkFileExists(filePath) {
49 | try {
50 | await accessSync(filePath)
51 | return true
52 | } catch (err) {
53 | return false
54 | }
55 | }
56 |
57 | /**
58 | * 递归创建目录
59 | */
60 | async function recursiveMkdir(dirPath) {
61 | const prevDirPath = path.dirname(dirPath)
62 | try {
63 | await accessSync(prevDirPath)
64 | } catch (err) {
65 | // 上一级目录不存在
66 | await recursiveMkdir(prevDirPath)
67 | }
68 |
69 | try {
70 | await accessSync(dirPath)
71 |
72 | const stat = await statSync(dirPath)
73 | if (stat && !stat.isDirectory()) {
74 | // 目标路径存在,但不是目录
75 | await renameSync(dirPath, `${dirPath}.bak`) // 将此文件重命名为 .bak 后缀
76 | await mkdirSync(dirPath)
77 | }
78 | } catch (err) {
79 | // 目标路径不存在
80 | await mkdirSync(dirPath)
81 | }
82 | }
83 |
84 | /**
85 | * 读取 json
86 | */
87 | function readJson(filePath) {
88 | try {
89 | // eslint-disable-next-line import/no-dynamic-require
90 | const content = require(filePath)
91 | delete require.cache[require.resolve(filePath)]
92 | return content
93 | } catch (err) {
94 | return null
95 | }
96 | }
97 |
98 | /**
99 | * 读取文件
100 | */
101 | async function readFile(filePath) {
102 | try {
103 | return await readFileSync(filePath, 'utf8')
104 | } catch (err) {
105 | // eslint-disable-next-line no-console
106 | return console.error(err)
107 | }
108 | }
109 |
110 | /**
111 | * 写文件
112 | */
113 | async function writeFile(filePath, data) {
114 | try {
115 | await recursiveMkdir(path.dirname(filePath))
116 | return await writeFileSync(filePath, data, 'utf8')
117 | } catch (err) {
118 | // eslint-disable-next-line no-console
119 | return console.error(err)
120 | }
121 | }
122 |
123 | /**
124 | * 时间格式化
125 | */
126 | function format(time, reg) {
127 | const date = typeof time === 'string' ? new Date(time) : time
128 | const map = {}
129 | map.yyyy = date.getFullYear()
130 | map.yy = ('' + map.yyyy).substr(2)
131 | map.M = date.getMonth() + 1
132 | map.MM = (map.M < 10 ? '0' : '') + map.M
133 | map.d = date.getDate()
134 | map.dd = (map.d < 10 ? '0' : '') + map.d
135 | map.H = date.getHours()
136 | map.HH = (map.H < 10 ? '0' : '') + map.H
137 | map.m = date.getMinutes()
138 | map.mm = (map.m < 10 ? '0' : '') + map.m
139 | map.s = date.getSeconds()
140 | map.ss = (map.s < 10 ? '0' : '') + map.s
141 |
142 | return reg.replace(/\byyyy|yy|MM|M|dd|d|HH|H|mm|m|ss|s\b/g, $1 => map[$1])
143 | }
144 |
145 | /**
146 | * 日志插件
147 | */
148 | function logger(action = 'copy') {
149 | return through.obj(function (file, enc, cb) {
150 | const type = path.extname(file.path).slice(1).toLowerCase()
151 |
152 | // eslint-disable-next-line no-console
153 | console.log(`[${format(new Date(), 'yyyy-MM-dd HH:mm:ss').grey}] [${action.green} ${type.green}] ${'=>'.cyan} ${file.path}`)
154 |
155 | this.push(file)
156 | cb()
157 | })
158 | }
159 |
160 | /**
161 | * 比较数组是否相等
162 | */
163 | function compareArray(arr1, arr2) {
164 | if (!Array.isArray(arr1) || !Array.isArray(arr2)) return false
165 | if (arr1.length !== arr2.length) return false
166 |
167 | for (let i = 0, len = arr1.length; i < len; i++) {
168 | if (arr1[i] !== arr2[i]) return false
169 | }
170 |
171 | return true
172 | }
173 |
174 | /**
175 | * 合并两个对象
176 | */
177 | function merge(obj1, obj2) {
178 | Object.keys(obj2).forEach(key => {
179 | if (Array.isArray(obj1[key]) && Array.isArray(obj2[key])) {
180 | obj1[key] = obj1[key].concat(obj2[key])
181 | } else if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
182 | obj1[key] = Object.assign(obj1[key], obj2[key])
183 | } else {
184 | obj1[key] = obj2[key]
185 | }
186 | })
187 |
188 | return obj1
189 | }
190 |
191 | /**
192 | * 获取 id
193 | */
194 | let seed = +new Date()
195 | function getId() {
196 | return ++seed
197 | }
198 |
199 | module.exports = {
200 | wrap,
201 | transformPath,
202 |
203 | checkFileExists,
204 | readJson,
205 | readFile,
206 | writeFile,
207 |
208 | logger,
209 | format,
210 | compareArray,
211 | merge,
212 | getId,
213 | }
214 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "esnext",
4 | "target": "es2015",
5 | "lib": ["es2015", "es2017", "dom"],
6 | "noImplicitAny": false,
7 | "moduleResolution": "node",
8 | "sourceMap": true,
9 | "baseUrl": ".",
10 | "allowSyntheticDefaultImports": true,
11 | "experimentalDecorators": true,
12 | "emitDecoratorMetadata":true,
13 | "esModuleInterop": true,
14 | "resolveJsonModule": true
15 | },
16 | "files": [
17 | "node_modules/miniprogram-api-typings/index.d.ts"
18 | ],
19 | "include": [
20 | "src/**/*.ts"
21 | ],
22 | "exclude": [
23 | "node_modules"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------