├── .gitignore ├── index.js ├── README.md ├── test.js ├── src ├── service.js ├── url.js ├── path.js ├── utils.js └── router.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | *logs 4 | DS_Store -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var service = require('./src/service'); 2 | module.exports = service; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # weex-service 2 | 3 | Fast create weex service for multiple pages application. 4 | 5 | ## Install 6 | 7 | ```bash 8 | $ npm install weex-service 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```javascript 14 | var service = require('weex-service'); 15 | 16 | ``` -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | var Router = require('./src/router'); 2 | 3 | var router = new Router('http://www.new.com:8088/a/b/app.weex.js?q=123/#/c/d/1?c=10', '/c/:test/:id'); 4 | 5 | console.log(router.route); 6 | 7 | console.log(router.parse('www.new.com/a/b/app.weex.js?q=123/#/c/d/1?c=10', '/c/:test/:id')) 8 | 9 | var qs = require('qs'); 10 | 11 | console.log(qs.stringify({ 12 | a: 100, 13 | b: [1, 2] 14 | })); -------------------------------------------------------------------------------- /src/service.js: -------------------------------------------------------------------------------- 1 | var Router = require('./router'); 2 | 3 | exports.create = function(el, View, routes) { 4 | var url = weex.config.bundleUrl; 5 | var router = new Router({ url: url, routes: routes }); 6 | 7 | Vue.prototype.$router = router; 8 | Vue.prototype.$route = router.route; 9 | 10 | new Vue({ 11 | el: el, 12 | render: function(h) { 13 | return h(View); 14 | } 15 | }); 16 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weex-service", 3 | "version": "0.0.2", 4 | "description": "Fast create weex service for multiple pages application.", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/Spikef/weex-service.git" 10 | }, 11 | "keywords": [ 12 | "weex", 13 | "service", 14 | "router" 15 | ], 16 | "author": "Spikef", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/Spikef/weex-service/issues" 20 | }, 21 | "homepage": "https://github.com/Spikef/weex-service#readme", 22 | "dependencies": { 23 | "path-to-regexp": "^1.7.0", 24 | "qs": "^6.4.0" 25 | }, 26 | "devDependencies": { 27 | "webpack": "^2.3.3" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/url.js: -------------------------------------------------------------------------------- 1 | module.exports = function(url) { 2 | var req = { 3 | protocol: '', 4 | host: '', 5 | port: '', 6 | href: '', 7 | origin: '', 8 | pathname: '', 9 | filename: '' 10 | }; 11 | 12 | req.href = url; 13 | 14 | url = url.replace(/[?#].+/, ''); 15 | 16 | var parts; 17 | 18 | parts = url.split('//'); 19 | if (/^(http|https|ftp|file):$/.test(parts[0])) { 20 | req.protocol = parts.shift(); 21 | url = parts.join('/'); 22 | } 23 | 24 | parts = url.split('/'); 25 | req.origin = parts.shift(); 26 | req.filename = parts.pop(); 27 | req.pathname = parts.join('/'); 28 | req.pathname = '/' + req.pathname; 29 | 30 | parts = req.origin.split(':'); 31 | req.host = parts.shift(); 32 | 33 | if (parts[0]) req.port = parts[0]; 34 | 35 | if (req.protocol) req.origin = req.protocol + '//' + req.origin; 36 | 37 | return req; 38 | }; -------------------------------------------------------------------------------- /src/path.js: -------------------------------------------------------------------------------- 1 | var path = require('path-to-regexp'); 2 | 3 | exports.match = function(input, match) { 4 | if (!input || !match) return false; 5 | 6 | var keys = []; 7 | var re = path(match, keys); 8 | var arr = re.exec(input, match); 9 | return arr && arr.length; 10 | }; 11 | 12 | exports.parse = function(input, match) { 13 | var params = {}; 14 | if (!input || !match) return params; 15 | 16 | var keys = []; 17 | var re = path(match, keys); 18 | var arr = re.exec(input, match); 19 | 20 | if (arr) { 21 | keys.forEach(function(d, i) { 22 | var name = d.name; 23 | var value = arr[i + 1]; 24 | if (typeof value !== 'undefined') { 25 | params[name] = value; 26 | } 27 | }); 28 | } 29 | 30 | return params; 31 | }; 32 | 33 | exports.stringify = function(params, match) { 34 | var compiler = path.compile(match) 35 | 36 | return compiler(params); 37 | }; -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | exports.isString = function() { 2 | var args = Array.prototype.slice.call(arguments); 3 | var result = []; 4 | args.forEach(function(str) { 5 | result.push(typeof str === 'string'); 6 | }); 7 | 8 | switch (result.length) { 9 | case 0: 10 | return false; 11 | case 1: 12 | return result[0]; 13 | default: 14 | return result; 15 | } 16 | }; 17 | 18 | exports.removeSlash = function(str) { 19 | if (this.isString(str)) { 20 | return str.replace(/\/$/, ''); 21 | } 22 | 23 | return str; 24 | }; 25 | 26 | exports.removeQuestion = function(str) { 27 | if (this.isString(str)) { 28 | return str.replace(/^\?/, ''); 29 | } 30 | 31 | return str; 32 | }; 33 | 34 | exports.resolveSearch = function(str) { 35 | if (this.isString(str)) { 36 | return str.replace(/^&/, '?'); 37 | } 38 | 39 | return str; 40 | }; 41 | 42 | exports.parseFileName = function(str) { 43 | var ret = { 44 | name: '', 45 | extension: '' 46 | }; 47 | 48 | if (this.isString(str)) { 49 | var parts = str.split('.'); 50 | ret.name = parts.shift(); 51 | ret.extension = parts.join('.'); 52 | } 53 | 54 | return ret; 55 | }; 56 | 57 | /** 58 | * 获取对象类型:undefined, null, string, number, array, boolean, date, error, function, math, object, regexp. 59 | * @param obj 60 | * @returns {string} 61 | */ 62 | exports.getType = function(obj) { 63 | var type = obj === null ? 'null' : typeof obj; 64 | if (type === 'object') { 65 | type = Object.prototype.toString.call(obj); // [object Array]; 66 | type = type.replace(/(\[object )|]/g, '').toLowerCase(); 67 | } 68 | 69 | return type; 70 | }; -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | var qs = require('qs'); 2 | var ps = require('./path'); 3 | var Url = require('./url'); 4 | var utils = require('./utils'); 5 | var appName = WXEnvironment.platform !== 'Web' ? '.weex.js' : ''; 6 | 7 | var navigator = weex.requireModule('navigator'); 8 | 9 | function Router(options) { 10 | var url = options.url; 11 | 12 | if (!url || !utils.isString(url)) { 13 | throw new Error('Missing required parameter url!'); 14 | } 15 | 16 | url = url.replace(/\\/g, '/'); 17 | 18 | var match, that = this; 19 | 20 | var data = splitUrl(url); 21 | if (options.routes) { 22 | this.routes = options.routes; 23 | this._routes = {}; 24 | this.routes.forEach(function(route) { 25 | that._routes[route.name] = route; 26 | }); 27 | if (data.hash) { 28 | var hash = data.hash.replace('#', ''); 29 | if (hash) match = this.match(hash); 30 | } 31 | } 32 | 33 | this.route = this.parse({ url: url, data: data }, match); 34 | } 35 | 36 | Router.prototype.match = function(hash) { 37 | if (!this.routes || !this.routes.length) { 38 | throw new Error('No routes!'); 39 | } 40 | 41 | for (var i = 0; i < this.routes.length; i++) { 42 | var route = this.routes[i]; 43 | if (ps.match(hash, route.path)) { 44 | return route.path; 45 | } 46 | } 47 | }; 48 | 49 | Router.prototype.push = function(route) { 50 | var url = this.stringify(route); 51 | 52 | navigator.push({ 53 | url: url, 54 | animated: 'true' 55 | }, function() {}); 56 | }; 57 | 58 | Router.prototype.back = function() { 59 | navigator.pop(); 60 | }; 61 | 62 | // name || {name || path, params, query} 63 | Router.prototype.stringify = function(route) { 64 | var url; 65 | var rType = utils.getType(route); 66 | 67 | if (rType === 'string') { 68 | if (/:\/\//.test(route)) { 69 | url = route + appName; 70 | } else { 71 | url = this.route.baseUrl + '/' + route + appName; 72 | } 73 | } else if (rType === 'object') { 74 | if (route.params && !this.routes) { 75 | throw new Error('You might have forgotten to define routes!'); 76 | } 77 | 78 | url = this.route.baseUrl + '/' + route.name + appName; 79 | 80 | if (route.query) { 81 | var search = qs.stringify(route.query); 82 | if (search) { 83 | url += '?' + search; 84 | } 85 | } 86 | 87 | if (this._routes && this._routes[route.name]) { 88 | var path = this._routes[route.name].path; 89 | var hash = ps.stringify(route.params, path); 90 | if (hash) { 91 | url += '#' + hash; 92 | } 93 | } 94 | } else { 95 | throw new Error('Error parameter type of route!'); 96 | } 97 | 98 | return url; 99 | }; 100 | 101 | Router.prototype.parse = function(url, match) { 102 | var data; 103 | if (typeof url === 'object') { 104 | data = url.data; 105 | url = url.url; 106 | } 107 | 108 | url = url.replace(/\\/g, '/'); 109 | 110 | if (!data) data = splitUrl(url); 111 | 112 | var route = { 113 | originUrl: url, 114 | baseUrl: data.baseUrl, 115 | host: '', 116 | protocol: '', 117 | port: '', 118 | pathname: '', 119 | filename: '', 120 | name: '', 121 | extension: '', 122 | hash: data.hash, 123 | path: '', 124 | search: data.search, 125 | match: match || '', 126 | query: {}, 127 | params: {} 128 | }; 129 | 130 | if (route.baseUrl) { 131 | var req = Url(route.baseUrl); 132 | 133 | route.baseUrl = req.origin; 134 | if (req.pathname !== '/') route.baseUrl += req.pathname; 135 | 136 | route.protocol = req.protocol; 137 | route.host = req.host; 138 | route.port = req.port; 139 | route.pathname = req.pathname; 140 | route.filename = req.filename; 141 | 142 | var file = utils.parseFileName(req.filename); 143 | route.name = file.name; 144 | route.extension = file.extension; 145 | } 146 | 147 | if (route.search) { 148 | route.search = utils.resolveSearch(route.search); 149 | route.query = qs.parse(utils.removeQuestion(route.search)); 150 | } 151 | 152 | if (route.hash) { 153 | route.path = route.hash.replace(/^#/, ''); 154 | 155 | if (match) { 156 | route.params = ps.parse(route.path, match); 157 | } 158 | } 159 | 160 | return route; 161 | }; 162 | 163 | function splitUrl(url) { 164 | var baseUrl = ''; 165 | var search = ''; 166 | var hash = ''; 167 | var parts = url.split(/(?=[?#])/); 168 | parts.forEach(function(p) { 169 | if (/^\?/.test(p)) { 170 | search += '&' + utils.removeQuestion(utils.removeSlash(p)); 171 | } else if (/#/.test(p)) { 172 | hash += utils.removeSlash(p); 173 | } else { 174 | baseUrl += p; 175 | } 176 | }); 177 | 178 | return { baseUrl: baseUrl, search: search, hash: hash }; 179 | } 180 | 181 | module.exports = Router; --------------------------------------------------------------------------------