├── pages
├── form
│ ├── form.json
│ ├── form.wxss
│ ├── form.wxml
│ └── form.js
├── dataset
│ ├── dataset.json
│ ├── dataset.wxss
│ ├── dataset.wxml
│ └── dataset.js
├── index
│ ├── index.json
│ ├── index.wxss
│ ├── index.wxml
│ └── index.js
├── request
│ ├── request.json
│ ├── request.wxss
│ ├── request.wxml
│ └── request.js
├── elements
│ ├── elements.json
│ ├── elements.wxss
│ ├── elements.wxml
│ └── elements.js
├── pageevent
│ ├── pageevent.json
│ ├── pageevent.wxss
│ ├── pageevent.wxml
│ └── pageevent.js
├── components
│ ├── components.json
│ ├── components.wxss
│ ├── components.wxml
│ └── components.js
└── simple_app
│ ├── simple_app.json
│ ├── simple_app.wxss
│ ├── simple_app.wxml
│ └── simple_app.js
├── pages_bac
├── index
│ ├── index.json
│ ├── index.wxml
│ ├── index.js
│ └── index.wxss
├── scan_store
│ ├── scan_store.json
│ ├── scan_store.wxss
│ ├── scan_store.js
│ └── scan_store.wxml
├── logs
│ ├── logs.json
│ ├── logs.wxss
│ ├── logs.wxml
│ └── logs.js
└── test-1
│ ├── test-1.json
│ ├── test-1.wxss
│ ├── test-1.wxml
│ └── test-1.js
├── pages.zip
├── images
├── Grid.png
├── User.png
└── Camera.png
├── plugins
├── loader.js
└── switcher
│ ├── switcher.wxss
│ └── switcher.js
├── MinQuery
├── source
│ ├── global
│ │ ├── update.js
│ │ ├── index.js
│ │ ├── pages.js
│ │ ├── servers.js
│ │ ├── events.js
│ │ └── module.js
│ ├── utils
│ │ ├── index.js
│ │ ├── systemInfo.js
│ │ ├── styles.js
│ │ ├── path.js
│ │ ├── dataEngine.js
│ │ └── tools.js
│ ├── config
│ │ ├── mq_config.js
│ │ └── wx_config.js
│ ├── wx
│ │ └── methods.js
│ └── third_part
│ │ └── thenjs.js
└── index.js
├── common.wxss
├── utils
└── util.js
├── app.json
├── LICENSE
├── app.wxss
├── app.js
├── README.md
└── MinQuery-API.md
/pages/form/form.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/dataset/dataset.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/index/index.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/request/request.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages_bac/index/index.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/elements/elements.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/pageevent/pageevent.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/components/components.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages/simple_app/simple_app.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages_bac/scan_store/scan_store.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/pages.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JasonDRZ/MinQuery/HEAD/pages.zip
--------------------------------------------------------------------------------
/pages_bac/logs/logs.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "查看启动日志"
3 | }
--------------------------------------------------------------------------------
/pages_bac/test-1/test-1.json:
--------------------------------------------------------------------------------
1 | {
2 | "navigationBarTitleText": "Test-1"
3 | }
--------------------------------------------------------------------------------
/images/Grid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JasonDRZ/MinQuery/HEAD/images/Grid.png
--------------------------------------------------------------------------------
/images/User.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JasonDRZ/MinQuery/HEAD/images/User.png
--------------------------------------------------------------------------------
/images/Camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JasonDRZ/MinQuery/HEAD/images/Camera.png
--------------------------------------------------------------------------------
/plugins/loader.js:
--------------------------------------------------------------------------------
1 | var pluginLoader = function(plugin){
2 | var t_p = require(plugin+"/"+plugin);
3 | return t_p.plugin;
4 | }
5 |
6 | exports.load = pluginLoader;
--------------------------------------------------------------------------------
/pages/form/form.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .dataset-object{
5 | padding: 10px 0;
6 |
7 | }
8 | button{
9 | margin-bottom: 10px;
10 | }
--------------------------------------------------------------------------------
/pages/dataset/dataset.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .dataset-object{
5 | padding: 10px 0;
6 |
7 | }
8 | button{
9 | margin-bottom: 10px;
10 | }
--------------------------------------------------------------------------------
/pages/request/request.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .dataset-object{
5 | padding: 10px 0;
6 |
7 | }
8 | button{
9 | margin-bottom: 10px;
10 | }
--------------------------------------------------------------------------------
/MinQuery/source/global/update.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/19.
3 | * This global method use to watching the Framework's global data changes,and updating all of the page instances in the same time;
4 | */
5 |
--------------------------------------------------------------------------------
/pages/pageevent/pageevent.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .dataset-object{
5 | padding: 10px 0;
6 |
7 | }
8 | button{
9 | margin-bottom: 10px;
10 | }
--------------------------------------------------------------------------------
/pages/simple_app/simple_app.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .dataset-object{
5 | padding: 10px 0;
6 |
7 | }
8 | button{
9 | margin-bottom: 10px;
10 | }
--------------------------------------------------------------------------------
/pages_bac/logs/logs.wxss:
--------------------------------------------------------------------------------
1 | .log-list {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 40rpx;
5 | }
6 | .log-item {
7 | margin: 10rpx;
8 | }
9 |
10 | .active{
11 | color: red;
12 | }
13 | .disable{
14 | color: blue;
15 | }
--------------------------------------------------------------------------------
/MinQuery/source/global/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 |
5 | module.exports = {
6 | $events: require('events'),
7 | $pages: require('pages'),
8 | $servers: require('servers'),
9 | $module: require('module')
10 | }
--------------------------------------------------------------------------------
/pages_bac/test-1/test-1.wxss:
--------------------------------------------------------------------------------
1 | .log-list {
2 | display: flex;
3 | flex-direction: column;
4 | padding: 40rpx;
5 | }
6 | .log-item {
7 | margin: 10rpx;
8 | }
9 |
10 | .active{
11 | color: red;
12 | }
13 | .disable{
14 | color: blue;
15 | }
--------------------------------------------------------------------------------
/common.wxss:
--------------------------------------------------------------------------------
1 | .operation_block{
2 | padding: 15px;
3 | background-color: #fff;
4 | width: 100%;
5 | margin-bottom: 10px
6 | }
7 | .block_title{
8 | padding: 10px 0;
9 | border-bottom: 1px solid #eee;
10 | }
11 | .block_body{
12 | padding: 10px 0;
13 | }
--------------------------------------------------------------------------------
/pages/components/components.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .banner_item{
5 | background-position: center;
6 | background-repeat: no-repeat;
7 | background-size: cover;
8 | }
9 | .dataset-object{
10 | padding: 10px 0;
11 |
12 | }
13 | button{
14 | margin-bottom: 10px;
15 | }
--------------------------------------------------------------------------------
/pages/elements/elements.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | @import "../../common.wxss";
4 | .banner_item{
5 | background-position: center;
6 | background-repeat: no-repeat;
7 | background-size: cover;
8 | }
9 |
10 | .dataset-object{
11 | padding: 10px 0;
12 |
13 | }
14 | button{
15 | margin-bottom: 10px;
16 | }
--------------------------------------------------------------------------------
/MinQuery/source/utils/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('tools');
5 |
6 | $tools.extend(require('styles'));
7 |
8 | $tools.extend(require('systemInfo'));
9 |
10 | $tools.extend(require('path'));
11 |
12 | $tools.extend(require('dataEngine'));
13 |
14 | $tools.extend(require('../third_part/thenjs'));
15 |
16 |
17 | module.exports = $tools;
--------------------------------------------------------------------------------
/plugins/switcher/switcher.wxss:
--------------------------------------------------------------------------------
1 | .tab_switch_box{
2 | position: relative;
3 | width: 100%;
4 | height: 100%;
5 |
6 | }
7 | .tab_header{
8 | height: 30px;
9 | line-height: 30px;
10 | background-color: #fff;
11 | display: flex;
12 | flex-direction: row;
13 | }
14 | .tab_header view.header_list{
15 | flex: 1;
16 | text-align: center;
17 | }
18 | .tab_header view.header_list.active{
19 | border-bottom: 2px solid #EFEFEF
20 | }
--------------------------------------------------------------------------------
/pages/pageevent/pageevent.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page自定义事件绑定
5 |
6 |
7 | Author: {{author}};
8 |
9 |
10 | Gander: {{gander}};
11 |
12 |
13 | Work: {{work}};
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/utils/util.js:
--------------------------------------------------------------------------------
1 | function formatTime(date) {
2 | var year = date.getFullYear()
3 | var month = date.getMonth() + 1
4 | var day = date.getDate()
5 |
6 | var hour = date.getHours()
7 | var minute = date.getMinutes()
8 | var second = date.getSeconds()
9 |
10 |
11 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
12 | }
13 |
14 | function formatNumber(n) {
15 | n = n.toString()
16 | return n[1] ? n : '0' + n
17 | }
18 |
19 | module.exports = {
20 | formatTime: formatTime
21 | }
22 |
--------------------------------------------------------------------------------
/pages_bac/scan_store/scan_store.wxss:
--------------------------------------------------------------------------------
1 | @import "../../app.wxss";
2 | @import "../../plugins/switcher/switcher.wxss";
3 | .store_scanner{
4 | z-index: 9999;
5 | position: fixed;
6 | bottom: 30px;
7 | left: 50%;
8 | transform: translateX(-50%);
9 | height: 30px;
10 | width: 90px;
11 | padding: 5px 10px;
12 | line-height: 20px;
13 | background-color: #fff;
14 | border-radius: 20px;
15 | box-shadow: 0 0 15px #000;
16 | }
17 | .store_scanner image {
18 | float: left;
19 | height: 20px;
20 | width: 20px;
21 | margin: 0 10px 0 5px;
22 | }
23 |
24 | .borderText{
25 | display: block;
26 | padding: 5px;
27 | border: 1px solid #000;
28 | }
--------------------------------------------------------------------------------
/pages/index/index.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | view{
4 | box-sizing: border-box;
5 | }
6 | .header{
7 | background-color: #f1f1f1;
8 | }
9 | .header-title{
10 | padding-top: 4rem;
11 | text-align: center;
12 | font-size: 1.6rem;
13 | }
14 | .header-info{
15 | padding: 2rem;
16 | text-align: center;
17 | font-size: 14px;
18 | line-height: 1.7em;
19 | color: #888;
20 | }
21 | .cotainer{
22 | padding: 10px;
23 | }
24 | .guide-item{
25 | padding: 15px;
26 | background-color: #fff;
27 | border-radius: 3px;
28 | margin: 10px 0;
29 | }
30 | .guide-item::after{
31 | content: '>';
32 | float: right;
33 | }
--------------------------------------------------------------------------------
/pages/request/request.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 远程数据-Comments
5 |
6 |
7 | Title: {{item.title}}
8 | Content: {{item.body}}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages":[
3 | "pages/components/components",
4 | "pages/index/index",
5 | "pages/dataset/dataset",
6 | "pages/elements/elements",
7 | "pages/pageevent/pageevent",
8 | "pages/request/request",
9 | "pages/form/form",
10 |
11 | "pages/simple_app/simple_app"
12 |
13 |
14 |
15 |
16 |
17 | ],
18 | "window":{
19 | "backgroundTextStyle":"light",
20 | "navigationBarBackgroundColor": "#fff",
21 | "navigationBarTitleText": "WeChat",
22 | "navigationBarTextStyle":"black"
23 | },
24 | "tabBar": {
25 | "list": [{
26 | "pagePath": "pages/index/index",
27 | "text": "课程"
28 | }, {
29 | "pagePath": "pages/components/components",
30 | "text": "Now"
31 | }]
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/pages/elements/elements.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 操作元素样式
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/pages/pageevent/pageevent.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('pageevent');
3 |
4 | let author = $.setData('author', "");//与使用当个兑现字段的方法相同 $.setData({'author':"JasonDRZ"});
5 | let info = $.setData({
6 | 'gander': '',
7 | 'work': ''
8 | })
9 |
10 | const _page = $('page');
11 |
12 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
13 | $(function () {
14 | console.info('复杂执行逻辑请一定使用此主运行方法来执行Page对象的自定义事件、数据绑定操作,确保自定义事件和数据的正确注入');
15 |
16 | // 在Page实例对象上绑定自定义处理方法
17 | _page.bind('changeAuther', function () {
18 | author.set('I am JasonD');
19 | })
20 | // 原生Page页面事件监听
21 | .on("ready",function(){
22 | author.set('JasonDRZ');
23 | }).on('load',function(e){
24 | console.log(e)
25 | info.gander.set('Male');
26 | info.work.set("WEB Front-End");
27 | });
28 |
29 |
30 | });
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/pages_bac/test-1/test-1.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{index + 1}}. {{log}}
5 |
6 | 测试事件1
7 | 测试事件2
8 | 测试事件3{{$data.name}}
9 | 测试事件4
10 | 测试事件5
11 |
12 |
13 |
--------------------------------------------------------------------------------
/pages/elements/elements.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('elements');
3 |
4 |
5 |
6 | let _swiper = $("#swiper_id");
7 | //
8 | _swiper.config({
9 | indicatorDots: true,
10 | autoplay: true,
11 | current: 0,
12 | interval: 1000,
13 | duration: 1000
14 | })
15 | // 设置当前元素的数据
16 | .data([
17 | 'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
18 | 'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
19 | 'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
20 | ]);
21 |
22 |
23 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
24 | $(function () {
25 | $("page").on('load',function(){
26 | console.log(_swiper);
27 | })
28 | //
29 | _swiper.on('change', function (e) {
30 | console.log(e);
31 | }).on('touchstart', function (e) {
32 | $(this).config('autoplay', false);
33 | }).on('touchend', function (e) {
34 | $(this).config().autoplay(true);
35 | });
36 |
37 | });
38 |
39 |
--------------------------------------------------------------------------------
/pages/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 | Page事件绑定
11 | 数据设置
12 | 元素操作及事件绑定
13 | Ajax请求
14 | 视图组件
15 | 表单方法
16 | 简单app
17 |
18 |
--------------------------------------------------------------------------------
/MinQuery/source/utils/systemInfo.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('tools');
5 |
6 | // bind system info
7 | let getSystemInfo = function (cb) {
8 | let sys, res = {};
9 | try {
10 | sys = wx.getSystemInfoSync();
11 | // res.model pixelRatio windowWidth windowHeight language version platform
12 | res.DPI = sys.pixelRatio;
13 | res.width = sys.windowWidth;
14 | res.height = sys.windowHeight;
15 | delete sys.pixelRatio;
16 | delete sys.windowHeight;
17 | delete sys.windowWidth;
18 | $tools.extend(res, sys);
19 | $tools.isFunction(cb) && cb(res);
20 | } catch (e) {
21 | // try async model
22 | wx.getSystemInfo({
23 | success: function (sys) {
24 | res.DPI = sys.pixelRatio;
25 | res.width = sys.windowWidth;
26 | res.height = sys.windowHeight;
27 | delete sys.pixelRatio;
28 | delete sys.windowHeight;
29 | delete sys.windowWidth;
30 | $tools.extend(res, sys);
31 | $tools.isFunction(cb) && cb(res);
32 | }
33 | })
34 | }
35 | };
36 |
37 | module.exports = {
38 | getSystemInfo
39 | };
--------------------------------------------------------------------------------
/MinQuery/source/global/pages.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | // 页面MQ对象存储器,仅在页面被load后才加载到此对象上,unload后卸载相应页面对象
5 | // 获取/打开打开的页面MQ实例对象
6 | const $pages = {
7 | // 页面标示,用于存储对应页面的MinQuery对象,防止二次注册页面
8 | __registeredPages__: {},
9 | //存储页面的实例对象数据
10 | __loadedInstances__: {},
11 | //获取对应页面的对象或是数据【仅能是已经打开的页面】
12 | get(pageName) {
13 | if (pageName) {
14 | if (pageName in this.__loadedInstances__ && this.__loadedInstances__[pageName].isReady) {
15 | return this.__loadedInstances__[pageName];
16 | } else {
17 | return undefined;
18 | }
19 | } else {
20 | return this.__loadedInstances__;
21 | }
22 | },
23 | set(pageName, tMQ) {
24 | if (pageName) {
25 | if (!!tMQ && !!tMQ.expando && pageName in this.__loadedInstances__) {
26 | console.error("Page Loaded instance can not be registered twice!", pageName);
27 | return;
28 | }
29 | if (tMQ === null) {
30 | delete this.__loadedInstances__[pageName];
31 | } else if (!!tMQ.expando) {
32 | this.__loadedInstances__[pageName] = tMQ;
33 | }
34 | }
35 | }
36 | };
37 |
38 | module.exports = $pages;
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 JasonD
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 |
--------------------------------------------------------------------------------
/MinQuery/index.js:
--------------------------------------------------------------------------------
1 | // components
2 | var MinQuery = require("components/minquery-dev");
3 | // MinQuery.plugin("$wx",{expando:false});
4 | module.exports = MinQuery;
5 |
6 | // var cloneMinQuery = function (pname) {
7 | // var _cloneMQ = function(){};
8 | // _cloneMQ.prototype = (new MinQuery).constructor;
9 | // _cloneMQ.prototype.indicater = pname;
10 | // return _cloneMQ;
11 | // }
12 |
13 | // // 为区分不同Page使用Symbol作为键值存储当前copy MinQuery;
14 | // var rootMinQuery = {};
15 |
16 | // // 绑定到wx对象上
17 | // wx.MinQuery = {
18 | // load(pageName) {
19 | // if (!pageName) {
20 | // console.error("MinQuery load requires pageName for load method!");
21 | // return;
22 | // }
23 | // if (rootMinQuery[pageName]) {
24 | // console.error(`MinQuery load target name [${pageName}] has already been registered,please check!`);
25 | // return;
26 | // }
27 | // rootMinQuery[pageName] = cloneMinQuery(pageName);
28 | // return rootMinQuery[pageName];
29 | // }
30 | // };
31 | // console.info(wx)
32 | // module.exports = wx.MinQuery;
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/pages/form/form.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page自定义事件绑定
5 |
6 |
7 | Author: {{author}};
8 |
9 |
10 | Gander: {{gander}};
11 |
12 |
13 | Work: {{work}};
14 |
15 |
16 |
17 |
18 |
19 | 素组数据设置
20 |
21 |
22 | This is a forEach Item,index: {{item}};
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/pages/simple_app/simple_app.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Page自定义事件绑定
5 |
6 |
7 | Author: {{author}};
8 |
9 |
10 | Gander: {{gander}};
11 |
12 |
13 | Work: {{work}};
14 |
15 |
16 |
17 |
18 |
19 | 素组数据设置
20 |
21 |
22 | This is a forEach Item,index: {{item}};
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/pages/components/components.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Swiper组件
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 当前是第 {{$id.swiper_id.$data.current}} 张
13 |
14 |
15 |
16 |
17 | Canvas组件
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/pages_bac/index/index.wxml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/pages/dataset/dataset.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 对象数据设置
5 |
6 |
7 | Author: {{author}};
8 |
9 |
10 | Gander: {{gander}};
11 |
12 |
13 | Work: {{work}};
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | 素组数据设置
23 |
24 |
25 | This is a forEach Item,index: {{item}};
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app.wxss:
--------------------------------------------------------------------------------
1 | /* 基础样式 */
2 | view, scroll-view, swiper, swiper-item, icon, text, progress, button,
3 | checkbox-group, checkbox, form, input, label, picker, radio-group, radio, slider,
4 | switch, action-sheet, action-sheet-item, action-sheet-cancel, modal, toast,
5 | loading, navigator, audio, image, video, map, canvas {
6 | -webkit-box-sizing: border-box;
7 | -moz-box-sizing: border-box;
8 | box-sizing: border-box;
9 | font-size: 14px;
10 | }
11 |
12 | page {
13 | height: 100%;
14 | font-family: -apple-system-font, Helvetica Neue, Helvetica, sans-serif;
15 | background-color: #efefef;
16 | }
17 | view{
18 | box-sizing: border-box;
19 | }
20 |
21 | checkbox-group, radio-group {
22 | display: block;
23 | }
24 |
25 | :before, :after, ::before, ::after {
26 | -webkit-box-sizing: border-box;
27 | -moz-box-sizing: border-box;
28 | box-sizing: border-box;
29 | }
30 | /*公共样式*/
31 | .com_minheight {
32 | min-height: 60px;
33 | }
34 |
35 | .com_full {
36 | width: 100%;
37 | height: 100%;
38 | }
39 |
40 | .com_block {
41 | display: block;
42 | }
43 |
44 | .com_autosize {
45 | width: auto;
46 | height: auto;
47 | }
48 |
49 | .com_fullwidth {
50 | width: 100%;
51 | }
52 |
53 | .com_fullheight {
54 | height: 100%;
55 | }
56 |
57 | .com_initHide {
58 | opacity: 0 !important;
59 | }
60 |
61 | .com_ellipse {
62 | text-overflow: ellipsis;
63 | display: -webkit-box;
64 | -webkit-box-orient: vertical;
65 | -webkit-line-clamp: 2;
66 | overflow: hidden;
67 | }
68 |
--------------------------------------------------------------------------------
/plugins/switcher/switcher.js:
--------------------------------------------------------------------------------
1 | var switcherConfig = {
2 | header: {},
3 | body: {}
4 | };
5 | var currentElement = null;
6 |
7 | var handleConfig = function (arr) {
8 | arr.forEach(function (s, i) {
9 | if (i == 0) {
10 | switcherConfig.header[s] = "active";
11 | switcherConfig.body[s] = "active";
12 | } else {
13 | switcherConfig.header[s] = "";
14 | switcherConfig.body[s] = "";
15 | }
16 | })
17 | getCurrentPages().pop().switcher = {
18 | trigger: function (e) {
19 | currentElement = e;
20 | console.log(e);
21 | getCurrentPages().pop().setData({
22 | switcher: switcherConfig
23 | })
24 | }
25 | };
26 | getCurrentPages().pop().setData({
27 | switcher: switcherConfig
28 | });
29 | }
30 |
31 | var switchActive = function (key) {
32 | var _h = switcherConfig.switcherHeader;
33 | var _b = switcherConfig.switcherBody;
34 | for (var h in _h) {
35 | h === key ? (_h[h] = "active") : (_h[h] = "");
36 | }
37 | for (var b in _b) {
38 | b === key ? (_b[b] = "active") : (_b[b] = "");
39 | }
40 | }
41 |
42 |
43 | exports.plugin = function (switches) {
44 | switches = switches ? switches : ["history", "comment"];
45 | handleConfig(switches);
46 | return {
47 | switch: function (ele) {
48 | getCurrentPages().pop().data.switcher
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/pages/components/components.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('components');
3 |
4 | let _swiper = $("#swiper_id");
5 | //
6 | _swiper.config({
7 | indicatorDots: true,
8 | autoplay: true,
9 | current: 1,
10 | interval: 10000,
11 | duration: 1000
12 | })
13 | // 设置当前元素的数据,你也可以直接给data方法赋值一个banner数组,视图调用的时候就只需要调用$data字段就能渲染了
14 | //
15 | .data({
16 | banner: [
17 | 'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
18 | 'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
19 | 'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
20 | ], current: 1
21 | });
22 | $("#myCanvas").on("touchmove", function (e) {
23 | $(this).canvas(function () {
24 | this.setFillStyle('red')
25 | this.fillRect(e.touches[0].x, e.touches[0].y, 150, 75)
26 | });
27 | });
28 |
29 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
30 | $(function () {
31 | $(".banner_item").on('tap', function (e) {
32 | console.log(e);
33 | })
34 | //
35 | _swiper.on('change', function (e) {
36 | _swiper.data('current', e.detail.current + 1);
37 | }).on('touchstart', function (e) {
38 | let _this = $(this);
39 | _this.config('autoplay', false);
40 | _this.attr({ a: 12, d: 1231 });
41 | }).on('touchend', function (e) {
42 | $(this).config('autoplay', true);
43 | });
44 | $("#slide_to_first").on('tap', function () {
45 | Thenjs
46 | _swiper.config('current', 0);
47 | })
48 |
49 |
50 |
51 | $('page').bind('onCanvasMove', function (e) {
52 | console.log(e);
53 | });
54 |
55 | });
56 |
--------------------------------------------------------------------------------
/pages_bac/index/index.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | //获取应用实例
3 | var app = getApp();
4 | const ctx = wx.createCanvasContext('myCanvas');
5 | Page({
6 | data: {
7 | banner: {
8 | imgUrls: [
9 | 'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
10 | 'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
11 | 'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
12 | ],
13 | current: 0,
14 | indicatorDots: true,
15 | autoplay: false,
16 | interval: 5000,
17 | duration: 1000
18 | },
19 | classify: {
20 | imgUrls: [1,2,3],
21 | indicatorDots: true,
22 | autoplay: false,
23 | interval: 5000,
24 | duration: 1000
25 | }
26 | },
27 | onCanvasMove(e){
28 | console.log(e);
29 | ctx.setFillStyle('red');
30 | ctx.fillRect(e.touches[0].x, e.touches[0].y, 150, 75);
31 | ctx.draw();
32 | },
33 | onReady(){
34 |
35 | ctx.setFillStyle('red')
36 | ctx.fillRect(10, 10, 150, 75)
37 | ctx.draw()
38 | console.log(__wxRoute)
39 | },
40 | onChange(e){
41 | console.log(e);
42 | },
43 | pushSwiper(){
44 | this.data.banner.imgUrls.push(this.data.banner.imgUrls[0]);
45 | this.setData({
46 | 'banner.imgUrls': this.data.banner.imgUrls
47 | })
48 |
49 | },
50 | location(){
51 | this.setData({
52 | 'banner.current': 2
53 | })
54 | },
55 | onLoad: function () {
56 | console.log(__wxRoute)
57 | var that = this
58 | //调用应用实例的方法获取全局数据
59 | // app.getUserInfo(function (userInfo) {
60 | // //更新数据
61 | // that.setData({
62 | // userInfo: userInfo
63 | // })
64 | // })
65 | }
66 | })
67 |
--------------------------------------------------------------------------------
/pages_bac/index/index.wxss:
--------------------------------------------------------------------------------
1 | /**index.wxss**/
2 | @import "../../app.wxss";
3 | view{
4 | box-sizing: border-box;
5 | }
6 | .header_container {
7 | z-index: 9999;
8 | position: absolute;
9 | top: 0;
10 | left: 0;
11 | height: 40px;
12 | width: 100%;
13 | }
14 | .header_text{
15 | color: #fff;
16 | font-size: 12px;
17 | line-height: 25px;
18 | }
19 |
20 | .current_location {
21 | position: absolute;
22 | left: 10px;
23 | top: 7.5px;
24 | height: 25px;
25 | width: 25px;
26 | background: rgba(0, 0, 0, 0.5);
27 | border-radius: 12.5px;
28 | padding-left: 25px;
29 | }
30 | .current_location text{
31 | display: none;
32 | }
33 | .current_location.active{
34 | width: 100px;
35 | }
36 | .current_location.active text{
37 | display: inline-block;
38 | width: 100%;
39 | white-space: nowrap;
40 | text-overflow: ellipsis;
41 | overflow: hidden;
42 | }
43 | .current_location::before, .current_location::after {
44 | content: "";
45 | position: absolute;
46 | display: inline-block;
47 | border: 1px solid #fff;
48 | }
49 |
50 | .current_location::before {
51 | top: 4px;
52 | left: 6.3px;
53 | width: 12px;
54 | height: 12px;
55 | -webkit-transform: rotate(45deg);
56 | -moz-transform: rotate(45deg);
57 | -ms-transform: rotate(45deg);
58 | transform: rotate(45deg);
59 | border-radius: 50% 50% 0 50%;
60 | }
61 |
62 | .current_location::after {
63 | top: 8px;
64 | left: 10px;
65 | width: 4px;
66 | height: 4px;
67 | border: 1px solid #fff;
68 | border-radius: 50%;
69 | }
70 |
71 | .search_box{
72 | position: absolute;
73 | right: 10px;
74 | top: 7.5px;
75 | height: 25px;
76 | width: calc(100% - 125px - 20px);
77 | background: rgba(255,255,255, 0.9);
78 | border-radius: 12.5px;
79 | padding: 0 10px;
80 | color: #adadad;
81 | }
82 | .search_box input{
83 | height: 100%;
84 | }
85 | .banner_container{
86 | margin-top: -1rem;
87 | }
88 | .banner_item{
89 | background-size: cover;
90 | background-position: center;
91 | }
--------------------------------------------------------------------------------
/pages/request/request.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('request');
3 |
4 | let items = $.setData('items', []);
5 |
6 | const _page = $('page'), _add_comment = $("#add_comment"), _edit_first = $('#edit_first');
7 |
8 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
9 | $(function () {
10 |
11 | // Then.js的详细使用方法,请参考API文档:https://github.com/teambition/then.js/blob/master/README.md
12 | // 通过是用$.$when的each方法并行请求3组数据
13 | $.$when.each([1, 2, 3], function (cont, args) {
14 | // 使用complete保证then链的调用
15 | $.get('/posts/' + args).complete(function (res) {
16 | cont(null, res.data);
17 | })
18 | })
19 | // 异步成功返回调用的方法
20 | .then(function (cont, res) {
21 | items.set(res);
22 | })
23 | // 无论出错与否,总是会执行的方法,如果出现错误,result的结果数据将被忽略。
24 | .fin(function (cont, error, result) {
25 | console.log(error, result);
26 | cont();
27 | })
28 | // 最后的错误处理方法,所有的请求错误都将通过此方法或后续fail方法进行处理
29 | .fail(function (cont, error) {
30 | console.error(error);
31 | });
32 |
33 |
34 |
35 | // 页面初始化完成后,页面数据依然有效
36 | _page.on("load", function () {
37 | console.log(items.get());
38 | });
39 |
40 | // 简单数据提交
41 | _add_comment.on("tap", {
42 | title: 'foo',
43 | body: 'bar',
44 | userId: 1
45 | }, function (e) {
46 | $.showLoading("Submiting..");
47 | $.post('posts', e.$data).success(function (res) {
48 | $.hideLoading();
49 | items.append(res.data);
50 | })
51 | })
52 |
53 | _edit_first.on('tap', {
54 | id: 1,
55 | title: 'Edit - foo',
56 | body: 'Edit - bar',
57 | userId: 1
58 | }, function (e) {
59 | $.ajax({ url: '/posts/1', method: 'put', data: e.$data }).success(function (res) {
60 | console.log(res)
61 | items.set('[0]', res.data);
62 | })
63 | });
64 |
65 | $('#delete_comment').on("tap", function () {
66 | $.ajax('http://jsonplaceholder.typicode.com/posts/1', {
67 | method: 'DELETE'
68 | }).success(function (res) {
69 | items.remove(0);
70 | });
71 | })
72 |
73 |
74 | });
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/MinQuery/source/global/servers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('../utils/tools');
5 | const $pages = require('pages');
6 |
7 | // 全局数据配置,一般用于设置访问服务器地址等
8 | let serverHook = {
9 | __configurations__: {},
10 | // 设置
11 | set(key, value) {
12 | $tools.type(key) === 'number' && (key = key.toString());
13 | if ($tools.isPlainObject(key)) {
14 | $tools.extend(this.__configurations__, key);
15 | } else if ($tools.isString(key) && !$tools.isUndefined(value)) {
16 | this.__configurations__[key] = value;
17 | }
18 | },
19 | get(key, preset) {
20 | if ($tools.isString(key)) {
21 | return key in this.__configurations__ ? this.__configurations__[key] : preset ? (this.__configurations__[key] = preset) : undefined;
22 | } else {
23 | return preset;
24 | }
25 | }
26 | };
27 |
28 | // 设置公共的ajax请求服务器地址
29 | // 设置Socket服务器地址
30 | // 设置upLoadFile服务器地址
31 | // 设置downloadFile服务器地址
32 | // 设置imageServer图片服务器地址
33 | // 设置audioServer音频服务器地址
34 | // 设置videoServer视频服务器地址
35 | const _serverTypes = 'ajaxServer,socketServer,uploadServer,downloadServer,imageServer,imageLocal,audioServer,videoServer'.split(',');
36 | $tools.each(_serverTypes, function (i, k) {
37 | serverHook.set(k, '');
38 | });
39 |
40 | // 单个、批量设置服务器地址,或单个,全部服务器地址设置信息获取
41 | const configServers = function (serverName, serverAddress) {
42 | if ($tools.isPlainObject(serverName)) {
43 | $tools.each(serverName, function (sname, saddress) {
44 | if ($tools.isString(saddress)) {
45 | serverHook.set(sname, saddress);
46 | }
47 | })
48 | } else if ($tools.isString(serverName)) {
49 | if ($tools.isString(serverAddress)) {
50 | serverHook.set(serverName, serverAddress);
51 | } else {
52 | return serverHook.get(serverName);
53 | }
54 | }
55 | let _servers = {};
56 | // 获取所有可设置的服务器地址字段
57 | $tools.each(_serverTypes, function (i, st) {
58 | _servers[st] = serverHook.get(st);
59 | });
60 | // 更新所有已注册页面中的服务器地址设置,检测是否为更新服务项,否则将出现死循环调用,导致内存溢出。
61 | !!serverName && $tools.each($pages.get(), function (pname, pcontext) {
62 | pcontext.setData('$servers', _servers);
63 | })
64 | return _servers;
65 | };
66 |
67 | module.exports = {
68 | configServers,
69 | serverHook
70 | }
--------------------------------------------------------------------------------
/MinQuery/source/global/events.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('../utils/tools');
5 |
6 | const $events = {
7 | __events__: {},
8 | // 分离需要执行的和不被执行的
9 | classifyFilter(filter, _negative, _positive) {
10 | if (filter instanceof Array) {
11 | filter.forEach((f) => {
12 | f = Array.from(f);
13 | if (f[0] === "!") {
14 | f.shift();
15 | _negative[f.join("")] = f;
16 | } else {
17 | _positive[f.join("")] = f;
18 | }
19 | })
20 | }
21 | },
22 | register(pname, ename, method) {
23 | if (!pname) return;
24 | if (typeof ename === "string" && typeof method === 'function') {
25 | if (!(pname in this.__events__)) {
26 | this.__events__[pname] = {
27 | [ename]: method
28 | };
29 | } else {
30 | if (!(ename in this.__events__[pname])) {
31 | this.__events__[pname][ename] = method;
32 | } else {
33 | // 禁止在同一页面多次注册同一全局事件
34 | console.error(`Can not regiser a global event name in the same page again!PageName:[${pname}];EventName:[${ename}]`);
35 | }
36 | }
37 | }
38 | },
39 | // 触发器为全局触发,无筛选器,data为数组形式
40 | trigger(pname, ename, data) {
41 | if (!pname) return;
42 | for (let pg in this.__events__) {
43 | if (pg in this.__events__ && ename in this.__events__[pg]) {
44 | // 将来源作为第一个参数传入,其他附属参数紧跟其后
45 | this.__events__[pg][ename].apply(null,[pname].concat(data));
46 | }
47 | }
48 | },
49 | // filter arr: 关闭对应页面的当前事件['page1','page2'],关闭除了过滤页面以外所有页面的当前事件["!page1","!page2"]
50 | destroy(pname, ename, filter) {
51 | let _off = {}, _keep = {},pg;
52 | if ($tools.isArray(filter)){
53 | //删除筛选项内的对应事件
54 | this.classifyFilter(filter, _keep, _off);
55 | for (pg in this.__events__) {
56 | if (pg in _keep) continue;
57 | if (pg in _off && ename in this.__events__[pg]) {
58 | delete this.__events__[pg][ename];
59 | }
60 | }
61 | } else if ($tools.isString(filter) && filter == 'all'){
62 | //删除所有页面的事件
63 | for (pg in this.__events__) {
64 | delete this.__events__[pg][ename];
65 | }
66 | } else {
67 | //默认值删除当前页面的事件
68 | for (pg in this.__events__) {
69 | if (pg == pname) delete this.__events__[pg][ename];
70 | }
71 | }
72 | }
73 | };
74 | module.exports = $events;
--------------------------------------------------------------------------------
/pages/index/index.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('index');
3 |
4 | $(function(){
5 | // console.info($.getData('$servers'));
6 | $('.navigater').on('tap',function(e){
7 | console.log(e);
8 | let _url = e.data('url');
9 | console.info($.$servers());
10 | $.navigateTo(_url);
11 | })
12 | })
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | //获取应用实例
21 | // var app = getApp();
22 | // const ctx = wx.createCanvasContext('myCanvas');
23 | // Page({
24 | // data: {
25 | // banner: {
26 | // imgUrls: [
27 | // 'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg',
28 | // 'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg',
29 | // 'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'
30 | // ],
31 | // current: 0,
32 | // indicatorDots: true,
33 | // autoplay: false,
34 | // interval: 5000,
35 | // duration: 1000
36 | // },
37 | // classify: {
38 | // imgUrls: [1,2,3],
39 | // indicatorDots: true,
40 | // autoplay: false,
41 | // interval: 5000,
42 | // duration: 1000
43 | // }
44 | // },
45 | // onCanvasMove(e){
46 | // console.log(e);
47 | // ctx.setFillStyle('red');
48 | // ctx.fillRect(e.touches[0].x, e.touches[0].y, 150, 75);
49 | // ctx.draw();
50 | // },
51 | // onReady(){
52 |
53 | // ctx.setFillStyle('red')
54 | // ctx.fillRect(10, 10, 150, 75)
55 | // ctx.draw()
56 | // console.log(__wxRoute)
57 | // },
58 | // onChange(e){
59 | // console.log(e);
60 | // },
61 | // pushSwiper(){
62 | // this.data.banner.imgUrls.push(this.data.banner.imgUrls[0]);
63 | // this.setData({
64 | // 'banner.imgUrls': this.data.banner.imgUrls
65 | // })
66 |
67 | // },
68 | // location(){
69 | // this.setData({
70 | // 'banner.current': 2
71 | // })
72 | // },
73 | // onLoad: function () {
74 | // console.log(__wxRoute)
75 | // var that = this
76 | // //调用应用实例的方法获取全局数据
77 | // // app.getUserInfo(function (userInfo) {
78 | // // //更新数据
79 | // // that.setData({
80 | // // userInfo: userInfo
81 | // // })
82 | // // })
83 | // }
84 | // })
85 |
--------------------------------------------------------------------------------
/MinQuery/source/global/module.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/19.
3 | */
4 | let $tools = require('../utils/tools');
5 |
6 | //模块的存储变量
7 | let $moduleStore = [];
8 | /**
9 | * 定义一个模块
10 | * @param moduleName String 当前模块的内容
11 | * @param [moduleDependencies] Array 当前模块的依赖模块
12 | * @param [moduleMethod] Function 模块的方法
13 | * @param [execDirectly] Boolean 是否直接执行当前component的方法,并获取返回值
14 | */
15 | let defineModule = function (moduleName, moduleDependencies, moduleMethod, execDirectly) {
16 | if ($tools.isString(moduleName)) {
17 | if ($tools.isFunction(moduleDependencies)) {
18 | moduleMethod = moduleDependencies;
19 | moduleDependencies = [];
20 | }
21 | if (!$tools.isArray(moduleDependencies)) moduleDependencies = $tools.makeArray(moduleDependencies);
22 | if (moduleName in $moduleStore) {
23 | console.log(`You can't define a component named ${moduleName} twice,please check!`);
24 | } else {
25 | $moduleStore[moduleName] = {
26 | //模块名称
27 | name: moduleName,
28 | //模块方法,是否直接执行掉当前定义的模块
29 | method: !!execDirectly ? $tools.carry(null, moduleMethod) : moduleMethod,
30 | //模块依赖方法名称
31 | dependencies: moduleDependencies,
32 | //模块依赖方法返回数据,与名称一一对应,每次调用都会运行更新
33 | dependencies_transport: []
34 | }
35 | }
36 | }
37 | };
38 | /**
39 | * 模块调用
40 | * @param moduleName String 要调用的模块名称
41 | * @param componentParams
42 | */
43 | let callModule = function (moduleName, moduleParams) {
44 | if ($tools.isString(moduleName)) {
45 | moduleParams = $tools.slice.call(arguments, 1);
46 | if (moduleName in $moduleStore) {
47 | let _currentModule = $moduleStore[moduleName];
48 | $tools.each(_currentModule.dependencies, function (i, dependencyName) {
49 | if ($tools.trim(dependencyName) !== '') {
50 | _currentModule.dependencies_transport[i] = callModule(dependencyName);
51 | };
52 | });
53 | let params = [].concat(_currentModule.dependencies_transport, moduleParams);
54 | return $tools.isFunction(_currentModule.method) ? $tools.carry.apply(null, [null, _currentModule.method].concat(params)) : _currentModule.method;
55 | } else {
56 | console.error(`The [${moduleName}] module is not defined!`)
57 | }
58 | }
59 | }
60 |
61 | module.exports = {
62 | defineModule,
63 | callModule
64 | }
--------------------------------------------------------------------------------
/pages_bac/logs/logs.wxml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{index + 1}}. {{log}}
5 |
6 | 测试事件1
7 | 测试事件2
8 | 测试事件3{{userName}}
9 | 测试事件4
10 | 测试事件5
11 |
12 | 测试组-1
13 | 测试组-1
14 | 测试组-1
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/MinQuery/source/utils/styles.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('tools');
5 | let $path = require('path');
6 |
7 | //style转json
8 | const styleToJson = function (styleString) {
9 | let object = {};
10 | styleString = styleString.split(';');
11 | for (let i = 0; i < styleString.length; i++) {
12 | if (styleString[i].replace(/\s/g, "") !== "") {
13 | let temp = styleString[i].split(':');
14 | temp.length === 2 && (object[temp[0]] = temp[1]);
15 | }
16 | }
17 | return object;
18 | }
19 |
20 | //格式化style数据未字符串
21 | const jsonToStyle = function (styleJson, extraStyle) {
22 | if (extraStyle !== undefined) {
23 | typeof extraStyle == "string" && (extraStyle = styleToJson(extraStyle));
24 | for (let key in extraStyle) {
25 | // 合并两个style json数据
26 | styleJson[key] = extraStyle[key];
27 | }
28 | }
29 | let style = '', style_value, img_url;
30 | for (let key in styleJson) {
31 | style_value = styleJson[key], img_url = style_value.match(/url\(([^\s}]+)\)/);
32 | if ($tools.isArray(img_url)) {
33 | style_value = 'url(' + $path.autoMendServer(img_url[0], 'imageServer') + ")";
34 | }
35 | style += `${key}:${style_value};`;
36 | }
37 | return style;
38 | };
39 | //样式承接=>旨在更新原有样式,添加新的样式,而非删除原有添加新样式
40 | const styleExtend = function () {
41 | let args = arguments, first = arguments[0], len = arguments.length, i = 1;
42 | if (typeof first === "string") {
43 | first = styleToJson(first);
44 | }
45 | for (; i < len;) {
46 | first = jsonToStyle(first, args[i++]);
47 | }
48 | return first;
49 | }
50 |
51 | // 检查是否存在某个样式
52 | const hasClass = function (sourceClassStr, className) {
53 | if (typeof sourceClassStr === "string") {
54 | sourceClassStr = sourceClassStr.split(" ");
55 | return sourceClassStr.indexOf(className);
56 | } else if (sourceClassStr instanceof Array) {
57 | return sourceClassStr.indexOf(className);
58 | } else {
59 | return -1;
60 | }
61 | }
62 |
63 | // 添加样式
64 | const addClass = function (sourceClassStr, className) {
65 | if (typeof sourceClassStr === "string") {
66 | sourceClassStr = sourceClassStr.split(" ");
67 | sourceClassStr.push(className)
68 | return sourceClassStr.join(" ");
69 | }
70 | }
71 | //删除样式
72 | const removeClass = function (sourceClassStr, className) {
73 | if (typeof sourceClassStr === "string") {
74 | let cindex = hasClass(sourceClassStr, className);
75 | sourceClassStr = sourceClassStr.split(" ");
76 | cindex !== -1 && sourceClassStr.splice(cindex, 1);
77 | return sourceClassStr.join(" ");
78 | }
79 | }
80 |
81 | const styleController = {
82 | styleToJson: styleToJson,
83 | jsonToStyle: jsonToStyle,
84 | styleExtend: styleExtend,
85 | hasClass: hasClass,
86 | addClass: addClass,
87 | removeClass: removeClass
88 | };
89 |
90 | module.exports = {
91 | styleController
92 | };
--------------------------------------------------------------------------------
/MinQuery/source/utils/path.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('tools');
5 | let $global = require('../global/index');
6 |
7 | // 检查是否存在http或https或wss协议头
8 | const hasHttp_sPrefix = function (target) {
9 | if ($tools.isString(target)) {
10 | // 全路径文件匹配/^((http):\/\/[\w\/\.]*)?\w+\.{1}[a-z]+$/
11 | let _ishttp = /^(http):\/\/[\w\/\.]*?\w+/.test(target),
12 | _ishttps = /^(https):\/\/[\w\/\.]*?\w+/.test(target),
13 | _iswss = /^(wss):\/\/[\w\/\.]*?\w+/.test(target);
14 | if (_ishttp || _ishttps || _iswss) {
15 | return true;
16 | }
17 | } else return false;
18 | }
19 | // 允许可发直接数据页面的名称即可访问页面,而非输入全路径。
20 | /**
21 | * 允许你传入这样的页面路径:pageName, /pageName,./pagePath/to/pageName?q=1
22 | * 全路径不被处理:../pageName, ../path/pageName,../../path/pageName
23 | * @param url
24 | * @return {*}
25 | */
26 | const autoMendLocalPath = function (url) {
27 | if ($tools.isString(url)) {
28 | let _isFullPath = /^..\//.test(url), _needToFix = url[0] !== '!';
29 | //只对非全路径和需要进行补全的路径进行处理
30 | if (!_isFullPath && _needToFix) {
31 | let _hasSlash = url.indexOf('/') !== -1,
32 | _splitPath = url.split('/'),
33 | _pathLastSplit = _splitPath.pop().split('?'),
34 | _query = _pathLastSplit[1];
35 | //将最后一位的query字段进行抽离
36 | _splitPath.push(_pathLastSplit[0]);
37 | //去掉空路径和单点路径
38 | _splitPath.filter(function (pa, i) {
39 | return $tools.trim(pa) !== '' || $tools.trim(pa) !== '.';
40 | });
41 | //定位到同一主目录的页面
42 | if (_splitPath.length == 1) {
43 | url = '../' + _splitPath[0] + '/' + _splitPath[0] + (!!_query ? ('?' + _query) : '');
44 | } else {
45 | url = '../' + _splitPath.join('/') + (!!_query ? ('?' + _query) : '')
46 | }
47 | ;
48 | }
49 | // 如果不需要补全则删掉第一位的感叹号
50 | !_needToFix && (url = url.substr(1));
51 | }
52 | return url;
53 | };
54 |
55 | // 自动分析链接中是否存在http或https协议头开始的路径,如果存在则认为是全路径,直接返回;如果不存在,则根据需求添加本地设置的响应服务器路径。
56 | const autoMendServer = function (url, serverType) {
57 | let _server = $global.$servers.serverHook.get(serverType, '');
58 | if ($tools.isString(url)) {
59 | // 取消链接的补全
60 | let _needToFix = url[0] !== '!';
61 | // 如果不需要补全则删掉第一位的感叹号
62 | !_needToFix && (url = url.substr(1));
63 | if (_needToFix) {
64 | if (!hasHttp_sPrefix(url)) {
65 | if ($tools.trim(url) === '') {
66 | url = _server;
67 | } else {
68 | _server = Array.from(_server);
69 | url = Array.from(url);
70 | let _server_end_is_slash = _server[_server.length - 1] === '/';
71 | if (_server_end_is_slash) {
72 | url = url[0] !== '/' ? (_server.join('') + url.join('')) : (url.shift(), _server.join('') + url.join(''));
73 | } else {
74 | url = url[0] !== '/' ? (_server.join('') + '/' + url.join('')) : (_server.join('') + url.join(''));
75 | }
76 | }
77 | }
78 | }
79 | }
80 | return url;
81 | }
82 |
83 | module.exports = {
84 | autoMendServer,
85 | autoMendLocalPath
86 | }
--------------------------------------------------------------------------------
/pages_bac/test-1/test-1.js:
--------------------------------------------------------------------------------
1 | //logs.js
2 | // var util = require('../../utils/util.js')
3 | // Page({
4 | // data: {
5 | // logs: []
6 | // },
7 | // onLoad: function () {
8 | // console.log(__wxRoute)
9 | // this.setData({
10 | // logs: (wx.getStorageSync('logs') || []).map(function (log) {
11 | // return util.formatTime(new Date(log))
12 | // })
13 | // })
14 | // }
15 | // })
16 | var $ = wx.MinQuery.load("test-1",true);
17 |
18 | // 与设置一个userName的data值
19 | $.setData({ "userName": "test page one !" });
20 | $((_$) => {
21 | // 暂存查询实例
22 | var _page = $("page");
23 |
24 | // 创建自定义封装对象:如果传入一个非框架内默认识别的查询器名称,框架将直接使用这个名称在data根对象上创建MQ实例,让你可以对这个对象使用近乎所有的实例方法
25 | var _custom = $("customOne");
26 | _custom.on("updata",{name: "_custom",gender: 1},function(e) {
27 | // body...
28 |
29 | })
30 |
31 | // data-m-class选择器元素事件绑定
32 | $(".cone").on("tap", function (e) {
33 | console.log(e);
34 | _custom.stop();
35 | // _page.trigger("custom", "trigger data")
36 | ctx.setFillStyle('red')
37 | ctx.fillRect(18, 18, 150, 75)
38 | ctx.draw()
39 | })
40 |
41 |
42 | // var secondSelector = ;
43 | $(".ctwo").attr("name", "JasonDRZ");
44 | $(".ctwo").bind("tap", function (e) {
45 | $.setData({ "userName": "This is a test page one!" });
46 |
47 | $(this).toggleClass("active", "disable").delay(2000).cssAnimation("box-shadow: 0 0 10px #000;transform: scale(1.1);", 300).delay(3000).cssAnimation("border: 1px solid #444;background: #1f2a3d;", 800, ".17, .86, .73, .14").delay(4800).cssAnimation({
48 | "margin-top": "20px",
49 | "margin-bottom": "40px"
50 | }, 300)
51 | $(_page).data("name", "JasonDRZ&CSQ");
52 | $.$trigger("user-login","trigger form test-1");
53 | $.$off("user-login",['!logs'])
54 | return this.$selectorName;
55 | }).on("touchstart", function (e) {
56 | // console.log(e)
57 | })//.css("transition: all 3000ms cubic-bezier(.17, .86, .73, .14)");
58 | _page.on("ready", "ready to go", function (e) {
59 | console.info("Page ready event has a custom handler!", e)
60 | })
61 | _page.bind("custom", "ready to go", function (e) {
62 | console.info("Page ready event has a custom handler!", e)
63 | })
64 | _page.on("ready", "ready to go", function (e) {
65 | console.info("Page ready event has a custom handler!", e)
66 | _custom.animation(function () {
67 | console.log(this)
68 | this.translate(100, 100).rotate(45)
69 | }, 3000, "ease").delay(3000).animation(function () {
70 | this.translate(30).rotate(0, -45)
71 | }, 5000, "linner")
72 | })
73 | _page.on("load", { name: "pageLoader" }, function (op) {
74 | console.info("Page load event has a custom handler!", op);
75 | }).on("unload",function(){
76 | console.info("我退出啦!!")
77 | })
78 | })
79 | // $(".name,#elements").trigger("load",true,function(res){
80 | // console.info(res)
81 | // });
--------------------------------------------------------------------------------
/pages/form/form.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('form');
3 |
4 | let author = $.setData('author', "JasonDRZ");//与使用当个兑现字段的方法相同 $.setData({'author':"JasonDRZ"});
5 | let info = $.setData({
6 | 'gander': 'Male',
7 | 'work': 'WEB Front-End'
8 | })
9 | let items = $.setData('items', [1, 2, 3, 4]);
10 |
11 | let _multi_level = $.setData('multis', { info: { hobbies: ['Football', 'PingPang', 'Basketball'] } });
12 | let _multi_level_2 = $.setData('multis_2', [{ info_1: { hobbies: ['Football', 'PingPang', 'Basketball'] } }, { info_2: { hobbies: ['Football', 'PingPang', 'Basketball'] } }]);
13 |
14 | const _page = $('page');
15 |
16 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
17 | $(function () {
18 | // 单个数据设置字段进行更新
19 | _page.bind('changeAuther', function () {
20 | author.set('I am JasonD');
21 | })
22 | // 获取数据接口,支持dot分隔符查询形式,如:$.getData('info.user.name');$.getData('info.user.hobbies[0]');
23 | $("#get_author").on("tap", function () {
24 | $(this).text("我的爱好:");
25 | $.setData('author_hobby', _multi_level.get('info.hobbies[2]'));
26 |
27 | // 通过以下两种方式去设置和获取相应的数据
28 | // $.setData('multis_2[0].info_1.hobbies[0]',"Movies");
29 | _multi_level_2.set('[0].info_1.hobbies[0]', "Movies");
30 |
31 | // console.log($.getData('multis_2[0].info_1.hobbies[0]'));
32 | console.log(_multi_level_2.get('[0].info_1.hobbies[0]'));
33 | })
34 | // 多个设置字段进行数据更新
35 | $("#change_info").on('tap', function () {
36 | console.log(info.get('gander'));
37 |
38 | info.gander.set("I'm still a man!");
39 | info.set('gander', "No Woman");
40 | info.work.set('Working on WEB Front-End!');
41 | });
42 | $("#delete_info").on('tap', function () {
43 | // 默认设置为null
44 | author.clear();
45 | // 自定义清除值为空
46 | info.clear('');
47 | })
48 | // 向上添加
49 | $("#prepend").on('tap', function () {
50 | // 支持数组形式批量添加,请设置第二个参数为true
51 | console.info(items.prepend("prepend"));
52 | });
53 | // 向下添加
54 | $('#append').on('tap', function () {
55 | // 支持数组形式批量添加,请设置第二个参数为true
56 | console.log(items.append('append'));
57 | $('page').trigger('customEvent');
58 | })
59 |
60 | });
61 |
62 | // 向上添加
63 | $("#prepend").on('tap', function () {
64 | // 支持数组形式批量添加,请设置第二个参数为true
65 | console.info(items.prepend("prepend"));
66 | });
67 | // 向下添加
68 | $('#append').on('tap', function () {
69 | // 支持数组形式批量添加,请设置第二个参数为true
70 | console.log(items.append('append'));
71 | $('page').trigger('customEvent');
72 | })
73 |
74 | $('page').bind("customEvent", function () {
75 | console.info('customEvent triggered!!');
76 | }).on('load', function () {
77 | console.timeEnd('MinQuery');
78 | }).on('show', function () {
79 | console.timeEnd('MinQuery');
80 | })
81 |
82 | // 插入
83 | // 插入的index从0开始
84 | let b_t = 1, a_t = 1;
85 | $('#before').on('tap', function () {
86 | // 通过给before设置第三个参数为true,标示传入的数组是继承到源数据中的,而非插入数组作为一个数据。
87 | console.info(items.before(1, ['insert before!' + (b_t++), 'insert before!' + (b_t++)], true));
88 | });
89 | $('#after').on('tap', function () {
90 | // 未设置滴三个参数,则是插入一个数组元素,而非继承到源数据上
91 | console.info(items.after(1, ['insert after' + (a_t++), 'insert after' + (a_t++)]));
92 | });
93 | $("#delete").on("tap", function () {
94 | // 删除某个项
95 | items.remove(1);
96 | });
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/pages_bac/scan_store/scan_store.js:
--------------------------------------------------------------------------------
1 | // pages/scan_store/scan_store.js
2 | var app = getApp();
3 | var pageConfig = {};
4 | // console.log(app);
5 | var $ = wx.MinQuery.load("scan_store");
6 | // var m = require("../..//index");
7 | // console.log(m);
8 | // console.log(m.inArray)
9 | // var $ = app.minquery;
10 | // console.log($)
11 | $(function () {
12 | $.setData({
13 | switcher: {
14 | header: { comment: "", history: "active" }
15 | },
16 | monkeys: [{
17 | id: "0",
18 | propertys: {
19 | name: "JasonD",
20 | gender: "male"
21 | }
22 | }, {
23 | id: "1",
24 | propertys: {
25 | name: "JasonDR",
26 | gender: "female"
27 | }
28 | }, {
29 | id: "2",
30 | propertys: {
31 | name: "JasonDZ",
32 | gender: "male"
33 | }
34 | }],
35 | storageTest: wx.getStorageSync('monkey')
36 | });
37 |
38 | // 根数据选择器
39 | // $("@switcher").key("header").key("comment").value("active").end();
40 | // $("@switcher").find("id=12");
41 | // $("@switcher").find(function (e, i) { return e.id == '0'}).key("event").value([1,3,3]);
42 |
43 |
44 | $("page").on("load", function (options) {
45 | console.log(__wxRoute)
46 | console.log("onLoad 事件加载完成");
47 | // $("$tab_header").data([{'id': "123",'property': { 'monkey': "Jason" } }, { '2': { 'monkey': "Juny" } }], true);
48 | console.log($.getData("monkeys"));
49 | wx.setStorageSync('monkey', "我嗯是的沙发上的酸辣粉见识到了房间撒的发生了")
50 | }).on("ready", function () {
51 | console.log(this);
52 | }).on("show", function () {
53 | wx.showToast({
54 | title: "显示",
55 | icon: 'success',
56 | duration: 2000
57 | });
58 | }).on("hide", function () {
59 | wx.showToast({
60 | title: "隐藏",
61 | icon: 'success',
62 | duration: 2000
63 | });
64 | })
65 | .bind("tapSwitcher", function (e) {
66 | console.log(e.target.id)
67 | }).bind("formSubmit", function (e) {
68 | console.log(e)
69 | }).bind("formReset", function (e) {
70 | console.log(e)
71 | }).bind("gotolog", function () {
72 | wx.navigateTo({
73 | url: '../logs/logs'
74 | })
75 | });
76 |
77 |
78 | $(".monkey").on("tap", function (e) {
79 | this.children().all().css("color", "#000");
80 | this.children().current().css("color", "red");
81 | console.log(e.attr("id"))
82 | });
83 | $(".o_list").on("tap", function (e) {
84 | console.log("Scope Taped")
85 | this.children().current().css("color", "red");
86 | this.children().current().toggleClass("borderText");
87 | this.children().filter("16").addClass("borderText");
88 | });
89 | $(".tab_header").on("tap", function (e) {
90 | console.log(this.children().current().hasClass("active"))
91 | this.children().all().removeClass("active");
92 | this.children().current().addClass("active");
93 | })//.children(()=>{
94 | //return ["history", "comment"];
95 | // }).filter(0).addClass("active").end()
96 | // .on("longtap", function (e) {
97 | // console.log(e);
98 | // });
99 | $(".tab_header_box").catch("tap", function (e) {
100 | console.log(this);
101 | console.log(e)
102 | console.log($("window"))
103 | })
104 | })
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/pages_bac/scan_store/scan_store.wxml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | 您去过的店铺{{$Data.switcherHeader_2.monkey.a}}{{$Window.width}}
10 |
11 | {{storageTest}}
12 |
13 | 您评论过的店铺{{newData}}
14 |
15 |
22 |
23 | 我是一只名叫{{item.propertys.name}}的{{item.propertys.gender}}猴子!
24 |
25 |
61 |
62 |
63 |
64 |
65 |
66 | 扫码
67 |
--------------------------------------------------------------------------------
/pages/dataset/dataset.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('dataset');
3 |
4 | let author = $.setData('author', "JasonDRZ");//与使用当个兑现字段的方法相同 $.setData({'author':"JasonDRZ"});
5 | let info = $.setData({
6 | 'gander': 'Male',
7 | 'work': 'WEB Front-End'
8 | })
9 | let items = $.setData('items', [1, 2, 3, 4]);
10 |
11 | let _multi_level = $.setData('multis', { info: { hobbies: ['Football', 'PingPang', 'Basketball'] } });
12 | let _multi_level_2 = $.setData('multis_2', [{ info_1: { hobbies: ['Football', 'PingPang', 'Basketball'] } }, { info_2: { hobbies: ['Football', 'PingPang', 'Basketball'] } }]);
13 |
14 | // 数据监听,全路径精确监听,只有当修改数据的键完全等于监听字段时,才会触发
15 | $.watch('items',function(newV,oldV,path){
16 | console.log(newV,oldV,path);
17 | })
18 |
19 | // 模糊数据监听,只要存在类似字段被修改,则触发。
20 | $.watch('hobbies',function(newV,oldV,path){
21 | console.log(newV,oldV,path);
22 | console.log($.getData(path));
23 | },true)
24 |
25 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
26 | $(function () {
27 | console.info('复杂执行逻辑请一定使用此主运行方法来执行Page对象的自定义事件、数据绑定操作,确保自定义事件和数据的正确注入');
28 |
29 | // 单个数据设置字段进行更新
30 | $("#change_author").on('tap', function (e) {
31 | author.set('I am JasonD');
32 | console.log(e);
33 | })
34 |
35 | // 获取数据接口,支持dot分隔符查询形式,如:$.getData('info.user.name');$.getData('info.user.hobbies[0]');
36 | $("#get_author").on("tap", function () {
37 | $(this).text("我的爱好:");
38 | $.setData('author_hobby', _multi_level.get('info.hobbies[2]'));
39 |
40 | // 通过以下两种方式去设置和获取相应的数据
41 | // $.setData('multis_2[0].info_1.hobbies[0]',"Movies");
42 | _multi_level_2.set('[0].info_1.hobbies[0]', "Movies");
43 |
44 | // console.log($.getData('multis_2[0].info_1.hobbies[0]'));
45 | console.log(_multi_level_2.get('[0].info_1.hobbies[0]'));
46 | })
47 |
48 | // 多个设置字段进行数据更新
49 | $("#change_info").on('tap', function () {
50 | console.log(info.get('gander'));
51 |
52 | info.gander.set("I'm still a man!");
53 | info.set('gander', "No Woman");
54 | info.work.set('Working on WEB Front-End!');
55 | });
56 |
57 | $("#delete_info").on('tap', function () {
58 | // 默认设置为null
59 | author.clear();
60 | // 自定义清除值为空
61 | info.clear('');
62 | })
63 |
64 | // 向上添加
65 | $("#prepend").on('tap', function () {
66 | // 支持数组形式批量添加,请设置第二个参数为true
67 | console.info(items.prepend("prepend"));
68 | });
69 |
70 | // 向下添加
71 | $('#append').on('tap', function () {
72 | // 支持数组形式批量添加,请设置第二个参数为true
73 | console.log(items.append('append'));
74 | $('page').trigger('customEvent');
75 | });
76 |
77 | // 向上添加
78 | $("#prepend").on('tap', function () {
79 | // 支持数组形式批量添加,请设置第二个参数为true
80 | console.info(items.prepend("prepend"));
81 | });
82 |
83 | // 向下添加
84 | $('#append').on('tap', function () {
85 | // 支持数组形式批量添加,请设置第二个参数为true
86 | console.log(items.append('append'));
87 | })
88 |
89 | // 插入
90 | // 插入的index从0开始
91 | let b_t = 1, a_t = 1;
92 | $('#before').on('tap', function () {
93 | // 通过给before设置第三个参数为true,标示传入的数组是继承到源数据中的,而非插入数组作为一个数据。
94 | console.info(items.before(1, ['insert before!' + (b_t++), 'insert before!' + (b_t++)], true));
95 | });
96 |
97 | $('#after').on('tap', function () {
98 | // 未设置滴三个参数,则是插入一个数组元素,而非继承到源数据上
99 | console.info(items.after(1, ['insert after' + (a_t++), 'insert after' + (a_t++)]));
100 | });
101 |
102 | $("#delete").on("tap", function () {
103 | // 删除某个项
104 | items.remove(1);
105 | });
106 |
107 | });
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/pages/simple_app/simple_app.js:
--------------------------------------------------------------------------------
1 | //index.js
2 | let $ = wx.MinQuery('simple_app');
3 |
4 | let author = $.setData('author', "JasonDRZ");//与使用当个兑现字段的方法相同 $.setData({'author':"JasonDRZ"});
5 | let info = $.setData({
6 | 'gander': 'Male',
7 | 'work': 'WEB Front-End'
8 | })
9 | let items = $.setData('items', [1, 2, 3, 4]);
10 |
11 | let _multi_level = $.setData('multis', { info: { hobbies: ['Football', 'PingPang', 'Basketball'] } });
12 | let _multi_level_2 = $.setData('multis_2', [{ info_1: { hobbies: ['Football', 'PingPang', 'Basketball'] } }, { info_2: { hobbies: ['Football', 'PingPang', 'Basketball'] } }]);
13 |
14 | const _page = $('page');
15 |
16 | // 主函数必须运行,但元素的事件绑定及数据操作并不依赖于主函数执行。
17 | $(function () {
18 | console.info('复杂执行逻辑请一定使用此主运行方法来执行Page对象的自定义事件、数据绑定操作,确保自定义事件和数据的正确注入');
19 |
20 | $.get('https://jsonplaceholder.typicode.com/posts/1').success(function(re){
21 | console.info(re);
22 | }).fail(function(er){
23 | console.error(er);
24 | })
25 |
26 | // 单个数据设置字段进行更新
27 | _page.bind('changeAuther', function () {
28 | author.set('I am JasonD');
29 | })
30 | // 获取数据接口,支持dot分隔符查询形式,如:$.getData('info.user.name');$.getData('info.user.hobbies[0]');
31 | $("#get_author").on("tap", function () {
32 | $(this).text("我的爱好:");
33 | $.setData('author_hobby', _multi_level.get('info.hobbies[2]'));
34 |
35 | // 通过以下两种方式去设置和获取相应的数据
36 | // $.setData('multis_2[0].info_1.hobbies[0]',"Movies");
37 | _multi_level_2.set('[0].info_1.hobbies[0]', "Movies");
38 |
39 | // console.log($.getData('multis_2[0].info_1.hobbies[0]'));
40 | console.log(_multi_level_2.get('[0].info_1.hobbies[0]'));
41 | })
42 | // 多个设置字段进行数据更新
43 | $("#change_info").on('tap', function () {
44 | console.log(info.get('gander'));
45 |
46 | info.gander.set("I'm still a man!");
47 | info.set('gander', "No Woman");
48 | info.work.set('Working on WEB Front-End!');
49 | });
50 | $("#delete_info").on('tap', function () {
51 | // 默认设置为null
52 | author.clear();
53 | // 自定义清除值为空
54 | info.clear('');
55 | })
56 | // 向上添加
57 | $("#prepend").on('tap', function () {
58 | // 支持数组形式批量添加,请设置第二个参数为true
59 | console.info(items.prepend("prepend"));
60 | });
61 | // 向下添加
62 | $('#append').on('tap', function () {
63 | // 支持数组形式批量添加,请设置第二个参数为true
64 | console.log(items.append('append'));
65 | $('page').trigger('customEvent');
66 | })
67 |
68 | });
69 |
70 | // 向上添加
71 | $("#prepend").on('tap', function () {
72 | // 支持数组形式批量添加,请设置第二个参数为true
73 | console.info(items.prepend("prepend"));
74 | });
75 | // 向下添加
76 | $('#append').on('tap', function () {
77 | // 支持数组形式批量添加,请设置第二个参数为true
78 | console.log(items.append('append'));
79 | $('page').trigger('customEvent');
80 | })
81 |
82 | $('page').bind("customEvent", function () {
83 | console.info('customEvent triggered!!');
84 | }).on('load', function () {
85 | console.timeEnd('MinQuery');
86 | }).on('show', function () {
87 | console.timeEnd('MinQuery');
88 | })
89 |
90 | // 插入
91 | // 插入的index从0开始
92 | let b_t = 1, a_t = 1;
93 | $('#before').on('tap', function () {
94 | // 通过给before设置第三个参数为true,标示传入的数组是继承到源数据中的,而非插入数组作为一个数据。
95 | console.info(items.before(1, ['insert before!' + (b_t++), 'insert before!' + (b_t++)], true));
96 | });
97 | $('#after').on('tap', function () {
98 | // 未设置滴三个参数,则是插入一个数组元素,而非继承到源数据上
99 | console.info(items.after(1, ['insert after' + (a_t++), 'insert after' + (a_t++)]));
100 | });
101 | $("#delete").on("tap", function () {
102 | // 删除某个项
103 | items.remove(1);
104 | });
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | //app.js
2 | // var loadPlugin = require("../../plugins/loader").load;
3 | // var $ = require("MinQuery.1.0.2.min").load("app");
4 | require("MinQuery/index");
5 | wx.MinQuery.debug(true,function(errors){
6 | console.log(errors);
7 | });
8 |
9 | let $ = wx.MinQuery("app");
10 |
11 | $(()=>{
12 | // 设置ajax请求服务器
13 | $.$servers('ajaxServer','https://jsonplaceholder.typicode.com/');
14 | var app = $("app");
15 | var globalData = $.setData('globalData',{});
16 | var arrayData = $.setData("items",[['inner1']]);
17 | app.on('launch',function(e){
18 | // 这里的scene字段做了调整,新的scene字段是一个类型数组,第一个元素为进入场景类型编码,第二个字段是场景类型的官方描述。
19 | // 这样的方式方便开发过程中进行有效的验证和描述查看,不需要每次都查看开发文档进行一一对照。
20 | console.info("App has onLaunched!!!!!!!!!!!!!!!",e)
21 | })
22 |
23 | .bind('userLogin',function(cb){
24 | console.log(cb);
25 | $.$call(cb.call,"尼玛,传过来了!!")
26 | $.showLoading('登录中。。。。');
27 | $.hideLoading(3000);
28 | }).data("userInfo","用户信息!!!");
29 |
30 | $.$on('getUserInfo',function(cb){
31 | var userInfo = globalData.get('userInfo');
32 | if(!!userInfo){
33 | typeof cb == "function" && $.$call(cb,userInfo);
34 | }else{
35 | //调用登录接口
36 | wx.login({
37 | success: function () {
38 | wx.getUserInfo({
39 | success: function (res) {
40 | globalData.set('userInfo',res.userInfo);
41 | typeof cb == "function" && $.$call(cb,res.userInfo);
42 | }
43 | })
44 | }
45 | })
46 | }
47 | })
48 | })
49 |
50 | // ,
51 | // "pages/dataset/dataset",
52 | // "pages/pageevent/pageevent",
53 | // "pages/request/request",
54 | // "pages/form/form",
55 | // "pages/components/components",
56 | // "pages/simple_app/simple_app",
57 | // "pages/elements/elements"
58 |
59 | // })
60 |
61 |
62 | // App({
63 | // minquery: $,
64 | // // loadPlugin: loadPlugin,
65 | // onLaunch: function () {
66 | // console.info("App has onLaunched!!!!!!!!!!!!!!!")
67 | // //调用API从本地缓存中获取数据
68 | // var logs = wx.getStorageSync('logs') || []
69 | // logs.unshift(Date.now())
70 | // wx.setStorageSync('logs', logs)
71 | // },
72 | // getUserInfo:function(cb){
73 | // var that = this
74 | // if(this.globalData.userInfo){
75 | // typeof cb == "function" && cb(this.globalData.userInfo)
76 | // }else{
77 | // //调用登录接口
78 | // wx.login({
79 | // success: function () {
80 | // wx.getUserInfo({
81 | // success: function (res) {
82 | // that._userInfo = res.userInfo;
83 | // that.globalData.userInfo = res.userInfo
84 | // console.log(res.userInfo)
85 | // typeof cb == "function" && cb(that.globalData.userInfo)
86 | // }
87 | // })
88 | // }
89 | // })
90 | // }
91 | // },
92 | // globalData:{
93 | // userInfo:null
94 | // }
95 | // })
96 |
97 | var tabbar = {
98 | "tabBar": {
99 | "list": [{
100 | "pagePath": "pages/scan_store/scan_store",
101 | "text": "首页",
102 | "iconPath": "images/Grid.png",
103 | "selectedIconPath": "images/Grid.png"
104 | },{
105 | "pagePath": "pages/index/index",
106 | "text": "进店",
107 | "iconPath": "images/Camera.png",
108 | "selectedIconPath": "images/Camera.png"
109 | },{
110 | "pagePath": "pages/index/index",
111 | "text": "我的",
112 | "iconPath": "images/User.png",
113 | "selectedIconPath": "images/User.png"
114 | }]
115 | }
116 | }
--------------------------------------------------------------------------------
/MinQuery/source/config/mq_config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | const $_config = {
5 | //当前框架版本配置
6 | version: '1.2.1',
7 | //服务器类型配置
8 | serverSetting: 'ajaxServer,socketServer,uploadServer,downloadServer,imageServer,imageLocal,audioServer,videoServer'.split(','),
9 | //页面事件配置
10 | pageEvents: "onLoad,onReady,onShow,onHide,onUnload,onPullDownRefresh,onReachBottom,onShareAppMessage".split(","),
11 | //app事件配置
12 | appEvents: "onLaunch,onShow,onError,onHide".split(","),
13 | //元素占用字段解释
14 | // MinQuery固有Data和Page事件属性标识
15 | inherentStaticKeys: {
16 | "$id": ["$id", "To store element,which selected by id!"],
17 | "$cs": ["$cs", "To store element,which selected by data-min-class!"],
18 | "$window": ["$window", "To store system information."],
19 | "$data": ["$data", "To store custom isolate data!"],
20 | "$servers": ["$servers", "To store global server configuration!"],
21 | // 固有事件处理函数标识
22 | "$bind": ["$bind", "A unified bind[event] handler."],
23 | "$catch": ["$catch", "A unified catch[event] handler."],
24 | // 元素固有操作属性标识
25 | "$class": ["$class", "To manage the element class string! Access method: $id/$cs.elementID/mClass.$class"],
26 | "$hoverClass": ["$hoverClass", "To manage the element hover-class string! Access method: $id/$cs.elementID/mClass.$hoverClass"],
27 | "$attr": ["$attr", "To manage the element multiple attributes value! Access method: $id/$cs.elementID/mClass.$attr.disabled;"],
28 | "$cf": ["$cf", "To manage the Min App View Plugin's configuration! Access method: $id/$cs.elementID/mClass.$attr.disabled;"],
29 | "$style": ["$style", "To manage the element style string! Access method: $id/$cs.elementID/mClass.$style;"],
30 | "$cssAnimation": ["$cssAnimation", "To manage the element css animation string! Access method: $id/$cs.elementID/mClass.$cssAnimation;"],
31 | "$data": ["$data", "To manage the element multiple custom data object! Access method: $id/$cs.elementID/mClass.$data.imageSrc;"],
32 | "$children": ["$children", "To mark children elements,which are wrapped by this element! Not recommend to access!"],
33 | "$list": ["$list", "To manage list elements. Access method: $id/$cs.elementID/mClass.$list[listTag].$class;"],
34 | "$animation": ["$animation", "To manage the element animation object!Access method: $id/$cs.elementID/mClass.$animation;"],
35 | "$text": ["$text", "To manage the element text string! Access method: $id/$cs.elementID/mClass.$text"],
36 | "$events": ["$events", "To manage the element events bank route! Not recommend to access!"],
37 | "$selectorType": "To cache the element selector type!",
38 | "$selectorName": "To cache the element selector name!"
39 | },
40 | //选择器配置
41 | selectorsBank: {
42 | // 挂载到data对象上的固有属性选择器
43 | // [selector,hasEvent,eventsString[Separated by commas!]]
44 | "#": ["$id", true, "all"],
45 | ".": ["$cs", true, "all"],
46 | "*": ["$all", true, "all"],
47 | "window": ["$window", false],
48 | "data": ["$data", true, "change"],
49 | // 获取当前页面实例对象
50 | "page": ["$page", true, "load,ready,show,hide,unload,pulldownrefresh,reachbottom,shareappmessage"],
51 | // 获取App初始化数据
52 | "app": ["$app", true, "launch,show,error,hide"]
53 | },
54 | // 元素固有操作属性初始化
55 | getElementInitialData() {
56 | // 使用函数进行对象返回,防止页面之间的对象污染
57 | return {
58 | "$selectorType": "",
59 | "$selectorName": "",
60 | "$class": "",
61 | "$hoverClass": "",
62 | "$attr": {},
63 | "$cf": {},
64 | "$style": "",
65 | "$list": {},
66 | "$data": {},
67 | "$children": [],
68 | "$cssAnimation": "",
69 | "$animation": undefined,
70 | "$events": {
71 | // "bind": {
72 | // "tap": ["$id.element", "bind.tap"]
73 | // },
74 | // "catch": {
75 | // "tap": ["$id.element", "catch.tap"]
76 | // }
77 | }
78 | }
79 | }
80 | };
81 |
82 | module.exports = $_config;
--------------------------------------------------------------------------------
/MinQuery/source/wx/methods.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | const $tools = require('../utils/index');
5 | const wx_config = require('../config/wx_config');
6 |
7 | //微信接口封装访问器
8 | /** 此接口用于访问未支持的wx接口,提供二次封装,并支持链式调用方式。
9 | * 调用方法-分类回调形式:
10 | * 常规配置方法: MinQuery.wxMethod('wxMethodName',{config: value,success(re){},fail(err){}});
11 | * Thenjs方法:
12 | * MinQuery.wxMethod('wxMethodName',{config:value})
13 | * .then((cont,res)=>{cont()})
14 | * .fail((cont,err)=>{cont()})
15 | * .fin((cont,err,res)=>{cont(err)});
16 | * 单回调形式: MinQuery.wxMethod(wxMethodName,function(re){});
17 | * 单一参数型: MinQuery.wxMethod(wxMethodName,paramValue);
18 | */
19 | //将所有微信接口变为then链式调用形式
20 | let _wxMethodsThenTransformer = function (methodName, _options, wrapperCall, context) {
21 | // 检测并设置wx对象上下文
22 | !context && (context = wx);
23 | // 检测调用方法名称及是否存在
24 | let options = !_options ? {} : _options;
25 | if (typeof methodName == 'string' && methodName in context) {
26 | return $tools.when(function (cont) {
27 | let mannuComp = options.complete;
28 | // 仅在参数集为Object的情况下进行回调封装继承
29 | $tools.isPlainObject(options) && $tools.extend(options, {
30 | complete(e) {
31 | if ($tools.isFunction(mannuComp)) mannuComp(e);
32 | // 支持Then.js的链式反应链
33 | if (methodName == 'request' && e.statusCode === 200) {
34 | cont(null,e);
35 | } else {
36 | let _msg = e.errMsg.split(":");
37 | if (_msg[1] === "ok") {
38 | cont(null,e);
39 | } else {
40 | cont(e);
41 | }
42 | }
43 | }
44 | });
45 | //执行方法
46 | $tools.isFunction(wrapperCall)
47 | ? $tools.carry(null, wrapperCall, context[methodName], options)
48 | : $tools.isArray(options) ? context[methodName].apply(null, options) : context[methodName].call(null, options);
49 | })
50 | } else {
51 | //微信版本提示
52 | wx.showModal({
53 | title: '提示',
54 | content: `当前微信版本过低,无法使用[${methodName}]功能,请升级到最新微信版本后重试。`
55 | })
56 | console.error(`Do not have method [${methodName}] on context:`, context);
57 | }
58 | }
59 | //封装已配置的wx接口
60 | let wxMethodsPackages = {};
61 | $tools.each(wx_config.methodsParams, function (i, _oj) {
62 | if (_oj.name && _oj.name in wx) {
63 | wxMethodsPackages[_oj.name] = (function (_inob) {
64 | let _param_def = _inob['param_def'], _param_nor = _inob['param_nor'], _param_all;
65 | if ($tools.isArray(_param_def)) {
66 | _param_all = $tools.isArray(_param_nor) ? _param_def.concat(_param_nor) : _param_def;
67 | } else _param_all = null;
68 | return function (a) {
69 | // 返回的封装函数
70 | let args = $tools.slice.call(arguments), _has_config = $tools.isArray(_param_all), _type = 'string',
71 | _type_matches = [], _preset = '', _cur_param, _first = args[0], options = {};
72 | // 如果存在配置,则表明此项一定是异步回调形式,则进行预设参数进行继承
73 | if (_has_config) {
74 | // 优先进行配置项预设
75 | $tools.each(_param_all, function (_i, dar) {
76 | _preset = dar[2];
77 | // 仅设置有预制项的字段
78 | if (!$tools.isUndefined(_preset)) options[dar[0]] = _preset;
79 | });
80 | if ($tools.isPlainObject(_first)) {
81 | $tools.extend(options, _first);
82 | } else $tools.each(args, function (_i, ar) {
83 | _type_matches = [];
84 | _cur_param = _param_all[_i];
85 | // 存在配置预设项则进行验证,不存在,则忽略此字段
86 | if (!!_cur_param && !$tools.isUndefined(ar)) {
87 | _type = !!_cur_param[1] ? _cur_param[1] : 'string';
88 | _type = _type.split("|");
89 | // 判断是否符合多个类型中的某一个类型
90 | $tools.each(_type, function (_, t) {
91 | if ($tools.type(ar) === t) {
92 | //匹配到一个则中断
93 | _type_matches = [];
94 | return false;
95 | } else {
96 | _type_matches.push(t);
97 | }
98 | })
99 | if (_type_matches.length == 0) {
100 | options[_cur_param[0]] = ar;
101 | } else {
102 | console.error(`${_inob.name} method's param ${_cur_param[0]} should be ${_type_matches.join(' or ')}!`)
103 | }
104 | } else return false;
105 | });
106 | } else {
107 | options = args;
108 | }
109 | return _wxMethodsThenTransformer(_inob.name, options, _inob['agent_call']);
110 | }
111 | })(_oj);
112 | }
113 | });
114 |
115 | module.exports ={
116 | _wxMethodsThenTransformer,
117 | wxMethodsPackages
118 | }
--------------------------------------------------------------------------------
/MinQuery/source/utils/dataEngine.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/19.
3 | */
4 | let $tools = require('tools');
5 | //数据处理引擎
6 | // 支持对象设置及单数据键值设置的数据查询引擎
7 | let dataEngine = function (sourceData, keyString, keyValue) {
8 | // 如果传入的是data 查询的 key 并且使用call方法调用
9 | if ($tools.isString(sourceData)) {
10 | sourceData = this[sourceData];
11 | }
12 | if (sourceData) {
13 |
14 | // 如果不存在则返回数据源
15 | if (!keyString) {
16 | return sourceData;
17 | }
18 | // 是否获取指定键值
19 | let dataRequire = false, obj = {};
20 | if ($tools.isString(keyString) && $tools.isUndefined(keyValue)) {
21 | dataRequire = true;
22 | obj[keyString] = {};
23 | }
24 | // 如果关闭获取指定键值下,keyString不是数据对象时,则报错
25 | if ((!dataRequire && $tools.isUndefined(keyValue) && !$tools.isPlainObject(keyString)) || (!$tools.isUndefined(keyValue) && !$tools.isString(keyString))) {
26 | console.error(`AnalysisDataEngine params error!`, keyString, keyValue);
27 | return sourceData;
28 | }
29 | // 复制object
30 | if (!dataRequire) {
31 | if ($tools.isPlainObject(keyString)) {
32 | obj = keyString;
33 | } else
34 | obj[keyString] = keyValue;
35 | }
36 | // dataRequire模式,不存在则返回false,并终止;
37 | // 非dataRequire模式,将自动初始化对象的值为指定的objInit值
38 | let analyType = function (_data, key, objInit) {
39 | if ($tools.trim(key) !== '' && !_data[key]) {
40 | if (dataRequire) {
41 | // undefindData(key, _data);
42 | return false;
43 | } else {
44 | _data[key] = objInit
45 | return true;
46 | }
47 | } else {
48 | return true;
49 | }
50 | }
51 | let dotKeys, arrKeys, eackKey, noArrKey, value, l, d;
52 | // 对象循环
53 | dataEach: for (l in obj) {
54 | let _rd = sourceData;
55 | // 优先筛选dot key
56 | dotKeys = l.split(".");
57 | // 存储当前字段数据
58 | value = obj[l];
59 | // 循环查询当前dotkey 和 arrkey对象
60 | // 数组循环
61 | dotKeyEach: for (d = 0; d < dotKeys.length; d++) {
62 | eackKey = dotKeys[d];
63 | // 忽略空键,直接进入下一阶段解析
64 | if (eackKey.replace(/\s/g, "") === "") {
65 | continue dotKeyEach;
66 | }
67 | arrKeys = eackKey.match(/\[(\d+)\]/g);
68 | if (arrKeys) {
69 | if (eackKey[eackKey.length - 1] !== "]") {
70 | console.error(`Data setter key format error: [${d}];Should like: "key","key.key","key[1].key","key[1][0].key"`);//no support "key[1][0].key[1]"
71 | // break dataEach;
72 | // 终止当前数据项后续循环步骤
73 | break dotKeyEach;
74 | }
75 | let a, ai = 0, _len = arrKeys.length;
76 | // 去掉数组key
77 | noArrKey = eackKey.replace(arrKeys.join(""), "");
78 | // 检测遍历类型
79 | if (!analyType(_rd, noArrKey, [])) {
80 | return undefined;
81 | }
82 | ;
83 | // 递归赋值
84 | noArrKey !== '' && (_rd = _rd[noArrKey]);
85 | for (; ai < _len; ai++) {
86 | a = arrKeys[ai];
87 | a = Array.from(a);
88 | // 去掉中括号
89 | a.shift();
90 | a.pop();
91 | a = a.join("");
92 | // 返回查询数据
93 | if (d == dotKeys.length - 1 && ai == arrKeys.length - 1) {
94 | if (dataRequire) {
95 | return _rd[a];
96 | } else _rd[a] = value;
97 | } else {
98 | // 检测并初始化为数组
99 | if (!analyType(_rd, a, [])) {
100 | return undefined;
101 | }
102 | ;
103 | _rd = _rd[a];
104 | }
105 | }
106 | } else {
107 | // 返回查询的数据
108 | if (d == dotKeys.length - 1) {
109 | if (dataRequire) {
110 | return _rd[eackKey];
111 | }
112 | _rd[eackKey] = value;
113 | } else {
114 | // 检测并初始化为对象
115 | if (!analyType(_rd, eackKey, {})) {
116 | return undefined;
117 | }
118 | ;
119 | _rd = _rd[eackKey];
120 | }
121 | }
122 | }
123 | }
124 | } else {
125 | console.log(`AnalysisDataEngine require's a sourceData!`)
126 | }
127 | }
128 |
129 | module.exports = {
130 | dataEngine
131 | };
132 |
133 | // (function (source,key,value, _$) {
134 | // if (!_$.isPlainObject(source)) return undefined;
135 | // if (!key) return source;
136 |
137 | // let keyIsString = _$.isString(key),
138 | // keyIsPlainObject = _$.isPlainObject(key),
139 | // valueIsUndefined = _$.isUndefined(value),
140 | // //判断是否为获取数据,只能进行单个键值数据获取
141 | // dataRequire = keyIsString && valueIsUndefined,
142 | // //设置数据时
143 | // dataSetters = keyIsPlainObject ? key : {};
144 | // //将数据进行键值对设置
145 | // if(keyIsString) dataSetters[key] = !dataRequire ? value : undefined;
146 |
147 | // // dataRequire模式,不存在则返回false,并终止;
148 | // // 非dataRequire模式,将自动初始化对象的值为指定的objInit值
149 | // let detecteAndInit = function (_data, key, objInit) {
150 | // if (!(key in _data)) {
151 | // if (dataRequire) {
152 | // return false;
153 | // } else {
154 | // _data[key] = objInit
155 | // return true;
156 | // }
157 | // } else {
158 | // return true;
159 | // }
160 | // };
161 |
162 | // let dataAccess = function (_source,_key,_val) {
163 | // if (_$.isUndefined(_key)) return _source;
164 |
165 | // let _select_source,_split_k = _key.split('.');
166 |
167 | // let traverseKey = function (_tra_so,_sin_k) {
168 | // if (_$.isString(_sin_k) && _$.trim(_sin_k) !== ''){
169 | // let _arrK = _sin_k.match(/\[(\d+)\]/g),_strK = _sin_k.replace(_arrK.join(""),"");
170 | // if (_$.trim(_strK) !== ''){
171 | // _tra_so = _tra_so[_strK];
172 | // }
173 | // if (_arrK.length > 0){
174 | // _$.each(_arrK,function(i,ak){
175 |
176 | // })
177 | // }
178 |
179 | // return _tra_so;
180 | // } else {
181 | // return _tra_so;
182 | // }
183 | // }
184 | // _$.each(_split_k,function(i,mulK){
185 | // _select_source = traverseKey(_source,mulK);
186 | // })
187 | // if(_val) _select_source = _val;
188 | // else return _select_source;
189 | // };
190 | // //如果是获取值则直接查询
191 | // if (dataRequire) return dataAccess(source,key);
192 | // //如果是设置值,则进行对象循环设置
193 | // else _$.each(dataSetters,function (set_k,set_v) {
194 | // dataAccess(source,set_k,set_v);
195 | // })
196 |
197 |
198 | // })({a:{b:1}},'a.b', 3, $);
--------------------------------------------------------------------------------
/pages_bac/logs/logs.js:
--------------------------------------------------------------------------------
1 | //logs.js
2 | // var util = require('../../utils/util.js')
3 | // Page({
4 | // data: {
5 | // logs: []
6 | // },
7 | // onLoad: function () {
8 | // console.log(__wxRoute)
9 | // this.setData({
10 | // logs: (wx.getStorageSync('logs') || []).map(function (log) {
11 | // return util.formatTime(new Date(log))
12 | // })
13 | // })
14 | // }
15 | // })
16 | var $ = wx.MinQuery.load("logs");
17 |
18 |
19 |
20 | function task(arg, cont) { // 模拟异步任务
21 | $.Thenjs.nextTick(function () {
22 | cont(null, arg);
23 | });
24 | }
25 |
26 | // $.scanCode({complete(res){console.log(res)}})
27 |
28 | // $.Thenjs($.scanCode())
29 | // .then(function(cont,data){
30 | // console.info(data);
31 | // cont();
32 | // })
33 | // .fin(function(cont,err,e){
34 | // console.log(err,e);
35 | // cont(err)
36 | // })
37 | // .fail(function (cont, error) { // 通常应该在链的最后放置一个 `fail` 方法收集异常
38 | // console.log(error);
39 | // });
40 |
41 | // $.Thenjs(function (cont) {
42 | // _task(10, cont);
43 | // })
44 | // .then(function (cont, arg) {
45 | // console.log(arg);
46 | // cont(new Error('error!'), 123);
47 | // })
48 | // .fin(function (cont, error, result) {
49 | // console.log(error, result);
50 | // cont();
51 | // })
52 | // .each([0, 1, 2], function (cont, value) {
53 | // task(value * 2, cont); // 并行执行队列任务,把队列 list 中的每一个值输入到 task 中运行
54 | // })
55 | // .then(function (cont, result) {
56 | // console.log(result);
57 | // cont();
58 | // })
59 | // .series([ // 串行执行队列任务
60 | // function (cont) { task(88, cont); }, // 队列第一个是异步任务
61 | // function (cont) { cont(null, 99); } // 第二个是同步任务
62 | // ])
63 | // .then(function (cont, result) {
64 | // console.log(result);
65 | // cont(new Error('error!!'));
66 | // })
67 | // .fail(function (cont, error) { // 通常应该在链的最后放置一个 `fail` 方法收集异常
68 | // console.log(error);
69 | // console.log('DEMO END!');
70 | // });
71 |
72 |
73 |
74 |
75 |
76 | var userName = $.setData({ "userName": "JasonDRZ" });
77 | var _page = $("page");
78 | $((_$) => {
79 | // 打组形式调用
80 | let _groups = $("#group_1,#group_2,#group_3");
81 | _groups.on("tap",function(e){
82 | _groups.css("color",'#444');
83 | $(this).css("color",'red');
84 | })
85 |
86 |
87 | $.$on("user-login", function (e) {
88 | console.log(e)
89 | });
90 |
91 | $.watch("user", function (n, o, p) {
92 | console.info(`Got userName value changes.New: ${n},Old: ${o}`, p);
93 | }, true)
94 | // console.log(_$(".name,#elements"));
95 |
96 | var $coustom = $("$coustomOne");
97 | var canvas = $("#myCanvas");
98 | var _window = $("window").get(0);
99 | // var canvasData = //$.canvas("customCanvas")
100 |
101 |
102 | // setInterval(function(){
103 | canvas.on("touchmove", function (e) {
104 | $(this).canvas(function () {
105 | this.setFillStyle('red')
106 | this.fillRect(e.touches[0].x, e.touches[0].y, 150, 75)
107 | })
108 | });
109 | // },13);
110 | var __video = $("#myVideo").on("pause",function(e){
111 | console.log("Pause:",e);
112 | wx.chooseAddress({
113 | success: function (res) {
114 | console.log(res.userName)
115 | console.log(res.postalCode)
116 | console.log(res.provinceName)
117 | console.log(res.cityName)
118 | console.log(res.countyName)
119 | console.log(res.detailInfo)
120 | console.log(res.nationalCode)
121 | console.log(res.telNumber)
122 | }
123 | })
124 | }).on("tap",function(e){
125 | console.info($('app').trigger('userLogin',{call: function(res){
126 | console.log(res);
127 | console.info(this.dataAccess("items").get())
128 | console.info(this.getData('globalData'))
129 | }},function(res){
130 | console.info("Trigger end call",res)
131 | }).data('userInfo'));
132 | console.log("video tap:",__video.pause());
133 | }).video()
134 |
135 |
136 | // $.ajax('https://minapp.ieyuan.com/jwhudong/api.php?op=content&module=comm&catid=67&page=1&state=0', {
137 | $.get('https://minapp.ieyuan.com/jwhudong/api.php', {
138 | op:'content',module:'comm',catid:67,page:1,state:0
139 | }).success((res) => {
140 | console.log(res);
141 | console.info($.$trigger('getUserInfo',function(i){
142 | // 通过dataAccess方法获取到globalData,的hook函数
143 | let globals = (this.dataAccess('globalData'));
144 | console.log(globals.get());
145 | console.info("I have success getUserInfo!!!",i)
146 | }));
147 | }).fail((res) => {
148 | console.log(res);
149 | }).complete(function(re){
150 | console.info(re);
151 | });
152 |
153 |
154 | var secondSelector = $(".secondClassSelector");
155 | secondSelector.config("name", "JasonDRZ");
156 | secondSelector.config("gander", "男");
157 | secondSelector.config("height", "168cm");
158 | secondSelector.on("tap", function (e) {
159 | __video.send(userName.get());
160 | console.info(e.data('mClass'));
161 | userName.set("JasonDRZ&CSQ");
162 | console.log($(this).config().name("JSONAFDFS"));
163 | console.log($(this).config().name());
164 | $(this).toggleClass("active", "disable").delay(2000).cssAnimation("box-shadow: 0 0 10px #000;transform: scale(1.1);", 300).delay(3000).cssAnimation("border: 1px solid #444;background: #1f2a3d;", 800, ".17, .86, .73, .14").delay(4800).cssAnimation({
165 | "margin-top": "20px",
166 | "margin-bottom": "40px"
167 | }, 300)
168 | }).on("touchstart", function (e) {
169 | // console.log(e)
170 | })
171 | _page.bind("custom", "ready to go", function (e) {
172 | console.info("Page ready event has a custom handler!", e);
173 | $.navigateTo("../test-1/test-1")
174 | })
175 | _page.on("ready", "ready to go", function (e) {
176 | // Canvas在真机中需要等待页面处理方法加载完全之后才能正确进行画布动作。
177 | canvas.canvas(function () {
178 | this.setFillStyle('red')
179 | this.fillRect(10, 10, 150, 75)
180 | });
181 | // $.showModal("我正在加载!","莫泰的内容!!",true,"Canc","#5ee2c4","Conf","#1abee2",{success: function(){
182 | // console.info("我已经加载成功了!!!!!!")
183 | // }})
184 |
185 | // .success(function(){
186 | // console.info("我已经加载成功了!!!!!!")
187 | // })
188 |
189 | // wx.showLoading("Wx loading...")
190 |
191 | $.startRecord().success(function(res){console.info(res)});
192 | $.stopRecord(1000);
193 |
194 | $coustom.animation(function () {
195 | console.log(this)
196 | this.scale(2, 2).rotate(45)
197 | }, 3000, "ease").delay(3000).animation(function () {
198 | this.translate(30).rotate(0, -45)
199 | }, 5000, "linner", "0% 50%")
200 |
201 |
202 |
203 |
204 | }).registerEvent("ready", function () {
205 | console.log("第一个page ready注册事件!", $.app("globalData"))
206 | }).registerEvent("ready", function () {
207 | console.log("第二个page ready注册事件!", $.page())
208 | })
209 | _page.on("load", { name: "pageLoader2" }, function (op) {
210 | console.info("Page load event has a custom handler!", op);
211 | })
212 | // console.log(_page[0]);
213 | // console.info($.pageInheritEventKVPair);
214 | // console.info($.eventManager)
215 | })
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MinQuery
2 |
3 | MinQuery是一款针对WeChat-Min-App的一套轻量级代码工具库。旨在简化小程序开发管理流程,降低开发门槛,提高开发效率。
4 |
5 | ## API文档
6 | [中文API文档](href "https://github.com/JasonDRZ/MinQuery/blob/master/MinQuery-API.md")
7 |
8 | ## 主要特性
9 | 1. 针对已有的小程序原生API进行简单二次封装,支持更多对原生API的简洁调用方式及链式调用方式。
10 | 2. 托管小程序页面JS处理主函数逻辑,提高代码可读性及可维护性。
11 | 3. 规范小程序页面数据字段类型,提高页面逻辑管理效率。
12 | 4. 统一元素事件处理入口,让事件管理就像jQuery一样简单。
13 | 5. 引入全局事件及跨页面事件管理机制,让跨页面间的模块调用变得简单。
14 | 6. 引入第三方Teambition的then.js库作为promise处理替代,提高同、异步操作效率。
15 |
16 | ## 快速入门
17 | #### 安装
18 | 你可以通过GitHub直接下载Zip包进行解压。
19 |
20 | 项目根目录分别存在两个MinQuery文件,分别是源码版和发布版
21 |
22 | 源码版:Size 132kb
23 | ```text
24 | MinQuery.1.0.2.js
25 | ```
26 |
27 | 发布版:Size 44kb
28 | ```text
29 | MinQuery.1.0.2.min.js
30 | ```
31 | 发布版代码经过了代码压缩工具压缩及Babel ES版本降级处理,文件体积变得更加适合开发使用。如果仅为开发,建议使用发布版代码。如需做个性修改,请使用源码版。
32 |
33 | 请自行根据应用场景进行选择。
34 |
35 | ~~后续可以通过npm进行安装~~(将在后续发布到NPM中供依赖安装使用);
36 |
37 | ```js
38 | //$ npm install minquery
39 | ```
40 |
41 | #### 引用MinQuery
42 | 你只需要在根目录下的`app.js`目录下引用一次MinQuery库,后续页面的开发即可直接调用wx.MinQuery进行调用。
43 |
44 | ```js
45 |
46 | let MinQuery = require("../path/MinQuery");
47 | ```
48 | #### 载入App对象
49 | ```js
50 |
51 | let $ = MinQuery("app");
52 |
53 | //# 运行App实例
54 | $(()=>{
55 |
56 | })
57 | ```
58 |
59 | #### App事件绑定,数据绑定
60 |
61 | ```js
62 | $(()=>{
63 | let _app = $('app');
64 |
65 | _app.on('launch',function(){});
66 |
67 | _app.bind('customHandler',function(data){});
68 | _app.data("userInfo","JasonD");
69 | })
70 | ```
71 |
72 | #### 载入Page对象
73 | ```js
74 |
75 | let $ = wx.MinQuery("pageName");
76 | //# 运行Page实例
77 | $(()=>{
78 |
79 | })
80 | ```
81 | > 请注意:每个页面处理JS调用MinQuery时必须使用`load`方法注册当前页面或App,请确保传入的`pageName`名称与当前页面的名称相同,及`pageName`的唯一性,以便后续开发进行跨页面调用操作使用。
82 |
83 | #### Page事件绑定,及元素事件绑定,数据绑定
84 |
85 | ```js
86 | $(()=>{
87 |
88 | let _title = $.setData('title','Hello Word!');
89 | let _page = $('page');
90 |
91 | _page.on('load',function(){});
92 |
93 | _page.bind('customHandler',function(data){});
94 |
95 | $('#ele').on('tap',function(){
96 | $(this).addClass('active')
97 | .data('url','https://github.com/JasonDRZ/MinQuery');
98 | }).on('touchstart',function(){});
99 |
100 | })
101 |
102 | ```
103 |
104 | ### 代码规范
105 | 1. MinQuery内置方法或参数基本以`$`符号开头,请避免在开发中自定义以`$`符号开始的绑定参数或函数,以免混淆。
106 | 2. 不推荐使用原生Page方法实例上的`setData`进行数据修改,这可能会导致框架管理的数据发生变化,从而导致异常错误。
107 | 3. 推荐使用框架内置的Then.js作为`Promise`替代方法进行使用,简单、高效。
108 |
109 | # 解决的问题
110 | #### 1. 剥离小程序数据管理为一个独立模块。
111 | 小程序原生数据管理是将数据集中挂载到`data`对象下面,一旦数据量增大,将导致数据管理变得异常麻烦。于是我将`setData`接口进行了独立式扩展封装,使得设置、获取和操作数据变得更加简单高效。并且新封装的`setData`接口会对设置数据进行一次新旧数据对比,只有当数据确实存在差异时才会进行视图数据更新,降低了无效的数据更新引发的视图假更新带来的额外开销。
112 |
113 | 官方数据管理方式
114 | ```js
115 | //page-index.js
116 | Page({
117 | data: {
118 | motto: 'Hello World',
119 | userInfo: {}
120 | },
121 | //#view元素事件处理函数
122 | bindViewTap: function() {
123 | console.log('#view clicked');
124 | this.setData({
125 | 'userInfo.name': 'JasonD'
126 | })
127 | },
128 | //页面事件
129 | onLoad: function () {
130 | console.log('onLoad');
131 | console.log(this.data.motto);// => 'Hello World'
132 | },
133 | onShow: function () {
134 | console.log('onShow')
135 | }
136 | ...
137 | })
138 | ```
139 | 使用MinQuery之后
140 | ```js
141 | //page-index.js
142 | let $ = MinQuery.load("page-index");
143 |
144 | let _page = $('page');
145 | let _motto = $.setData('motto','Hello World');
146 | let _userInfo = $.setData('userInfo',{});
147 |
148 | //也可以进行统一设置
149 | // let _dataPre = $.setData({
150 | // motto: 'Hello World',
151 | // userInfo: {}
152 | // });
153 |
154 |
155 | $(()=>{
156 | //给id值为view的元素绑定tap事件
157 | $("#view").on("top",function(e){
158 | console.log('#view clicked');
159 | _userInfo.set('name','JasonD');
160 | })
161 |
162 | //页面事件绑定
163 | _page.on('load',function(){
164 | console.log('onLoad');
165 | console.log(_motto.get());// => 'Hello World'
166 | }).on('show',function(){
167 | console.log('onLoad');
168 | });
169 | })
170 | ```
171 | #### 2. 托管小程序运行方法
172 | MinQuery托管了小程序的App处理对象以及Page处理对象,使开发者在开发过程中具有更好的开发扩展性,便于模块化管理。
173 |
174 | #### 3. 统一事件处理入口
175 | 原生小程序给元素绑定不同事件时,需要设置不同名称的调用函数来作为元素的事件处理方法。少量的元素事件管理起来还得心应手,但是一旦元素事件多了,这样的管理方法就比较吃力了。并且,单个的事件处理函数与数据关联性并不明确,导致很多时候管理处理方法与数据之间的关联变得非常费力。
176 |
177 | 原生事件绑定及数据绑定,事件与数据缺乏关联性
178 |
179 | ```html
180 |
181 |
182 | 绑定事件处理class及style
186 |
187 |
188 | 绑定事件处理animation及style
192 |
193 |
194 | ```
195 |
196 | 使用MinQuery之后,只需根据事件类型,分调用`$catch`或`$bind`事件处理器即可,不用再命名其他函数名称。
197 |
198 | ```html
199 |
200 |
201 | mClass事件绑定,控制后续class的增删,js定义style
206 |
207 |
208 | id事件绑定,控制原生animation动画,控制css animation 动画
213 |
214 |
215 | ```
216 |
217 | #### 4. 封装优化原生接口,支持链式调用
218 | 原生的 `wx` 对象方法几乎清一色的使用对象形式进行参数传递,并且不支持链式调用方法,使得几乎每次调用方法都需要传入一个对象,甚是麻烦。
219 |
220 | 原生调用
221 |
222 | ```js
223 | //request官方Demo
224 | wx.request({
225 | url: 'test.php', //仅为示例,并非真实的接口地址
226 | data: {
227 | x: '' ,
228 | y: ''
229 | },
230 | header: {
231 | 'content-type': 'application/json'
232 | },
233 | success: function(res) {
234 | console.log(res.data)
235 | }
236 | })
237 | ```
238 | MinQuery调用
239 |
240 | ```js
241 | //简单get请求方法
242 | $.get('test.php',{
243 | x: '' ,
244 | y: ''
245 | }).success(function(res){
246 | console.log(res.data)
247 | });
248 | //或使用ajax方法出入官方Demo形式的object等
249 | ```
250 | MinQuery封装方法调用规范及注意事项,请参考【MinQuery小程序二次封装API使用指南】
251 |
252 | #### 5. 新增跨页面事件注册、触发、销毁等方法
253 | 原生小程序的开发,解决全局事件分发的方法是在`App`实例对象上注册处理方法,然后其他页面通过`getApp`接口获取实例调用该方法。这样的处理形式存在一定的局限性。
254 |
255 | 这里只演示使用MinQuery注册全局事件的方法:
256 |
257 | 注册全局事件
258 |
259 | ```js
260 |
261 | $.$on('globalEvent',function(cb){
262 | var userInfo = globalData.get('userInfo');
263 | if(!!userInfo){
264 | //使用$.$call 或 $.$apply方法将绑定当前框架作用域到回调函数中。
265 | $.isFunction(cb) && $.$call(cb,userInfo);
266 | }else{
267 | //调用登录接口
268 | $.login().success(function () {
269 | $.getUserInfo().success(
270 | function (res) {
271 | globalData.set('userInfo',res.userInfo);
272 | $.isFunction(cb) && $.$call(cb,res.userInfo);
273 | })
274 | });
275 | }
276 | })
277 | ```
278 | 全局事件触发
279 |
280 | ```js
281 | $.$trigger('globalEvent',function(info){
282 | // 通过dataAccess方法获取到globalData,的hook函数
283 | let globals = this.dataAccess('globalData');
284 | console.log(globals.get());
285 | console.info("I have success getUserInfo!!!",i)
286 | })
287 | ```
288 |
289 | ## 开发应用说明
290 |
291 | #### data- 自定义属性占用字段表
292 | MinQuery中的`data`自定义属性,主要用于辅助和扩展MinQuery进行元素事件触发时对元素进行校验等工作,请不要在生产时占用该属性列表中的属性,这可能会导致MinQuery的处理出错。
293 |
294 | 自定义属性 | 必填 | 用途 | 实现否
295 | ---|---|---
296 | data-m-class | 否 | `.className`样式选择器查询对象 | 已实现
297 |
298 | ```html
299 | 'm-class'将可用于选择器进行事件标识
300 | ```
301 | ```js
302 |
303 | $(".m-class").on("tap",function(e){
304 |
305 | })
306 | ```
307 |
308 | #### 元素事件处理器
309 | 使用元素事件处理器,让你很轻松的管理单个或多个元素的事件处理方法,不用在Page实例对象上创建一长串的单个处理函数了。事件处理器将进行统一管理,让你能更加直观的管理对应元素事件处理方法,更有助于后期维护。
310 |
311 | 方法名 | 处理对象 | 实现否
312 | ---|---
313 | `$bind` | 元素的bind绑定事件处理器 | 已实现
314 | `$catch` | 元素的catch捕捉事件处理器 | 已实现
315 |
316 | 这两个事件处理器通过你可以绑定到元素对应类型的事件处理方法中。如:
317 |
318 | ```html
319 |
320 | 捕捉事件
321 | 绑定事件
322 |
323 | ```
324 | 使用事件统一处理器让你不需要关心事件处理函数名称是否与`wxml`页面中调用的函数名相同,仅仅需要按照两种不同类型事件进行分类调用即可。
325 | ```js
326 | $(".catchClassSelector").on("tap",function(e){
327 |
328 | });
329 | $(".bindClassSelector").catch("tap",function(e){
330 |
331 | })
332 | ```
333 |
334 | #### 选择器列表
335 | > 这里的选择器是能够使用$()进行直接查询的选择器
336 |
337 | 选择器 | 处理对象 | 调用方法 | 实现否
338 | ---|---
339 | #elem-id | 用于生成数据或绑定触发事件到对应的id元素上 | $("#elem-id") | 已实现
340 | .elem-data-m-class | 用于生成数据或绑定触发事件到对应的data-m-class元素上 | `$(".m-class") `| 已实现
341 | window | 存储所有系统信息、处理系统底层事件绑定,如getNetworkType| `$("window")` | 待完善
342 | page | 获取当前Page的框架镜像实例对象,并对其操作| `$('page')` | 已实现
343 | app | 用于获取并操作App对象上的事件或数据| `$('app')` | 已实现
344 |
345 | ##### window对象功能
346 | 通过`$("window")`查询得到的window对象,并非正真的`window`对象,而是小程序设备信息及事件的封装。
347 |
348 | 返回的数据对象主要为`systemInfo`,不过做了部分调整:
349 |
350 | ```js
351 | var res = $("window"),sys = wx.getSystemInfoSync();
352 |
353 |
354 | res.DPI == sys.pixelRatio;//true
355 | res.width == sys.windowWidth;//true
356 | res.height == sys.windowHeight;//true
357 |
358 | res.language == sys.language;//true
359 | res.versino == sys.version;//true
360 | res.platform == sys.platform;//true
361 | res.model == sys.model;//true
362 | res.system == sys.system;//true
363 |
364 | res.callup(phoneNumber) == wx.makePhoneCall();
365 | res.scan(callback) == wx.scanCode();
366 | ```
367 | >后续将增加`$("window").on()`绑定监听设备事件方法。
368 |
369 | #### 9. 元素事件处理机制
370 | 每个元素的所有事件均可以通过`$bind`、`$catch`两个MinQuery预制的两个类型的事件处理方法进行统一处理,但是每一个不同的事件都是需要在对应的元素上绑定对应类型的事件,这样MQ才能正确的管理每个事件对应的事件处理回调方法。
371 |
372 | 在JS方面,对元素绑定事件可以使用`on()`实例方法(或是`bind()`实例方法)和`catch()`实例方法,对元素进行事件处理回调函数的绑定操作。这样,对应的事件触发会执行当前被绑定的方法。
373 |
374 | JS中对元素绑定的事件必须存在同类型的元素事件绑定方法,这样的才能生效。如:给元素`#elem`绑定`tap`事件,则必须在对应的元素上使用`bindtap="$bind"`或`catchtap="$catch"`给对应的事件触发器传入统一事件处理方法。否则JS中绑定的事件将不会被元素出发。
375 |
376 | 每个绑定的事件处理函数在元素触发的时候都会有`event`对象的参数传入匿名函数,类似小程序原生的事件对象,只不过这里做了一些简易的封装处理。
377 |
378 | >注意:`bind()`对元素的事件绑定的处理机制与`on()`相同,但在处理page选择器对象的方式上与`on()`的行为是不同的,这个后面会讲到。
379 |
380 |
381 | # License
382 | MinQuery is licensed under the [MIT](href "https://github.com/JasonDRZ/MinQuery/blob/master/LICENSE") license.
383 |
384 | Copyright (c) 2017 JasonD
385 |
--------------------------------------------------------------------------------
/MinQuery/source/utils/tools.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | const $mq_config = require('../config/mq_config');
5 |
6 | // MinQuery 工具方法及变量
7 | // 页面数据操作主体
8 | let
9 | arr = [],
10 | slice = arr.slice,
11 | concat = arr.concat,
12 | push = arr.push,
13 | indexOf = arr.indexOf,
14 | class2type = {},
15 | // 用于初始化某一类型的对象
16 | typeInitial = {},
17 | toString = class2type.toString,
18 | hasOwn = class2type.hasOwnProperty,
19 |
20 | rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
21 | // 生成类型字典
22 | let _classTypeInitial = [false, 0, '', function () {
23 | }, [], Date.now(), new RegExp(), {}, new Error(), 0];
24 | ("Boolean Number String Function Array Date RegExp Object Error Uint8Array".split(" ")).forEach(function (name, i) {
25 | let _l_name = name.toLowerCase();
26 | class2type["[object " + name + "]"] = _l_name;
27 | typeInitial[_l_name] = _classTypeInitial[i];
28 | });
29 |
30 | let $tools = {
31 |
32 | version: $mq_config.version,
33 |
34 | slice: slice,
35 |
36 | error: function (msg) {
37 | console.error(msg);
38 | },
39 | //是否开启了调试模式
40 | debugMode: false,
41 | //是否存在代理错误处理函数
42 | errorHandler: null,
43 | // MinQuery 错误事件捕捉器
44 | carry: function (context, fn) {
45 | let _fn_ret, args = [].slice.call(arguments, 2);
46 | if ($tools.debugMode) {
47 | try {
48 | _fn_ret = fn.apply(context ? context : null, args);
49 | } catch (e) {
50 | typeof $tools.errorHandler == 'function' ? $tools.errorHandler(e) : console.error(e);
51 | }
52 | } else _fn_ret = fn.apply(context ? context : null, args);
53 | return _fn_ret;
54 | },
55 |
56 | noop: function () {
57 | },
58 |
59 | isFunction: function (obj) {
60 | return $tools.type(obj) === "function";
61 | },
62 |
63 | isArraylike: function (obj) {
64 | let length = obj.length,
65 | type = $tools.type(obj);
66 |
67 | if (type === "function") {
68 | return false;
69 | }
70 |
71 | return type === "array" || length === 0 ||
72 | typeof length === "number" && length > 0 && (length - 1) in obj;
73 | },
74 |
75 | isArray: Array.isArray,
76 |
77 | isNumeric: function (obj) {
78 | // parseFloat NaNs numeric-cast false positives (null|true|false|"")
79 | // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
80 | // subtraction forces infinities to NaN
81 | // adding 1 corrects loss of precision from parseFloat (#15100)
82 | return !$tools.isArray(obj) && (obj - parseFloat(obj) + 1) >= 0;
83 | },
84 |
85 | isPlainObject: function (obj) {
86 | // Not plain objects:
87 | // - Any object or value whose internal [[Class]] property is not "[object Object]"
88 | if ($tools.type(obj) !== "object") {
89 | return false;
90 | }
91 |
92 | if (obj.constructor &&
93 | !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
94 | return false;
95 | }
96 |
97 | // If the function hasn't returned already, we're confident that
98 | // |obj| is a plain object, created by {} or constructed with new Object
99 | return true;
100 | },
101 |
102 | isString: function (str) {
103 | return typeof str === 'string';
104 | },
105 |
106 | isEmpty: function (str) {
107 | return typeof str === 'undefined' || str === null || $tools.trim(str + "") == "";
108 | },
109 |
110 | isUndefined: function (obj) {
111 | return typeof obj === 'undefined';
112 | },
113 |
114 | isEmptyObject: function (obj) {
115 | let name;
116 | for (name in obj) {
117 | return false;
118 | }
119 | return true;
120 | },
121 |
122 | type: function (obj) {
123 | if (obj == null) {
124 | return obj + "";
125 | }
126 | // Support: Android<4.0, iOS<6 (functionish RegExp)
127 | return typeof obj === "object" || typeof obj === "function" ?
128 | class2type[toString.call(obj)] || "object" :
129 | typeof obj;
130 | },
131 | // 数据镜像:将已有数据镜像还原到某一原状态;//框架内部使用
132 | recoveryObject: function (source, mirror, deep) {
133 | let isArray, s;
134 | // 支持对象数据恢复,deep操作时支持数组
135 | if ($tools.isPlainObject(source) || (deep && $tools.isArray(source))) {
136 | for (s in source) {
137 | // 均存在这恢复镜像数据到源数据
138 | if (!(s in source) && !(s in mirror)) {
139 | if (deep) {
140 | // 进行深度恢复操作
141 | if ($tools.isPlainObject(source[s]) || (deep && $tools.isArray(source[s]))) {
142 | $tools.recoveryObject(source[s], mirror[s], deep);
143 | } else {
144 | // 非对象或数组,则进行赋值操作
145 | source[s] = mirror[s];
146 | }
147 | } else {
148 | // 非深度恢复,则进行赋值操作
149 | source[s] = mirror[s]
150 | }
151 | } else if (!(s in source) && s in mirror) {
152 | // 如果镜像数据不存在,而源数据存在,则删除源数据
153 | delete source[s];
154 | } else {
155 | // 如果镜像数据存在,源数据不存在,则恢复
156 | source[s] = mirror[s];
157 | }
158 | }
159 | }
160 | },
161 | // args is for internal usage only
162 | each: function (obj, callback, args) {
163 | let value,
164 | i = 0,
165 | length = obj.length,
166 |
167 | isArray = $tools.isArraylike(obj);
168 |
169 | if (args) {
170 | if (isArray) {
171 | for (; i < length;) {
172 | value = callback.apply(obj[i++], args);
173 |
174 | if (value === false) {
175 | break;
176 | }
177 | }
178 | } else {
179 | for (i in obj) {
180 | value = callback.apply(obj[i], args);
181 |
182 | if (value === false) {
183 | break;
184 | }
185 | }
186 | }
187 |
188 | // A special, fast, case for the most common use of each
189 | } else {
190 | if (isArray) {
191 | for (; i < length;) {
192 | value = callback.call(obj[i], i, obj[i++]);
193 |
194 | if (value === false) {
195 | break;
196 | }
197 | }
198 | } else {
199 | for (i in obj) {
200 | value = callback.call(obj[i], i, obj[i]);
201 |
202 | if (value === false) {
203 | break;
204 | }
205 | }
206 | }
207 | }
208 |
209 | return obj;
210 | },
211 |
212 | trim: function (text) {
213 | return text == null ?
214 | "" :
215 | (text + "").replace(rtrim, "");
216 | },
217 |
218 | // results is for internal usage only
219 | makeArray: function (arr, results) {
220 | let ret = results || [];
221 |
222 | if (arr != null) {
223 | if ($tools.isArraylike(Object(arr))) {
224 | $tools.merge(ret,
225 | typeof arr === "string" ? [arr] : arr
226 | );
227 | } else {
228 | push.call(ret, arr);
229 | }
230 | }
231 |
232 | return ret;
233 | },
234 |
235 | inArray: function (elem, arr, i) {
236 | return arr == null ? -1 : indexOf.call(arr, elem, i);
237 | },
238 |
239 | merge: function (first, second) {
240 | let len = +second.length,
241 | j = 0,
242 | i = first.length;
243 |
244 | for (; j < len; j++) {
245 | first[i++] = second[j];
246 | }
247 |
248 | first.length = i;
249 |
250 | return first;
251 | },
252 |
253 | grep: function (elems, callback, invert) {
254 | let callbackInverse,
255 | matches = [],
256 | i = 0,
257 | length = elems.length,
258 | callbackExpect = !invert;
259 |
260 | // Go through the array, only saving the items
261 | // that pass the validator function
262 | for (; i < length; i++) {
263 | callbackInverse = !callback(elems[i], i);
264 | if (callbackInverse !== callbackExpect) {
265 | matches.push(elems[i]);
266 | }
267 | }
268 |
269 | return matches;
270 | },
271 |
272 | // arg is for internal usage only
273 | map: function (elems, callback, arg) {
274 | let value,
275 | i = 0,
276 | length = elems.length,
277 | isArray = $tools.isArraylike(elems),
278 | ret = [];
279 |
280 | // Go through the array, translating each of the items to their new values
281 | if (isArray) {
282 | for (; i < length; i++) {
283 | value = callback(elems[i], i, arg);
284 |
285 | if (value != null) {
286 | ret.push(value);
287 | }
288 | }
289 |
290 | // Go through every key on the object,
291 | } else {
292 | for (i in elems) {
293 | value = callback(elems[i], i, arg);
294 |
295 | if (value != null) {
296 | ret.push(value);
297 | }
298 | }
299 | }
300 |
301 | // Flatten any nested arrays
302 | return concat.apply([], ret);
303 | },
304 | // 短横线[或其他连接符]转驼峰
305 | toHump: function (str, symbal) {
306 | let reg = new RegExp((symbal ? symbal : "-") + "(\w)", 'g');
307 | return str.replace(reg, function ($0, $1) {
308 | return $1.toUpperCase();
309 | });
310 | },
311 | // 驼峰转中横线或任意链接符
312 | humpToAny: function (str, symbal) {
313 | return str.replace(/([A-Z])/g, (symbal ? symbal : "-") + "$1").toLowerCase();
314 | },
315 | /**
316 | * 格式化日期,支持时间戳和Date实例
317 | * @param date 要格式话的日期
318 | * @param fmt String 日期格式模板:{y:'年',m:'月',d:'日',h:'时',i:'分',s:'秒',q:'季度',S:'毫秒'}
319 | * @template ('2017.11.12','yyyy年mm月dd日') =>2017年11月12日
320 | * @return {*}
321 | */
322 | formatDate: function (date, fmt) {
323 | //author: meizz,jason
324 | if (date instanceof Date || $tools.isNumeric(date) || $tools.isString(date)) {
325 | date = new Date(date);
326 | } else {
327 | console.error("The formatDate first param must be an Date() instance or timestamp or date format string!");
328 | return date;
329 | }
330 | let o = {
331 | "m+": date.getMonth() + 1, //月份
332 | "d+": date.getDate(), //日
333 | "h+": date.getHours(), //小时
334 | "i+": date.getMinutes(), //分
335 | "s+": date.getSeconds(), //秒
336 | "q+": Math.floor((date.getMonth() + 3) / 3), //季度
337 | "S": date.getMilliseconds() //毫秒
338 | };
339 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
340 | for (let k in o)
341 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
342 | return fmt;
343 | },
344 | /**
345 | * 生成随机16进制颜色字符串方法
346 | * @return {string}
347 | */
348 | randomColor() {
349 | let rgb = [], i = 0;
350 | for (; i < 3; ++i) {
351 | let color = Math.floor(Math.random() * 256).toString(16)
352 | color = color.length == 1 ? '0' + color : color
353 | rgb.push(color)
354 | }
355 | return '#' + rgb.join('')
356 | },
357 | // 当前时间戳
358 | now: Date.now,
359 | //对象继承
360 | extend: function () {
361 | let options, name, src, copy, copyIsArray, clone,
362 | target = arguments[0] || {},
363 | i = 1,
364 | length = arguments.length,
365 | deep = false;
366 |
367 | // Handle a deep copy situation
368 | if (typeof target === "boolean") {
369 | deep = target;
370 |
371 | // Skip the boolean and the target
372 | target = arguments[i] || {};
373 | i++;
374 | }
375 |
376 | // Handle case when target is a string or something (possible in deep copy)
377 | if (typeof target !== "object" && !$tools.isFunction(target)) {
378 | target = {};
379 | }
380 |
381 | // Extend MinQuery itself if only one argument is passed
382 | if (i === length) {
383 | target = this;
384 | i--;
385 | }
386 |
387 | for (; i < length; i++) {
388 | // Only deal with non-null/undefined values
389 | if ((options = arguments[i]) != null) {
390 | // Extend the base object
391 | for (name in options) {
392 | src = target[name];
393 | copy = options[name];
394 |
395 | // Prevent never-ending loop
396 | if (target === copy) {
397 | continue;
398 | }
399 |
400 | // Recurse if we're merging plain objects or arrays
401 | if (deep && copy && ($tools.isPlainObject(copy) || (copyIsArray = $tools.isArray(copy)))) {
402 | if (copyIsArray) {
403 | copyIsArray = false;
404 | clone = src && $tools.isArray(src) ? src : [];
405 |
406 | } else {
407 | clone = src && $tools.isPlainObject(src) ? src : {};
408 | }
409 |
410 | // Never move original objects, clone them
411 | target[name] = $tools.extend(deep, clone, copy);
412 |
413 | // Don't bring in undefined values
414 | } else if (copy !== undefined) {
415 | target[name] = copy;
416 | }
417 | }
418 | }
419 | }
420 |
421 | // Return the modified object
422 | return target;
423 | }
424 | };
425 |
426 | module.exports = $tools;
--------------------------------------------------------------------------------
/MinQuery/source/third_part/thenjs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Github:** https://github.com/teambition/then.js
3 | * License:** MIT
4 | * ***/
5 | exports.when = (function () {
6 | let maxTickDepth = 100
7 | let toString = Object.prototype.toString
8 | let hasOwnProperty = Object.prototype.hasOwnProperty
9 | let nextTick = typeof setImmediate === 'function' ? setImmediate : function (fn) {
10 | setTimeout(fn, 0)
11 | }
12 | let isArray = Array.isArray || function (obj) {
13 | return toString.call(obj) === '[object Array]'
14 | }
15 |
16 | // 将 `arguments` 转成数组,效率比 `[].slice.call` 高很多
17 | function slice(args, start) {
18 | start = start || 0
19 | if (start >= args.length) return []
20 | let len = args.length
21 | let ret = Array(len - start)
22 | while (len-- > start) ret[len - start] = args[len]
23 | return ret
24 | }
25 |
26 | function map(array, iterator) {
27 | let res = []
28 | for (let i = 0, len = array.length; i < len; i++) res.push(iterator(array[i], i, array))
29 | return res
30 | }
31 |
32 | // 同步执行函数,同时捕捉异常
33 | function carry(errorHandler, fn) {
34 | try {
35 | fn.apply(null, slice(arguments, 2))
36 | } catch (error) {
37 | errorHandler(error)
38 | }
39 | }
40 |
41 | // 异步执行函数,同时捕捉异常
42 | function defer(errorHandler, fn) {
43 | let args = arguments
44 | nextTick(function () {
45 | carry.apply(null, args)
46 | })
47 | }
48 |
49 | function toThunk(object) {
50 | if (object == null) return object
51 | if (typeof object.toThunk === 'function') return object.toThunk()
52 | if (typeof object.then === 'function') {
53 | return function (callback) {
54 | object.then(function (res) {
55 | callback(null, res)
56 | }, callback)
57 | }
58 | } else return object
59 | }
60 |
61 | function arrayToTasks(array, iterator) {
62 | return map(array, function (value, index, list) {
63 | return function (done) {
64 | iterator(done, value, index, list)
65 | }
66 | })
67 | }
68 |
69 | // ## **Thenjs** 主函数
70 | function Thenjs(start, debug) {
71 | let self = this
72 | let cont
73 | if (start instanceof Thenjs) return start
74 | if (!(self instanceof Thenjs)) return new Thenjs(start, debug)
75 | self._chain = 0
76 | self._success = self._parallel = self._series = null
77 | self._finally = self._error = self._result = self._nextThen = null
78 | if (!arguments.length) return self
79 |
80 | cont = genContinuation(self, debug)
81 | start = toThunk(start)
82 | if (start === void 0) cont()
83 | else if (typeof start === 'function') defer(cont, start, cont)
84 | else cont(null, start)
85 | }
86 |
87 | Thenjs.defer = defer
88 |
89 | Thenjs.parallel = function (tasks, debug) {
90 | return new Thenjs(function (cont) {
91 | carry(cont, parallel, cont, tasks)
92 | }, debug)
93 | }
94 |
95 | Thenjs.series = function (tasks, debug) {
96 | return new Thenjs(function (cont) {
97 | carry(cont, series, cont, tasks)
98 | }, debug)
99 | }
100 |
101 | Thenjs.each = function (array, iterator, debug) {
102 | return new Thenjs(function (cont) {
103 | carry(cont, parallel, cont, arrayToTasks(array, iterator))
104 | }, debug)
105 | }
106 |
107 | Thenjs.eachSeries = function (array, iterator, debug) {
108 | return new Thenjs(function (cont) {
109 | carry(cont, series, cont, arrayToTasks(array, iterator))
110 | }, debug)
111 | }
112 |
113 | Thenjs.parallelLimit = function (tasks, limit, debug) {
114 | return new Thenjs(function (cont) {
115 | parallelLimit(cont, tasks, limit)
116 | }, debug)
117 | }
118 |
119 | Thenjs.eachLimit = function (array, iterator, limit, debug) {
120 | return new Thenjs(function (cont) {
121 | parallelLimit(cont, arrayToTasks(array, iterator), limit)
122 | }, debug)
123 | }
124 |
125 | Thenjs.nextTick = function (fn) {
126 | let args = slice(arguments, 1)
127 | nextTick(function () {
128 | fn.apply(null, args)
129 | })
130 | }
131 |
132 | // 全局 error 监听
133 | Thenjs.onerror = function (error) {
134 | console.error('Thenjs caught error: ', error)
135 | throw error
136 | }
137 |
138 | let proto = Thenjs.prototype
139 | // **Thenjs** 对象上的 **finally** 方法
140 | proto.fin = proto['finally'] = function (finallyHandler) {
141 | return thenFactory(function (cont, self) {
142 | self._finally = wrapTaskHandler(cont, finallyHandler)
143 | }, this)
144 | }
145 |
146 | // **Thenjs** 对象上的 **then** 方法
147 | proto.then = function (successHandler, errorHandler) {
148 | return thenFactory(function (cont, self) {
149 | if (successHandler) self._success = wrapTaskHandler(cont, successHandler)
150 | if (errorHandler) self._error = wrapTaskHandler(cont, errorHandler)
151 | }, this)
152 | }
153 |
154 | // **Thenjs** 对象上的 **fail** 方法
155 | proto.fail = proto['catch'] = function (errorHandler) {
156 | return thenFactory(function (cont, self) {
157 | self._error = wrapTaskHandler(cont, errorHandler)
158 | // 对于链上的 fail 方法,如果无 error ,则穿透该链,将结果输入下一链
159 | self._success = function () {
160 | let args = slice(arguments)
161 | args.unshift(null)
162 | cont.apply(null, args)
163 | }
164 | }, this)
165 | }
166 |
167 | // **Thenjs** 对象上的 **parallel** 方法
168 | proto.parallel = function (tasks) {
169 | return thenFactory(function (cont, self) {
170 | self._parallel = function (_tasks) {
171 | parallel(cont, tasks || _tasks)
172 | }
173 | }, this)
174 | }
175 |
176 | // **Thenjs** 对象上的 **series** 方法
177 | proto.series = function (tasks) {
178 | return thenFactory(function (cont, self) {
179 | self._series = function (_tasks) {
180 | series(cont, tasks || _tasks)
181 | }
182 | }, this)
183 | }
184 |
185 | // **Thenjs** 对象上的 **each** 方法
186 | proto.each = function (array, iterator) {
187 | return thenFactory(function (cont, self) {
188 | self._parallel = function (_array, _iterator) {
189 | // 优先使用定义的参数,如果没有定义参数,则从上一链结果从获取
190 | // `_array`, `_iterator` 来自于上一链的 **cont**,下同
191 | parallel(cont, arrayToTasks(array || _array, iterator || _iterator))
192 | }
193 | }, this)
194 | }
195 |
196 | // **Thenjs** 对象上的 **eachSeries** 方法
197 | proto.eachSeries = function (array, iterator) {
198 | return thenFactory(function (cont, self) {
199 | self._series = function (_array, _iterator) {
200 | series(cont, arrayToTasks(array || _array, iterator || _iterator))
201 | }
202 | }, this)
203 | }
204 |
205 | // **Thenjs** 对象上的 **parallelLimit** 方法
206 | proto.parallelLimit = function (tasks, limit) {
207 | return thenFactory(function (cont, self) {
208 | self._parallel = function (_tasks) {
209 | parallelLimit(cont, tasks || _tasks, limit)
210 | }
211 | }, this)
212 | }
213 |
214 | // **Thenjs** 对象上的 **eachLimit** 方法
215 | proto.eachLimit = function (array, iterator, limit) {
216 | return thenFactory(function (cont, self) {
217 | self._series = function (_array, _iterator) {
218 | parallelLimit(cont, arrayToTasks(array || _array, iterator || _iterator), limit)
219 | }
220 | }, this)
221 | }
222 |
223 | // **Thenjs** 对象上的 **toThunk** 方法
224 | proto.toThunk = function () {
225 | let self = this
226 | return function (callback) {
227 | if (self._result) {
228 | callback.apply(null, self._result)
229 | self._result = false
230 | } else if (self._result !== false) {
231 | self._finally = self._error = callback
232 | }
233 | }
234 | }
235 |
236 | // util.inspect() implementation
237 | proto.inspect = function () {
238 | let obj = {}
239 | for (let key in this) {
240 | if (!hasOwnProperty.call(this, key)) continue
241 | obj[key] = key === '_nextThen' ? (this[key] && this[key]._chain) : this[key]
242 | }
243 | return obj
244 | }
245 |
246 | // 核心 **continuation** 方法
247 | // **continuation** 收集任务结果,触发下一个链,它被注入各个 handler
248 | // 其参数采用 **node.js** 的 **callback** 形式:(error, arg1, arg2, ...)
249 | function continuation() {
250 | let self = this
251 | let args = slice(arguments)
252 |
253 | // then链上的结果已经处理,若重复执行 cont 则直接跳过;
254 | if (self._result === false) return
255 | // 第一次进入 continuation,若为 debug 模式则执行,对于同一结果保证 debug 只执行一次;
256 | if (!self._result && self._chain) {
257 | self.debug.apply(self, ['\nChain ' + self._chain + ': '].concat(slice(args)))
258 | }
259 | // 标记已进入 continuation 处理
260 | self._result = false
261 |
262 | carry(function (err) {
263 | if (err === args[0]) continuationError(self, err)
264 | else continuation.call(self._nextThen, err)
265 | }, continuationExec, self, args)
266 | }
267 |
268 | function continuationExec(ctx, args) {
269 | if (args[0] == null) args[0] = null
270 | else {
271 | args = [args[0]]
272 | if (!ctx._finally) throw args[0]
273 | }
274 | if (ctx._finally) return ctx._finally.apply(null, args)
275 | let success = ctx._success || ctx._parallel || ctx._series
276 | if (success) return success.apply(null, slice(args, 1))
277 | // 对于正确结果,**Thenjs** 链上没有相应 handler 处理,则在 **Thenjs** 链上保存结果,等待下一次处理。
278 | ctx._result = args
279 | }
280 |
281 | function continuationError(ctx, err) {
282 | let _nextThen = ctx
283 | let errorHandler = ctx._error || ctx._finally
284 |
285 | // 获取后链的 error handler
286 | while (!errorHandler && _nextThen._nextThen) {
287 | _nextThen = _nextThen._nextThen
288 | errorHandler = _nextThen._error || _nextThen._finally
289 | }
290 |
291 | if (errorHandler) {
292 | return carry(function (_err) {
293 | // errorHandler 存在则 _nextThen._nextThen 必然存在
294 | continuation.call(_nextThen._nextThen, _err)
295 | }, errorHandler, err)
296 | }
297 | // 如果定义了全局 **onerror**,则用它处理
298 | if (Thenjs.onerror) return Thenjs.onerror(err)
299 | // 对于 error,如果没有任何 handler 处理,则保存到链上最后一个 **Thenjs** 对象,等待下一次处理。
300 | while (_nextThen._nextThen) _nextThen = _nextThen._nextThen
301 | _nextThen._result = [err]
302 | }
303 |
304 | function genContinuation(ctx, debug) {
305 | function cont() {
306 | return continuation.apply(ctx, arguments)
307 | }
308 |
309 | // 标记 cont,cont 作为 handler 时不会被注入 cont,见 `wrapTaskHandler`
310 | cont._isCont = true
311 | // 设置并开启 debug 模式
312 | if (debug) {
313 | proto.debug = typeof debug === 'function' ? debug : defaultDebug
314 | ctx._chain = 1
315 | }
316 | return cont
317 | }
318 |
319 | // 注入 cont,执行 fn,并返回新的 **Thenjs** 对象
320 | function thenFactory(fn, ctx, debug) {
321 | let nextThen = new Thenjs()
322 | let cont = genContinuation(nextThen, debug)
323 |
324 | // 注入 cont,初始化 handler
325 | fn(cont, ctx)
326 | if (!ctx) return nextThen
327 | ctx._nextThen = nextThen
328 | if (ctx._chain) nextThen._chain = ctx._chain + 1
329 | // 检查上一链的结果是否处理,未处理则处理,用于续接 **Thenjs** 链
330 | if (ctx._result) {
331 | nextTick(function () {
332 | continuation.apply(ctx, ctx._result)
333 | })
334 | }
335 | return nextThen
336 | }
337 |
338 | // 封装 handler,`_isCont` 判定 handler 是不是 `cont` ,不是则将 `cont` 注入成第一个参数
339 | function wrapTaskHandler(cont, handler) {
340 | return handler._isCont ? handler : function () {
341 | let args = slice(arguments)
342 | args.unshift(cont)
343 | handler.apply(null, args)
344 | }
345 | }
346 |
347 | // ## **parallel** 函数
348 | // 并行执行一组 `task` 任务,`cont` 处理最后结果
349 | function parallel(cont, tasks) {
350 | if (!isArray(tasks)) return cont(errorify(tasks, 'parallel'))
351 | let pending = tasks.length
352 | let result = []
353 |
354 | if (pending <= 0) return cont(null, result)
355 | for (let i = 0, len = pending; i < len; i++) tasks[i](genNext(i))
356 |
357 | function genNext(index) {
358 | function next(error, value) {
359 | if (pending <= 0) return
360 | if (error != null) {
361 | pending = 0
362 | cont(error)
363 | } else {
364 | result[index] = value
365 | return !--pending && cont(null, result)
366 | }
367 | }
368 |
369 | next._isCont = true
370 | return next
371 | }
372 | }
373 |
374 | // ## **series** 函数
375 | // 串行执行一组 `array` 任务,`cont` 处理最后结果
376 | function series(cont, tasks) {
377 | if (!isArray(tasks)) return cont(errorify(tasks, 'series'))
378 | let i = 0
379 | let end = tasks.length - 1
380 | let run
381 | let result = []
382 | let stack = maxTickDepth
383 |
384 | if (end < 0) return cont(null, result)
385 | next._isCont = true
386 | tasks[0](next)
387 |
388 | function next(error, value) {
389 | if (error != null) return cont(error)
390 | result[i] = value
391 | if (++i > end) return cont(null, result)
392 | // 先同步执行,嵌套达到 maxTickDepth 时转成一次异步执行
393 | run = --stack > 0 ? carry : (stack = maxTickDepth, defer)
394 | run(cont, tasks[i], next)
395 | }
396 | }
397 |
398 | function parallelLimit(cont, tasks, limit) {
399 | let index = 0
400 | let pending = 0
401 | let len = tasks.length
402 | let queue = []
403 | let finished = false
404 |
405 | limit = limit >= 1 ? Math.floor(limit) : Number.MAX_VALUE
406 | // eslint-disable-next-line
407 | do {
408 | checkNext()
409 | } while (index < len && pending < limit)
410 |
411 | function checkNext() {
412 | if (finished) return
413 | if (index >= len) {
414 | finished = true
415 | return parallel(cont, queue)
416 | }
417 | if (pending >= limit) return
418 | pending++
419 | queue.push(evalTask())
420 | }
421 |
422 | function evalTask() {
423 | return new Thenjs(tasks[index++]).fin(function (next, err, res) {
424 | if (err != null) {
425 | finished = true
426 | return cont(err)
427 | }
428 | pending--
429 | checkNext()
430 | next(null, res)
431 | }).toThunk()
432 | }
433 | }
434 |
435 | // 默认的 `debug` 方法
436 | function defaultDebug() {
437 | console.log.apply(console, arguments)
438 | }
439 |
440 | // 参数不合法时生成相应的错误
441 | function errorify(obj, method) {
442 | return new Error('The argument ' + (obj && obj.toString()) + ' in "' + method + '" is not Array!')
443 | }
444 |
445 | Thenjs.NAME = 'Thenjs'
446 | Thenjs.VERSION = '2.0.3'
447 | return Thenjs
448 | })();
--------------------------------------------------------------------------------
/MinQuery/source/config/wx_config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by JasonD on 17/5/18.
3 | */
4 | let $tools = require('../utils/index');
5 |
6 |
7 | const launchScene = {
8 | '1001': [1001, '发现栏小程序主入口'],
9 | '1005': [1005, '顶部搜索框的搜索结果页'],
10 | '1006': [1006, '发现栏小程序主入口搜索框的搜索结果页'],
11 | '1007': [1007, '单人聊天会话'],
12 | '1008': [1008, '群聊会话'],
13 | '1011': [1011, '扫描二维码'],
14 | '1014': [1014, '小程序模版消息'],
15 | '1020': [1020, '公众号 profile 页相关小程序列表'],
16 | '1022': [1022, '聊天顶部置顶小程序入口'],
17 | '1023': [1023, '安卓系统桌面图标'],
18 | '1024': [1024, '小程序 profile 页'],
19 | '1025': [1025, '扫描一维码'],
20 | '1028': [1028, '我的卡包'],
21 | '1029': [1029, '卡券详情页'],
22 | '1035': [1035, '公众号自定义菜单'],
23 | '1036': [1036, 'App 分享消息卡片'],
24 | '1042': [1042, '添加好友搜索框的搜索结果页'],
25 | '1043': [1043, '公众号模板消息'],
26 | };
27 |
28 | const methodsCalls = "fail,success,complete,cancel,delay,exec".split(",");
29 |
30 | // 微信小程序原生接口支持,不支持组件接口
31 | const methodsParams = [
32 | // 接口可用性检测
33 | {
34 | name: 'canIUse'
35 | }, {
36 | //请求发起方法
37 | name: "request",
38 | param_def: [['url']],
39 | param_nor: [['data', 'object|string'], ['header', 'object', {
40 | 'content-type': 'application/json'
41 | }], ['method'], ['dataType', 'string', 'json']],
42 | agent_call: function (wxMethod, options) {
43 | // 用于支持用户小写输入
44 | !!options && !!options.method && (options.method = options.method.toUpperCase());
45 | // 加入设置的apiUrl头
46 | options.url = $tools.autoMendServer(options.url, 'ajaxServer');
47 | wxMethod(options);
48 | }
49 | }, {
50 | // 文件上传、下载
51 | // 方法名称
52 | name: 'uploadFile',
53 | // 必填参数,或者说支持快捷设置的参数,最后多一个config参数用于统一设置选填参数
54 | param_def: [['url'], ['filePath'], ['name']],
55 | // 选填参数
56 | param_nor: [['header', 'object'], ['formData', 'object']],
57 | agent_call: function (wxMethod, options) {
58 | // 加入设置的apiUrl头
59 | options.url = $tools.autoMendServer(options.url, 'uploadServer');
60 | wxMethod(options);
61 | }
62 | }, {
63 | name: 'downloadFile',
64 | param_def: [['url']],
65 | param_nor: [['header', 'object']],
66 | agent_call: function (wxMethod, options) {
67 | // 加入设置的apiUrl头
68 | options.url = $tools.autoMendServer(options.url, 'downloadServer');
69 | wxMethod(options);
70 | }
71 | }, {
72 | // webSocket
73 | name: 'connectSocket',
74 | param_def: [['url']],
75 | param_nor: [['data', 'object'], ['header', 'object'], ['method']],
76 | agent_call: function (wxMethod, options) {
77 | // 加入设置的apiUrl头
78 | options.url = $tools.autoMendServer(options.url, 'socketServer');
79 | wxMethod(options);
80 | }
81 | }, {
82 | // 只有名称的则直接返回传入参数后的方法
83 | name: 'onSocketOpen'
84 | }, {
85 | name: 'onSocketError'
86 | }, {
87 | name: 'sendSocketMessage',
88 | // 多类型支持
89 | param_def: [['data', 'string|uint8array']],
90 | param_nor: []
91 | }, {
92 | name: 'onSocketMessage'
93 | }, {
94 | name: 'closeSocket'
95 | }, {
96 | name: 'onSocketClose'
97 | }, {
98 | // 图片
99 | name: 'chooseImage',
100 | param_def: [['count', 'number']],
101 | param_nor: [['sizeType', 'array'], ['sourceType', 'array']]
102 | }, {
103 | name: 'previewImage',
104 | param_def: [['urls', 'array']],
105 | param_nor: [['current']]
106 | }, {
107 | name: 'getImageInfo',
108 | param_def: [['src']],
109 | param_nor: []
110 | }, {
111 | // 录音
112 | name: 'startRecord',
113 | param_def: [],
114 | param_nor: []
115 | }, {
116 | name: 'stopRecord',
117 | param_def: [['delay', 'number']],
118 | agent_call: function (wxMethod, options) {
119 | setTimeout(function () {
120 | delete options.delay;
121 | wxMethod(options);
122 | }, options.delay ? options.delay : 0);
123 | }
124 | }, {
125 | // 音频播放
126 | name: 'playVoice',
127 | param_def: [['filePath']],
128 | param_nor: []
129 | }, {
130 | name: 'pauseVoice'
131 | }, {
132 | name: 'stopVoice',
133 | param_def: [['delay', 'number']],
134 | agent_call: function (wxMethod, options) {
135 | setTimeout(function () {
136 | delete options.delay;
137 | wxMethod(options);
138 | }, options.delay ? options.delay : 0);
139 | }
140 | }, {
141 | // 音乐播放控制
142 | name: 'getBackgroundAudioPlayerState',
143 | param_def: [],
144 | param_nor: []
145 | }, {
146 | name: 'playBackgroundAudio',
147 | param_def: [['dataUrl']],
148 | param_nor: [['title'], ['coverImgUrl']]
149 | }, {
150 | name: 'pauseBackgroundAudio'
151 | }, {
152 | name: 'seekBackgroundAudio',
153 | param_def: [['position']],
154 | param_nor: []
155 | }, {
156 | name: 'stopBackgroundAudio'
157 | }, {
158 | name: 'onBackgroundAudioPlay'
159 | }, {
160 | name: 'onBackgroundAudioPause'
161 | }, {
162 | name: 'onBackgroundAudioStop'
163 | }, {
164 | //创建音频上下文对象
165 | name: 'createAudioContext'
166 | }, {
167 | // 选择视频
168 | name: 'chooseVideo',
169 | param_def: [],
170 | param_nor: [['sourceType', 'array'], ['maxDuration', 'number'], ['camera']]
171 | }, {
172 | //创建视频上下文对象
173 | name: 'createVideoContext'
174 | }, {
175 | // 文件
176 | name: 'saveFile',
177 | param_def: [['tempFilePath']],
178 | param_nor: []
179 | }, {
180 | name: 'getSavedFileList',
181 | param_def: [],
182 | param_nor: []
183 | }, {
184 | name: 'getSavedFileInfo',
185 | param_def: [['filePath']],
186 | param_nor: []
187 | }, {
188 | name: 'removeSavedFile',
189 | param_def: [['filePath']],
190 | param_nor: []
191 | }, {
192 | name: 'openDocument',
193 | param_def: [['filePath']],
194 | param_nor: []
195 | }, {
196 | // 数据缓存
197 | name: 'setStorage',
198 | param_def: [['key'], ['data', 'string|object']],
199 | param_nor: []
200 | }, {
201 | name: 'setStorageSync'
202 | }, {
203 | name: 'getStorage',
204 | param_def: [['key']],
205 | param_nor: []
206 | }, {
207 | name: 'getStorageSync'
208 | }, {
209 | name: 'getStorageInfo',
210 | param_def: [],
211 | param_nor: []
212 | }, {
213 | name: 'getStorageInfoSync'
214 | }, {
215 | name: 'removeStorage',
216 | param_def: [['key']],
217 | param_nor: []
218 | }, {
219 | name: 'removeStorageSync'
220 | }, {
221 | name: 'clearStorage'
222 | }, {
223 | name: 'clearStorageSync'
224 | }, {
225 | // 位置信息
226 | name: 'getLocation',
227 | param_def: [['type']],
228 | param_nor: []
229 | }, {
230 | name: 'chooseLocation',
231 | param_def: [],
232 | param_nor: []
233 | }, {
234 | name: 'openLocation',
235 | param_def: [['latitude', 'number'], ['longitude', 'number']],
236 | param_nor: [['scale', 'number'], ['name'], ['address']]
237 | }, {
238 | name: 'createMapContext'
239 | }, {
240 | // 设备信息
241 | name: 'getSystemInfo',
242 | param_def: [],
243 | param_nor: []
244 | }, {
245 | name: 'getSystemInfoSync'
246 | }, {
247 | name: 'getNetworkType',
248 | param_def: [],
249 | param_nor: []
250 | }, {
251 | name: 'onNetworkStatusChange'
252 | }, {
253 | name: 'onAccelerometerChange'
254 | }, {
255 | name: 'startAccelerometer',
256 | param_def: [],
257 | param_nor: []
258 | }, {
259 | name: 'stopAccelerometer',
260 | param_def: [],
261 | param_nor: []
262 | }, {
263 | name: 'onCompassChange'
264 | }, {
265 | name: 'startCompass',
266 | param_def: [],
267 | param_nor: []
268 | }, {
269 | name: 'stopCompass',
270 | param_def: [['delay', 'number']],
271 | param_nor: [],
272 | agent_call: function (wxMethod, options) {
273 | setTimeout(function () {
274 | delete options.delay;
275 | wxMethod(options);
276 | }, options.delay ? options.delay : 0);
277 | }
278 | }, {
279 | name: 'makePhoneCall',
280 | param_def: [['phoneNumber']],
281 | param_nor: []
282 | }, {
283 | name: 'scanCode',
284 | param_def: [],
285 | param_nor: []
286 | }, {
287 | name: 'setClipboardData',
288 | param_def: [['data']],
289 | param_nor: []
290 | }, {
291 | name: 'getClipboardData',
292 | param_def: [],
293 | param_nor: []
294 | }, {
295 | // 蓝牙设置
296 | name: 'openBluetoothAdapter',
297 | param_def: [],
298 | param_nor: []
299 | }, {
300 | name: 'closeBluetoothAdapter',
301 | param_def: [],
302 | param_nor: []
303 | }, {
304 | name: 'getBluetoothAdapterState',
305 | param_def: [],
306 | param_nor: []
307 | }, {
308 | name: 'onBluetoothAdapterStateChange'
309 | }, {
310 | name: 'startBluetoothDevicesDiscovery',
311 | param_def: [['services', 'array']],
312 | param_nor: []
313 | }, {
314 | name: 'stopBluetoothDevicesDiscovery',
315 | param_def: [],
316 | param_nor: []
317 | }, {
318 | name: 'getBluetoothDevices',
319 | param_def: [['services', 'array']],
320 | param_nor: []
321 | }, {
322 | name: 'onBluetoothDeviceFound'
323 | }, {
324 | name: 'createBLEConnection',
325 | param_def: [['deviceId']],
326 | param_nor: []
327 | }, {
328 | name: 'closeBLEConnection',
329 | param_def: [['deviceId']],
330 | param_nor: []
331 | }, {
332 | name: 'onBLEConnectionStateChanged'
333 | }, {
334 | name: 'getBLEDeviceServices',
335 | param_def: [['deviceId']],
336 | param_nor: []
337 | }, {
338 | name: 'getBLEDeviceCharacteristics',
339 | param_def: [['deviceId'], ['serviceId']],
340 | param_nor: []
341 | }, {
342 | name: 'readBLECharacteristicValue',
343 | param_def: [['deviceId'], ['serviceId'], ['characteristicId']],
344 | param_nor: []
345 | }, {
346 | name: 'writeBLECharacteristicValue',
347 | param_def: [['deviceId'], ['serviceId'], ['characteristicId'], ['value', 'uint8array']],
348 | param_nor: []
349 | }, {
350 | name: 'notifyBLECharacteristicValueChanged',
351 | param_def: [['deviceId'], ['serviceId'], ['characteristicId'], ['state', 'boolean']],
352 | param_nor: []
353 | }, {
354 | name: 'onBLECharacteristicValueChange'
355 | }, {
356 | //iBeacon
357 | name: 'startBeaconDiscovery',
358 | param_def: [['uuids','string|object']],
359 | param_nor: []
360 | }, {
361 | // 交互反馈
362 | name: 'showToast',
363 | param_def: [['title']],
364 | param_nor: [['icon'], ['image'], ['duration', 'number'], ['mask', 'boolean']]
365 | }, {
366 | name: 'showLoading',
367 | param_def: [['title']],
368 | param_nor: [['mask', 'boolean']]
369 | }, {
370 | name: 'hideToast',
371 | param_def: [['delay', 'number']],
372 | // 使用param_call时,传入的参数将全部传入到该回调中
373 | agent_call: function (wxMethod, options) {
374 | setTimeout(function () {
375 | delete options.delay;
376 | wxMethod(options);
377 | }, options.delay ? options.delay : 0);
378 | }
379 | }, {
380 | name: 'hideLoading',
381 | param_def: [['delay', 'number']],
382 | // 使用param_call时,传入的参数将全部传入到该回调中
383 | agent_call: function (wxMethod, options) {
384 | setTimeout(function () {
385 | delete options.delay;
386 | wxMethod(options);
387 | }, options.delay ? options.delay : 0);
388 | }
389 | }, {
390 | name: 'showModal',
391 | param_def: [['title'], ['content']],
392 | param_nor: [['showCancel', 'boolean'], ['cancelText'], ['cancelColor'], ['confirmText'], ['confirmColor']]
393 | }, {
394 | name: 'showActionSheet',
395 | param_def: [['itemList', 'array']],
396 | param_nor: [['itemColor']]
397 | }, {
398 | // 设置导航条
399 | name: 'setNavigationBarTitle',
400 | param_def: [['title']],
401 | param_nor: []
402 | }, {
403 | name: 'showNavigationBarLoading'
404 | }, {
405 | name: 'hideNavigationBarLoading'
406 | }, {
407 | // 导航
408 | name: 'navigateTo',
409 | param_def: [['url']],
410 | param_nor: [],
411 | agent_call: function (wxMethod, options) {
412 | // 自动补全本地路径
413 | options.url = $tools.autoMendLocalPath(options.url);
414 | wxMethod(options);
415 | }
416 | }, {
417 | name: 'redirectTo',
418 | param_def: [['url']],
419 | param_nor: [],
420 | agent_call: function (wxMethod, options) {
421 | // 自动补全本地路径
422 | options.url = $tools.autoMendLocalPath(options.url);
423 | wxMethod(options);
424 | }
425 | }, {
426 | name: 'switchTab',
427 | param_def: [['url']],
428 | param_nor: [],
429 | agent_call: function (wxMethod, options) {
430 | // 自动补全本地路径
431 | options.url = $tools.autoMendLocalPath(options.url);
432 | wxMethod(options);
433 | }
434 | }, {
435 | name: 'navigateBack'
436 | }, {
437 | name: 'reLaunch',
438 | param_def: [['url']],
439 | param_nor: [],
440 | agent_call: function (wxMethod, options) {
441 | // 自动补全本地路径
442 | options.url = $tools.autoMendLocalPath(options.url);
443 | wxMethod(options);
444 | }
445 | }, {
446 | // 下拉刷新
447 | name: 'stopPullDownRefresh'
448 | }, {
449 | // 登录
450 | name: 'login',
451 | param_def: [],
452 | param_nor: []
453 | }, {
454 | name: 'checkSession',
455 | param_def: [],
456 | param_nor: []
457 | }, {
458 | // 获取用户信息
459 | name: 'getUserInfo',
460 | param_def: [['withCredentials', 'boolean']],
461 | param_nor: []
462 | }, {
463 | // 微信支付
464 | name: 'requestPayment',
465 | param_def: [['timeStamp'], ['nonceStr'], ['package'], ['signType'], ['paySign']],
466 | param_nor: []
467 | }, {
468 | // 收货地址
469 | name: 'chooseAddress',
470 | param_def: [],
471 | param_nor: []
472 | }, {
473 | // 卡券
474 | name: 'addCard',
475 | param_def: [['cardList', 'array']],
476 | param_nor: []
477 | }, {
478 | name: 'openCard',
479 | param_def: [['cardList', 'array']],
480 | param_nor: []
481 | }, {
482 | // 设置
483 | name: 'openSetting',
484 | param_def: [],
485 | param_nor: []
486 | }, {
487 | // Buffer操作
488 | name: 'base64ToArrayBuffer'
489 | }, {
490 | name: 'arrayBufferToBase64'
491 | },
492 | //1.1.0 new API
493 | {
494 | name: 'getExtConfig',
495 | param_def: [],
496 | param_nor: []
497 | },
498 | {
499 | name: 'getExtConfigSync'
500 | },
501 | {
502 | name: 'showShareMenu',
503 | param_def: [],
504 | param_nor: []
505 | },
506 | {
507 | name: 'getExtConfig',
508 | param_def: [['withShareTicket','boolean']],
509 | param_nor: []
510 | },
511 | {
512 | name: 'hideShareMenu',
513 | param_def: [],
514 | param_nor: []
515 | },
516 | {
517 | name: 'updateShareMenu',
518 | param_def: [['withShareTicket','boolean']],
519 | param_nor: []
520 | },
521 | {
522 | name: 'getShareInfo',
523 | param_def: [['shareTicket']],
524 | param_nor: []
525 | },
526 | //1.2.0 new API
527 | {
528 | //iBeacon
529 | name: 'stopBeaconDiscovery',
530 | param_def: [],
531 | param_nor: []
532 | }, {
533 | //iBeacon
534 | name: 'getBeacons',
535 | param_def: [],
536 | param_nor: []
537 | }, {
538 | //iBeacon
539 | name: 'onBeaconUpdate'
540 | }, {
541 | //iBeacon
542 | name: 'onBeaconServiceChange'
543 | },
544 | {
545 | //获取小程序的授权设置
546 | name: 'getSetting',
547 | param_def: [],
548 | param_nor: []
549 | },{
550 | //提前授权
551 | name: 'authorize',
552 | param_def: [['scope']],
553 | param_nor: []
554 | },{
555 | //获取屏幕亮度
556 | name: 'getScreenBrightness',
557 | param_def: [],
558 | param_nor: []
559 | },{
560 | //设置屏幕亮度
561 | name: 'setScreenBrightness',
562 | param_def: [['value','number']],
563 | param_nor: []
564 | },{
565 | //保存联系人到系统通讯录
566 | name: 'addPhoneContact',
567 | param_def: [['firstName']],
568 | param_nor: [['photoFilePath'],['nickName'],['lastName'],['middleName'],
569 | ['remark'],['mobilePhoneNumber'],['weChatNumber'],['addressCountry'],
570 | ['addressState'],['addressCity'],['addressStreet'],['addressPostalCode'],
571 | ['organization'],['title'],['workFaxNumber'],['workPhoneNumber'],
572 | ['hostNumber'],['email'],['url'],['workAddressCountry'],
573 | ['workAddressState'],['workAddressCity'],['workAddressStreet'],['workAddressPostalCode'],
574 | ['homeFaxNumber'],['homePhoneNumber'],['homeAddressCountry'],['homeAddressState'],
575 | ['homeAddressCity'],['homeAddressStreet'],['homeAddressPostalCode'],
576 | ]
577 | },{
578 | //动态更新转发菜单设置
579 | name: 'updateShareMenu',
580 | param_def: [['withShareTicket','boolean']],
581 | param_nor: []
582 | },{
583 | // 使手机发生较长时间的振动(400ms)
584 | name: 'vibrateLong',
585 | param_def: [],
586 | param_nor: []
587 | },{
588 | // 使手机发生较短时间的振动(15ms)
589 | name: 'vibrateShort',
590 | param_def: [],
591 | param_nor: []
592 | },{
593 | //获取微信运动数据
594 | name: 'getWeRunData',
595 | param_def: [],
596 | param_nor: []
597 | },{
598 | //保存图片到系统相册
599 | name: 'saveImageToPhotosAlbum',
600 | param_def: [['filePath']]
601 | },{
602 | //保存视频到系统相册
603 | name: 'saveVideoToPhotosAlbum',
604 | param_def: [['filePath']]
605 | },
606 |
607 | // 组件模块
608 | {
609 | name: 'getBackgroundAudioManager'
610 | }
611 |
612 | ];
613 |
614 | // //组件及控制器
615 | // let componentsParams = [
616 | //
617 | // // 1.2.0基带以后的组件
618 | // {
619 | // // 获取背景音频管理器
620 | // name: 'getBackgroundAudioManager',
621 | // event: []
622 | // }
623 | // ]
624 |
625 |
626 | module.exports = {
627 | launchScene,
628 | methodsParams,
629 | methodsCalls
630 | }
--------------------------------------------------------------------------------
/MinQuery-API.md:
--------------------------------------------------------------------------------
1 | # 小程序MinQuery框架开发接口文档
2 |
3 | 谁说小程序就不能支持使用jQuery的方法了呢?
4 |
5 | MinQuery则由此而生,它是一款针对WeChat-Min-App的类jQuery开发管理库,它允许开发者使用类似jQuery的代码书写方式和数据管理模式进行代码逻辑的书写,并且有序、高校的管理你的小程序数据结构。让你在项目开发中能够更加轻松的进行页面数据的操作,元素事件的监听绑,元素样式、动画等属性等等操作。
6 |
7 | > 先睹为快
8 |
9 |
10 |
11 |
12 | **MinQuery —— 旨在简化小程序开发管理流程,降低开发门槛,提高开发效率。**
13 |
14 | [github地址](https://github.com/JasonDRZ/MinQuery/)
15 |
16 | [使用简介](https://github.com/JasonDRZ/MinQuery/blob/master/README.md)
17 |
18 | ## 安装使用
19 | #### 安装
20 | 你可以通过GitHub直接下载Zip包进行解压。
21 |
22 | 项目根目录分别存在两个MinQuery文件,分别是源码版和发布版
23 |
24 | 源码版:Size 132kb
25 | ```text
26 | MinQuery.1.0.2.js
27 | ```
28 |
29 | 发布版:Size 44kb
30 | ```text
31 | MinQuery.1.0.2.min.js
32 | ```
33 | 发布版代码经过了代码压缩工具压缩及Babel 处理,文件体积变得更加适合开发使用。如果仅为开发,建议使用发布版代码。如需做个性修改,请使用源码版。
34 |
35 | 请自行根据应用场景进行选择。
36 |
37 | ~~后续可以通过npm进行安装~~(将在后续发布到NPM中供依赖安装使用);
38 |
39 | ```js
40 | //$ npm install minquery
41 | ```
42 |
43 | #### 引用MinQuery
44 | 你只需要在根目录下的`app.js`目录下引用一次MinQuery库,后续页面的开发即可直接调用wx.MinQuery进行调用。
45 |
46 | ```js
47 |
48 | let MinQuery = require("../path/MinQuery");
49 | //此方法只需在app.js文件中引用一次,后续页面中可以使用一下方式进行访问。
50 | MinQuery === wx.MinQuery //=>true
51 | ```
52 |
53 | ## Debug模式
54 |
55 | MinQuery拥有一套较为健全的Error机制,用于在开发过程中捕获使用MinQuery开发时出现的各种Error问题,并方便开发进行Bug的修改等工作。**建议开发时开启,此模式!**
56 |
57 | > 你只需要在app.js文件中开启后,即可全局开启调试模式。
58 |
59 | app.js
60 |
61 | ```js
62 | let MinQuery = require("../path/MinQuery");
63 |
64 | //也可以适应wx.MinQuery.debug()方法,两方法等价。
65 | MinQuery.debug(true,function ErrorHandler(){
66 |
67 |
68 | });
69 |
70 | ```
71 |
72 |
73 | **开发完成后请关掉debug模式,以免降低程序的运行效率。**
74 |
75 | ## MinQuery页面注册
76 |
77 | **wx.MinQuery模块必须要传入一个当前页面的标识`pageName`才能正确注册并加载页面方法,并且要确保每一个`pageName`的唯一性。以便后续开发使用`$.page(pageName)` 接口,进行跨页面调用操作使用。注册完当前页面之后,所返回的才是MinQuery主框架方法集。**
78 |
79 | > 使用方法
80 |
81 | ```js
82 | /**
83 | * pageName: [String] 'app' 或是不同的 'pageName'
84 | * recoveryMode: [Boolean] 标示是否开启页面还原模式,默认为false
85 | */
86 | let $ = wx.MinQuery(pageName,recoveryMode);
87 | ```
88 | **关于`recoveryMode`,存在这个参数的主要原因是因为MinQuery框架会缓存几乎每一个页面的数据,这可能对某些页面需要打开时就是一个新状态的需求不符。故框架使用此参数标识是否对此页面开启数据恢复初始化的模式。请尽可能的少的对页面设置此参数,因为可能会造成额外的一部分性能开销。**
89 |
90 | 这里使用 `$` 来标示返回后的主框架名称。并且,每个页面注册后返回的 `$` 存在数据上的唯一性。
91 |
92 | > 载入App对象
93 |
94 | ```js
95 |
96 | App({
97 | onLaunch(){},
98 | globalData: {},
99 | ...
100 | })
101 |
102 |
103 |
104 | let $ = MinQuery("app");
105 |
106 | //# 运行App实例,此方法的调用为非必须的,但为保证在复杂结构中进行有效数据注入,请规范使用,并手动运行此方法
107 | $(()=>{
108 |
109 | })
110 | ```
111 |
112 | > 载入Page对象
113 |
114 | ```js
115 |
116 | Page({
117 | data: {},
118 | onLoad(){},
119 | ...
120 | })
121 |
122 |
123 |
124 | let $ = wx.MinQuery("pageName");
125 | //# 运行Page实例,此方法的调用为非必须的,但为保证在复杂结构中进行有效数据注入,请规范使用,并手动运行此方法
126 | $(()=>{
127 |
128 | })
129 | ```
130 |
131 | ## $.$servers() 服务器地址设置
132 | 服务器地址的设置的主要目的是为了简化异步请求url输入长度,和其他资源请求的url链接长度,让你在开发过程中部用每次的网络的请求都是用全链接进行请求设置。
133 | 当然,你也可以在实际接口请求中写入完整的地址,对应方法将自动判断是否需要进行补全。
134 | 主要设置方法如下:
135 |
136 | > 服务器地址配置
137 |
138 | 你可以在任何页面处理逻辑中进行服务器地址的设置和更改,但我们建议在`app.js`文件中进行统一设置。
139 |
140 | 主要服务器地址类型
141 |
142 | 服务器类型字段 | 使用场景描述
143 | ---|---
144 | `ajaxServer` | 设置公共的ajax请求服务器地址,在使用框架中ajax方法时,可自动补全服务器地址。
145 | `socketServer` | 设置Socket服务器地址,在使用框架中$.conectSocket()方法时,可自动补全服务器地址。
146 | `uploadServer` | 设置upLoadFile服务器地址
147 | `downloadServer` | 设置downloadFile服务器地址
148 | `imageServer` | 设置图片服务器地址
149 | `imageLocal` | 设置图片服务器地址
150 | `audioServer` | 设置音频服务器地址
151 | `videoServer` | 设置视频服务器地址
152 |
153 | app.js
154 |
155 | ```js
156 |
157 | $.$servers('ajaxServer','https://jsonplaceholder.typicode.com/');
158 |
159 | $.$servers({
160 | 'ajaxServer': 'https://www.api.com/ajax'//设置公共的ajax请求服务器地址
161 | 'socketServer': 'https://www.api.com/socket' //设置Socket服务器地址
162 | 'uploadServer': 'https://www.api.com/upload' //设置upLoadFile服务器地址
163 | 'downloadServer': 'https://www.api.com/download' //设置downloadFile服务器地址
164 | 'imageServer': 'https://www.api.com/image' //设置图片服务器地址
165 | 'audioServer': 'https://www.api.com/audio' //设置音频服务器地址
166 | 'videoServer': 'https://www.api.com/video' //设置视频服务器地址
167 | })
168 | ```
169 | 如果你在设置过程中不知道该设置那些服务器累心字段,你可以直接运行 `$.$servers()` 方法,打印出它的返回值。返回值里面会列出哪些服务器字段已经设置了,哪些字段还没有设置。
170 |
171 |
172 | ```js
173 | console.log($.$servers());//打印服务器所有类型
174 | ```
175 |
176 | > 获取服务器地址
177 |
178 | 你可以在任何页面逻辑中直接获取已经设置的服务器类型的地址设置
179 |
180 | page-xxx.js
181 |
182 | ```js
183 | console.log($.$servers('ajaxServer'));///'https://jsonplaceholder.typicode.com/'
184 | ```
185 |
186 | > 实际生产使用方法
187 |
188 |
189 | ```js
190 |
191 | $.$servers('ajaxServer','https://jsonplaceholder.typicode.com/');
192 |
193 |
194 | $.get('https://jsonplaceholder.typicode.com/post/1');
195 |
196 |
197 | $.get('post/1');//地址将会被地洞补全上设置的服务器地址:https://jsonplaceholder.typicode.com/post/1
198 |
199 |
200 | $.get('!https://www.api.com/post/1');//系统将忽略此地址的解析补全,并直接输出: https://www.api.com/post/1
201 | $.get('!/post/1');//输出地址:/post/1
202 | ```
203 |
204 |
205 |
206 | ## MinQuery 选择器与数据访问
207 |
208 | MinQuery提供了类jQuery的选择器方法,允许开发者像使用jQuery一样选择元素或事件对象。
209 |
210 | 选择器与数据之间使用规范化管理,每一个使用选择创建的元素,都将以选择器名称为标识在`Page()`实例对象上的`data`字段上挂载对应类型的标准数据。
211 |
212 | 如:ID选择器挂载的数据类型则为`$id`类型;
213 |
214 | > 选择器列表:
215 |
216 | 选择器规则 | 调用方法 | 处理对象 | 视图访问示例
217 | ---|---
218 | `#elem-id` | `$("#elem_id")` | 用于生成数据或绑定触发事件到对应的id元素上 | `{{$id.elem_id.style}}`
219 | `.elem-data-m-class` | `$(".m_class")` | 用于生成数据或绑定触发事件到对应的data-m-class元素上 | `{{$cs.m_class.style}}`
220 | `window` | `$("window")` | 获取系统信息 | `{{$window.width}}`
221 | `page` | `$('page')` | 获取当前`Page()`方法的实例对象,并对其进行操作 | 无
222 | `app` | `$('app')` | 获取`App()`实例对象 | 无
223 | `Anything Else` | `$('customs')` | 传入任何其他非内置选择器,都将在当前`Page()`实例对象上的`data`字段上挂载当前定义标示的框架标准数据形式。 | `{{customs.style}}`
224 |
225 |
226 | ### App选择器与Page选择器;
227 | 次选择器你会在`app.js`用到,做为对当前 `App()` 实例对象的调用。
228 |
229 | > 示例
230 |
231 | app.js
232 |
233 | ```js
234 | ...
235 |
236 | //# 运行App实例
237 | $(()=>{
238 | $.setData('globalData',{user: "JasonD"});
239 | $('app').on("launch",function(){
240 |
241 | }).on('userLogin',function(data){
242 |
243 |
244 | $.$call(data.call,"传给数据回调的数据");
245 |
246 | return "返回处理完的数据";
247 | })
248 | })
249 |
250 |
251 | App({
252 | onLaunch(){},
253 | ...
254 | })
255 |
256 | ```
257 | 你可能还会在其他页面的JS文件中进行调用
258 |
259 | page-xxx.js
260 | ```js
261 | ...
262 |
263 | //# 运行Page实例
264 | $(()=>{
265 |
266 | $('page').on('load',function(){
267 |
268 |
269 | $('app').trigger("userLogin",{call:function(res){
270 | console.log(res)//"传给数据回调的数据"
271 |
272 | console.info(this.getData('globalData')) //{user: "JasonD"}
273 | }},function(data){
274 | console.info("Trigger end call");
275 | console.log(data)//"返回处理完的数据"
276 | })
277 | }).bind('customHandler',function(e){
278 | console.log(e)
279 | });
280 | })
281 | ```
282 | 在UI界面可以可以直接调用 使用 `bind` 方法给 `$('page')`选择器绑定的方法 `customHandler`
283 |
284 |
285 | ```html
286 | 直接使用自定义事件
287 | ```
288 | 并且,在`$('page')`选择器上绑定的自定义事件支持进行触发调用。
289 |
290 | > 注意:原生页面事件不允许被重新触发调用!
291 |
292 | ```js
293 | $('#ele_id').on("tap",function(){
294 | $("page").trigger('customHandler', '传入的Data数据将以event事件参数字段传入!')
295 | })
296 | ```
297 |
298 | ### window选择器
299 | `window`选择器暂时只能获取设备信息,不能做其他过多的操作。
300 | 返回的数据对象主要为`systemInfo`,不过做了部分调整:
301 |
302 | ```js
303 | var res = $("window").info(),sys = wx.getSystemInfoSync();
304 |
305 |
306 | res.DPI == sys.pixelRatio;//true
307 | res.width == sys.windowWidth;//true
308 | res.height == sys.windowHeight;//true
309 |
310 | res.language == sys.language;//true
311 | res.versino == sys.version;//true
312 | res.platform == sys.platform;//true
313 | res.model == sys.model;//true
314 | res.system == sys.system;//true
315 | ```
316 |
317 | 存在三个针对`window`选择器的方法
318 |
319 | 1. `$("window").width()`用于获取width字段
320 |
321 | 2. `$("window").height()`用于获取height字段
322 |
323 | 3. `$("window").info([paramKey])` 用于获取指定的字段,如`DPI`、`language`;不传值则直接返回全部参数。
324 |
325 | 你也可以在UI层调用到window对象下的数据
326 |
327 | ```html
328 | 当前语言:{{$window.language}}
329 | ```
330 |
331 |
332 | ### ID选择器
333 | ID选择器用于选择绑定了`id`的元素,并对元素进行事件和对应数据、样式、动画等操作。
334 |
335 | 在框架中原则上认为ID是当前页面的唯一标示,请注意不要对多个元素使用同一个id标识值。
336 |
337 | > 示例
338 |
339 | ```html
340 | {{$id.ele_id.$data.myData}}
341 | ```
342 |
343 | ```js
344 | //选择并暂存元素对象
345 | let ele_id = $("#ele_id");
346 | //设置当前元素的数据
347 | ele_id.data('myData',"my data value");
348 | //元素事件绑定
349 | ele_id.on("tap",function(){})
350 | ```
351 |
352 | ### data-m-class选择器
353 | `data-m-class` 选择器用于选择绑定了`data-m-class`的元素,表现形式与`id`选择器相同。
354 |
355 | >示例
356 |
357 | ```html
358 | {{$cs.ele_m_class.$data.myData}}
359 | ```
360 |
361 | ```js
362 | //选择并暂存元素对象
363 | let ele_m_class = $(".ele_m_class");
364 | //设置当前元素的数据
365 | ele_m_class.data('myData',"my data value");
366 | //元素事件绑定
367 | ele_m_class.on("tap",function(){})
368 | ```
369 |
370 | ### 页面元素数据分类
371 | 几乎所有的选择器数据都是挂载到`Page()`实例对象上的`data`对象的,为了方便进行数据管理,我们为每一个选择器对象创建了独立的标准数据结构,用于对不同元素进行统一的数据管理。
372 |
373 | 标准数据结构对元素的各个属性和数据进行了分类管理,方便开发时进行快速数据区分。
374 |
375 | 如:
376 |
377 | `$class`字段仅用于管理元素的动态样式;
378 | `$data`用于管理与当前元素相关的数据结构;
379 | `$animation`用于管理元素的动画对象;
380 |
381 | > 元素标准访问数据结构
382 |
383 |
384 | ```js
385 | const standardElementDataStructure = {
386 | "$class": [String, "To manage the element class string! Access method: $id|$cs.elementID|mClass.$class"],
387 |
388 | "$hoverClass": [String, "To manage the element hover-class string! Access method: $id|$cs.elementID|mClass.$hoverClass"],
389 |
390 | "$attr": [Object, "To manage the element multiple attributes value! Access method: $id|$cs.elementID|mClass.$attr.disabled;"],
391 |
392 | "$cf": [Object, "To manage the Min App View Plugin's configuration! Access method: $id|$cs.elementID|mClass.$attr.disabled;"],
393 |
394 | "$style": [String, "To manage the element style string! Access method: $id|$cs.elementID|mClass.$style;"],
395 |
396 | "$cssAnimation": [Object, "To manage the element css animation string! Access method: $id|$cs.elementID|mClass.$cssAnimation;"],
397 |
398 | "$data": [Object, "To manage the element multiple custom data object! Access method: $id|$cs.elementID|mClass.$data.imageSrc;"],
399 |
400 | "$animation": [Object, "To manage the element animation object!Access method: $id|$cs.elementID|mClass.$animation;"],
401 |
402 | "$events": [Object, "To manage the element events bank route! Not recommend to access!"],
403 |
404 | "$selectorType": "To cache the element selector type!",
405 | "$selectorName": "To cache the element selector name!"
406 | }
407 | ```
408 |
409 |
410 | > `data`对象实例
411 |
412 | ```js
413 | ...
414 | data:{
415 |
416 | $id: {
417 | ele_id: standardElementDataStructure,
418 | ...
419 | },
420 |
421 | $cs: {
422 | ele_m_class: standardElementDataStructure,
423 | ...
424 | },
425 |
426 | $window: {
427 | windowInfo
428 | },
429 |
430 | $servers: {
431 | ajaxServer: '',
432 | imageSerer: '',
433 | ...
434 | },
435 |
436 | customSelector: standardElementDataStructure,
437 |
438 | setData_key: '与数据设置的类型保持一致'
439 | },
440 | ...
441 | ```
442 |
443 | ## 视图数据呈现分类
444 |
445 | 基于页面数据的分类管理形式,我们对视图各个元素和组件的数据也参照分类型数据管理方式进行管理,方便项目的后期的数据逻辑性维护工作的开展。
446 |
447 | > 元素
448 |
449 |
450 | ```html
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 | {{$id.view_id.$text ? $id.view_id.$text : "给个默认的文本,你也可以在JS中进行预设"}}
463 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
496 |
497 |
498 | ```
499 |
500 | > 组件
501 |
502 |
503 | ```html
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 | ```
512 |
513 |
514 | ## MinQuery 核心
515 |
516 | MinQuery的核心接口是在开发过程中密切使用的接口,这里做了重点阐述。
517 |
518 | ### $(function(){})
519 |
520 | `$(function(){})` 是 `Page()` 方法调用主函数,每个页面JS中都必须运行一次此方法,用于启用 小程序原生的 `Page()` 方法。
521 |
522 | 但是不同的是,使用`$(function(){})` 方法调用 `Page()` 显得更加的灵活。你并不需要将页面的处理逻辑完全放入`$(function(){})`方法中进行执行,你甚至可以在当前的页面JS中的任意位置书写你的页面处理逻辑代码。
523 |
524 | 对于轻量级的页面处理逻辑,你甚至都不需要运行`$(function(){})`方法,框架会自动检测是否手动调用过此方法,如果没有调用,框架会自行执行一次`$(function(){})`方法。
525 |
526 | > 示例
527 |
528 |
529 | ```js
530 |
531 |
532 | let $ = wx.MinQuery("pageName");
533 | //# 运行Page实例,如果你没有调用此方法,框架将会自动帮你执行一次。
534 | $(()=>{
535 |
536 | });
537 | ```
538 |
539 | > 请注意,有两种情况下不能让框架进行自动调用`$(function(){})`:
540 | 1. 页面JS文件存在复杂处理逻辑时,需手动调用`$(function(){})`方法。否则将造成数据丢失或事件方法注入失败等问题。
541 | 2. 在`app.json`中的 `tabBar-list` 下配置的页面需进行手动执行,否则小程序会报运行时错误。
542 |
543 | >为保证数据的正确注入,推荐在所有页面处理逻辑中手动运行`$(function(){})`方法来完成Page事件和数据的绑定注入。
544 |
545 |
546 |
547 | ### $.setData();
548 | 首先是页面数据操作管理接口 `$.setData()`,它有着小程序原生Page实例对象上调用的`this.setData()`全部的功能点,但也有原生接口没有的功能。
549 |
550 | `$.setData()`与原生方法主要的不同之处在于会自动进行脏数据检测,并且比对设置前后的数据是否一致,如果不一致才会通知视图进行数据更新,从而避免了无效更新带来的性能损耗。
551 |
552 | 并且你可以在页面未加载的情况下使用`$.setData()`方法来预设置页面数据,当页面初始化完成后,预设的数据将自动同步到小程序的`Page()`实例中的`data`对象上,保证了数据的统一性和先行性。
553 |
554 | 接下来就来展示一下,新的$.setData()的强大之处。
555 |
556 |
557 | ```js
558 |
608 | let author = $.setData('author',"JasonDRZ");
609 | //等同于 let author = $.setData({'author':"JasonDRZ"});
610 |
611 |
612 | let info = $.setData({
613 | 'gander': 'Male',
614 | 'work': 'WEB Front-End'
615 | });
616 |
617 |
618 | //get(key) ;
619 | //set(key,value);
620 |
621 | console.log(author.get())//"JasonDRZ"
622 | author.set('New Author@');
623 |
624 | console.log(info.get('gander'))//'Male'
625 | console.log(info.gander.get())//'Male'
626 |
627 |
628 | //如你设置:
629 | var _t = $.setData('a.b.c',"JasonDRZ");
630 | //你将可以使用:
631 | _t.c.get()//访问'a.b.c'的值
632 | _t.c.set('new value')//设置'a.b.c'的值;
633 | //或使用
634 | _t.get('c')//访问'a.b.c'的值
635 | _t.get('a.b.c')//或是全路径获取
636 | _t.set('c','new value')//设置'a.b.c'的值;
637 | _t.set('a.b.c','new value')//或是使用全路径设置'a.b.c'的值
638 |
639 | ```
640 | 数组操作类
641 |
642 |
643 | ```js
644 | let hobbies = $.setData('hobbies',['Football','PingPang','Basketball']);
645 |
646 |
647 | hobbies.set(1,"Movies");//将'PingPang'修改为'Movies'
648 |
649 |
650 |
651 | //数组操作接口:
652 | // prepend(data | dataArr , [isBatch]);
653 | // append(data | dataArr , [isBatch]);
654 | // before(index,data | dataArr , [isBatch]);
655 | // after(index,data | dataArr , [isBatch]);
656 | // remove([key.chain],index);
657 |
658 | //在数组最前面插入一个数据,并返回插入元素的索引值
659 | let index = hobbies.prepend('Prepend Hobby');//index === 0;
660 |
661 | //在数组最后面插入多个数据,并返回插入后的最后一个元素的索引值
662 | index = hobbies.append(['Prepend Hobby One','Prepend Hobby Two'],true);//index === 5
663 |
664 | //在数组某个元素之前插入一个数据
665 | index = hobbies.before(1,'A Before Hobby'); //index === 1;
666 |
667 | //在数组某个元素之前插入多个个数据
668 | index = hobbies.before(1,['A Before Hobby', 'Another Before Hobby'],true); //index === 2;
669 |
670 | //在数组某个元素之后插入一个数据
671 | index = hobbies.after(1,'An After Hobby'); //index === 2;
672 |
673 |
674 |
675 | //删除某个元素,接收要删除的index值
676 | hobbies.remove(1);
677 |
678 | hobbise.remove('An.array.data',2);
679 |
680 | ```
681 |
682 | 长键值设置数据
683 |
684 | ```js
685 | let _multi_level = $.setData('multis.info',[{'name':"JasonD","hobbies":['Football','PingPang','Basketball'],{'name':"Tom","hobbies":['Football','PingPang','Basketball']}]);
686 |
687 |
688 | $.setData('multis.info[0].hobbies[1]',"Movies");
689 |
690 | _multi_level.set('[0].hobbies[1]','Movies');
691 |
692 | ```
693 |
694 | ### $.getData()
695 | 此接口一般与$.setData()配合使用,它只能用来根据键字符串来获取对应数据。
696 |
697 | ```js
698 |
792 | .success((res) => {
793 | console.log(res);
794 | }).fail((err) => {
795 | console.error(err);
796 | }).complete(function(re){
797 | console.info(re);
798 | });
799 | ```
800 |
801 | > 如果需要进行长then链处理,请结合使用框架工具方法`$.$when()`进行链式调用处理,当然你也可以使用原生ES6的Promise方法进行处理。使用方法如下。
802 |
803 | ```js
804 | $.$when($.ajax('test.php', {op:'content',module:'comm'}))
805 |
806 | .then((cont,res) => {
807 | console.log(res);
808 | cont(null,res);
809 | })
810 |
811 | .then((cont,res) => {
812 | console.error(res);
813 | cont(null,res)
814 | })
815 |
816 | .fin(function(cont,err,res){
817 | err ? console.log(err) : console.log(res);
818 | cont();
819 | })
820 |
821 | .fail(function(err){
822 | console.error(err);
823 | });
824 |
825 |
826 | let sendAjax = new Promise(function(resolve, reject) {
827 | resolve('ok');
828 | $.ajax('test.php', {op:'content',module:'comm'})
829 | .success(res=>{resolve(res)})
830 | .fail(err=>{reject(err)});
831 | });
832 | sendAjax
833 | .then(function(res) { console.log(res) })
834 | .catch(function(error) { console.log(error)});
835 | ```
836 |
837 | > 关于`$.$when()`方法的使用请参考工具方法集中对它的介绍
838 |
839 | ### 元素事件绑定
840 |
841 | `$all`获取当前元素所有绑定事件。
842 |
843 | ```js
844 | $('#view-id').on('$all',function(e){
845 |
846 | })
847 | ```
848 |
849 |
850 | ## $ 工具方法集
851 |
852 | 用过jQuery的同学一定对jQuery的工具方法不陌生。诸如:$.trim()、$.slice()、$.isString()、$.type、$.makeArray()等等,MinQuery基本上也有这些接口的哟。
--------------------------------------------------------------------------------