├── .gitignore ├── gulpfile.js ├── package.json ├── READMECN.md ├── README.md ├── demo.html ├── dist ├── index.min.js └── index.js └── src └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const babel = require('gulp-babel'); 3 | const uglify = require('gulp-uglify'); 4 | const rename = require('gulp-rename'); 5 | 6 | gulp.task('default', () => { 7 | return gulp.src('src/index.js') 8 | .pipe(babel({ 9 | presets: ['es2015'] 10 | })) 11 | .pipe(gulp.dest('dist')) 12 | .pipe(uglify()) 13 | .pipe(rename({ extname: '.min.js' })) 14 | .pipe(gulp.dest('dist')); 15 | }); 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-router-then", 3 | "version": "1.3.180813", 4 | "description": "Promise the router request, then do anything you want.", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/wanyaxing/vue-router-then.git" 12 | }, 13 | "keywords": [ 14 | "promise", 15 | "vue", 16 | "router" 17 | ], 18 | "author": "wyx@wanyaxing.com", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/wanyaxing/vue-router-then/issues" 22 | }, 23 | "homepage": "https://github.com/wanyaxing/vue-router-then#readme", 24 | "devDependencies": { 25 | "babel-preset-es2015": "^6.18.0", 26 | "gulp": "^3.9.1", 27 | "gulp-babel": "^6.1.2", 28 | "gulp-rename": "^1.2.2", 29 | "gulp-uglify": "^2.0.1" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /READMECN.md: -------------------------------------------------------------------------------- 1 | # vue-router-then 2 | 3 | [demo](http://jsfiddle.net/wanyaxing/2c7f2wef/embedded/) 4 | 5 | ## 使用方法1 6 | 7 | > 顾名思义,就是给router的方法(push,replace,go)返回一个promise对象,并支持新页面的vm作为参数,进行then方法处理。 8 | 9 | ```javascript 10 | example.vue 11 | 12 | methods:{ 13 | clickSomeOne:function(){ 14 | this.$routerThen.push('/hello_world').then(vm=>{ 15 | console.log(vm); 16 | }); 17 | }, 18 | } 19 | ``` 20 | 21 | ## 使用方法2 22 | 23 | > 支持自定义指令v-model-link,捕捉新页面的input事件与当前元素互动,与同一元素上的v-model互动效果会更好。(此功能需要在keep-alive下的roter-view中使用,因为需要页面缓存支持。) 24 | 25 | 26 | ```html 27 | App.vue 28 | 33 | 34 | example.vue 35 | 44 | 53 | 54 | select_someone.vue 55 | 63 | 64 | ``` 65 | 66 | ## 安装到VUE项目中: 67 | 68 | ``` bash 69 | 70 | npm install vue-router-then --save; 71 | 72 | ``` 73 | 74 | ```javascript 75 | import Vue from 'vue' 76 | import router from './router' 77 | 78 | import routerThen from 'vue-router-then'; 79 | routerThen.initRouter(router) 80 | Vue.use(routerThen) 81 | 82 | ``` 83 | 84 | ## 继续开发和调试 85 | 86 | * 将本项目下载到本地,在src/index.js基础上进行修改后,可以使用gulp进行代码压缩和转化。 87 | ``` 88 | npm install 89 | gulp 90 | ``` 91 | * 如果本地没有安装gulp,需要先安装gulp 92 | ``` 93 | sudo npm install -g gulp 94 | ``` 95 | * 你也可以将代码发布到npm,如果你有权限的话。(或者你可以仿照此例,开发其他npm项目) 96 | ``` 97 | npm config set registry=http://registry.npmjs.org 98 | 99 | npm publish 100 | ``` 101 | ## License 102 | 103 | MIT 104 | 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-router-then 2 | 3 | [demo](http://jsfiddle.net/wanyaxing/2c7f2wef/embedded/) | [中文](https://github.com/wanyaxing/vue-router-then/blob/master/READMECN.md) 4 | 5 | ## this.$routerThen.push().then() 6 | > Promise the router request, then do anything you want . 7 | 8 | ```javascript 9 | example.vue 10 | 11 | methods:{ 12 | clickSomeOne:function(){ 13 | this.$routerThen.push('/hello_world').then(vm=>{ 14 | console.log(vm); 15 | }); 16 | }, 17 | } 18 | ``` 19 | 20 | ## v-model-link 21 | 22 | > v-model-link: add a eventListener of the element or component, to catch the input event in next router page. 23 | 24 | 25 | ```html 26 | App.vue 27 | 32 | 33 | example.vue 34 | 43 | 52 | 53 | 54 | select_someone.vue 55 | 63 | 64 | ``` 65 | 66 | 67 | ## INSTALL 68 | 69 | ``` bash 70 | 71 | npm install vue-router-then --save; 72 | 73 | ``` 74 | 75 | ```javascript 76 | import Vue from 'vue' 77 | import router from './router' 78 | 79 | import routerThen from 'vue-router-then'; 80 | routerThen.initRouter(router) 81 | Vue.use(routerThen) 82 | 83 | ``` 84 | 85 | ## DEVELOP 86 | 87 | * Code on src/index.js 88 | * Gulp it 89 | * pull it to me on github. 90 | ``` 91 | npm install 92 | gulp 93 | ``` 94 | * You need install gulp in your computer if you hasnot have it. 95 | ``` 96 | sudo npm install -g gulp 97 | ``` 98 | * publish the code to npm if you want to do it. 99 | ``` 100 | npm config set registry=http://registry.npmjs.org 101 | 102 | npm publish 103 | ``` 104 | ## License 105 | 106 | MIT 107 | 108 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | vue-router-then 6 | 7 |
8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /dist/index.min.js: -------------------------------------------------------------------------------- 1 | "use strict";var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e};(function(){var e={$router:null,resolve:null,request:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"push",o=arguments[1],n=this,t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;if(!o||""==o)throw new Error("location is missing");return new Promise(function(i,l){if(n.$router)switch(console.log("this.$router",n.$router),n.resolve=i,e){case"push":n.$router.push(o,t,r);break;case"replace":n.$router.replace(o,t,r);break;case"go":n.$router.go(o);break;default:l("requestType error:"+e)}else l("$router missing")}).catch(function(e){throw n.resolve=null,new Error(e)})},push:function(e){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return this.request("push",e,o,n)},replace:function(e){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;return this.request("replace",e,o,n)},go:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return this.request("go",e)},modelLink:function(e){var o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null;return this.push(e).then(function(e){return console.log("then",e),e.$on("input",function(e){if(console.log("modellink.input",o,e),"function"==typeof o)o(e);else if("object"==(void 0===o?"undefined":_typeof(o)))if(o.$emit)o.$emit("input",e);else if(o.tagName){o.value=e;var n=document.createEvent("HTMLEvents");n.initEvent("input",!0,!0),o.dispatchEvent(n)}}),e})},clickElFun:function(o){var n=this.getAttribute("model-link");return n?(console.log(this),e.modelLink(n,this.vnode&&this.vnode.componentInstance?this.vnode.componentInstance:this)):Promise.resolve()}},o={};o.install=function(o){Object.defineProperty(o.prototype,"$routerThen",{value:e}),o.directive("model-link",function(o,n,t){o.binding=n,o.vnode=t,o.setAttribute("model-link",n.value),o.removeEventListener("click",e.clickElFun),o.addEventListener("click",e.clickElFun)}),o.mixin({beforeRouteEnter:function(o,n,t){console.log("routerThen.resolve",e.resolve),e.resolve?t(function(o){e.resolve(o),e.resolve=null}):t(),console.log("model-link.beforeRouteEnter",o,n,t)},beforeRouteUpdate:function(o,n,t){console.log("routerThen.resolve",e.resolve),e.resolve&&(e.resolve(this),e.resolve=null),t(),console.log("model-link.beforeRouteUpdate",o,n,t)}})},o.initRouter=function(o){e.$router=o},"undefined"!=typeof module&&"object"===("undefined"==typeof exports?"undefined":_typeof(exports))&&define.cmd?module.exports=o:"function"==typeof define&&define.amd?define(function(){return o}):(this.moduleName=o,window.Vue&&Vue.use(o),window.$routerThen=o)}).call(function(){return this||("undefined"!=typeof window?window:global)}); -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | vue-router-then 3 | Promise the router request, then do anything you want . 4 | https://github.com/wanyaxing/vue-router-then 5 | */ 6 | 7 | 8 | ;(function(){ 9 | const routerThen = { 10 | '$router':null, 11 | resolve:null, 12 | //跳到指定页面,并返回promise 13 | request:function(requestType='push', location, onComplete=null, onAbort=null){ 14 | if (!location || location=='') 15 | { 16 | throw new Error('location is missing'); 17 | } 18 | return new Promise( (resolve, reject)=>{ 19 | if (this.$router) 20 | { 21 | console.log('this.$router',this.$router); 22 | this.resolve = resolve; 23 | switch (requestType) 24 | { 25 | case 'push': 26 | this.$router.push(location, onComplete, onAbort); 27 | break; 28 | case 'replace': 29 | this.$router.replace(location, onComplete, onAbort); 30 | break; 31 | case 'go': 32 | this.$router.go(location); 33 | break; 34 | default: 35 | reject('requestType error:'+requestType); 36 | break; 37 | } 38 | } 39 | else 40 | { 41 | reject('$router missing'); 42 | } 43 | }).catch(error=>{ 44 | this.resolve = null; 45 | throw new Error(error); 46 | }); 47 | }, 48 | //前往指定页面 49 | push:function(location, onComplete=null, onAbort=null){ 50 | return this.request('push',location, onComplete, onAbort); 51 | }, 52 | //替换当前页 53 | replace:function(location, onComplete=null, onAbort=null){ 54 | return this.request('replace',location, onComplete, onAbort); 55 | }, 56 | //历史记录跳转 57 | go:function(step=0){ 58 | return this.request('go',step); 59 | }, 60 | //前往新页面,并注册关联新页面的input事件到本页 61 | // 或为本页某对象自定义指令绑定点击事件 62 | // 即,新页面里触发input事件,即会回调本自定义指令对应的元素或vue对象的input事件, 63 | // 即,模拟了v-model事件 64 | modelLink:function(link, el=null){ 65 | return this.push(link).then(vm=>{ 66 | console.log('then',vm); 67 | vm.$on('input',value=>{ 68 | console.log('modellink.input',el,value); 69 | if (typeof el == 'function') 70 | { 71 | el(value); 72 | } 73 | else if (typeof el == 'object') 74 | { 75 | if (el.$emit) 76 | { 77 | el.$emit('input',value); 78 | } 79 | else if (el.tagName) 80 | { 81 | el.value = value; 82 | const e = document.createEvent('HTMLEvents'); 83 | // e.initEvent(binding.modifiers.lazy?'change':'input', true, true); 84 | e.initEvent('input', true, true); 85 | el.dispatchEvent(e); 86 | } 87 | } 88 | }); 89 | return vm; 90 | }) 91 | }, 92 | clickElFun:function(event){ 93 | let link = this.getAttribute('model-link'); 94 | if (link) 95 | { 96 | console.log(this); 97 | return routerThen.modelLink(link,this.vnode && this.vnode.componentInstance?this.vnode.componentInstance:this); 98 | } 99 | return Promise.resolve(); 100 | }, 101 | } 102 | 103 | let moduleItem = {}; 104 | moduleItem.install = function(Vue) { 105 | 106 | Object.defineProperty(Vue.prototype, '$routerThen', { value: routerThen }); 107 | 108 | Vue.directive('model-link', function (el, binding, vnode) { 109 | el.binding = binding; 110 | el.vnode = vnode; 111 | el.setAttribute('model-link',binding.value); 112 | el.removeEventListener('click',routerThen.clickElFun); 113 | el.addEventListener('click',routerThen.clickElFun); 114 | }); 115 | 116 | 117 | Vue.mixin({ 118 | // 在路由跳转到下一个页面之前,为下一个页面注册回调事件。 119 | beforeRouteEnter:function(to, from, next){ 120 | console.log('routerThen.resolve',routerThen.resolve); 121 | if (routerThen.resolve) 122 | { 123 | next(vm=>{ 124 | routerThen.resolve(vm); 125 | routerThen.resolve = null; 126 | }); 127 | } 128 | else 129 | { 130 | next(); 131 | } 132 | console.log('model-link.beforeRouteEnter',to, from, next); 133 | }, 134 | beforeRouteUpdate:function(to, from, next){ 135 | console.log('routerThen.resolve',routerThen.resolve); 136 | if (routerThen.resolve) 137 | { 138 | routerThen.resolve(this); 139 | routerThen.resolve = null; 140 | } 141 | next(); 142 | console.log('model-link.beforeRouteUpdate',to, from, next); 143 | }, 144 | }); 145 | }; 146 | 147 | moduleItem.initRouter = function(router){ 148 | routerThen.$router = router; 149 | } 150 | 151 | if (typeof module !== 'undefined' && typeof exports === 'object' && define.cmd) { 152 | module.exports = moduleItem; 153 | } else if (typeof define === 'function' && define.amd) { 154 | define(function() { return moduleItem; }); 155 | }else { 156 | this.moduleName = moduleItem; 157 | if (window.Vue) { 158 | Vue.use(moduleItem); 159 | } 160 | window.$routerThen = moduleItem; 161 | } 162 | }).call(function() { 163 | return this || (typeof window !== 'undefined' ? window : global); 164 | }); 165 | 166 | 167 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 4 | 5 | /* 6 | vue-router-then 7 | Promise the router request, then do anything you want . 8 | https://github.com/wanyaxing/vue-router-then 9 | */ 10 | 11 | ;(function () { 12 | var routerThen = { 13 | '$router': null, 14 | resolve: null, 15 | //跳到指定页面,并返回promise 16 | request: function request() { 17 | var requestType = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'push'; 18 | var location = arguments[1]; 19 | 20 | var _this = this; 21 | 22 | var onComplete = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 23 | var onAbort = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; 24 | 25 | if (!location || location == '') { 26 | throw new Error('location is missing'); 27 | } 28 | return new Promise(function (resolve, reject) { 29 | if (_this.$router) { 30 | console.log('this.$router', _this.$router); 31 | _this.resolve = resolve; 32 | switch (requestType) { 33 | case 'push': 34 | _this.$router.push(location, onComplete, onAbort); 35 | break; 36 | case 'replace': 37 | _this.$router.replace(location, onComplete, onAbort); 38 | break; 39 | case 'go': 40 | _this.$router.go(location); 41 | break; 42 | default: 43 | reject('requestType error:' + requestType); 44 | break; 45 | } 46 | } else { 47 | reject('$router missing'); 48 | } 49 | }).catch(function (error) { 50 | _this.resolve = null; 51 | throw new Error(error); 52 | }); 53 | }, 54 | //前往指定页面 55 | push: function push(location) { 56 | var onComplete = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 57 | var onAbort = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 58 | 59 | return this.request('push', location, onComplete, onAbort); 60 | }, 61 | //替换当前页 62 | replace: function replace(location) { 63 | var onComplete = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 64 | var onAbort = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; 65 | 66 | return this.request('replace', location, onComplete, onAbort); 67 | }, 68 | //历史记录跳转 69 | go: function go() { 70 | var step = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 71 | 72 | return this.request('go', step); 73 | }, 74 | //前往新页面,并注册关联新页面的input事件到本页 75 | // 或为本页某对象自定义指令绑定点击事件 76 | // 即,新页面里触发input事件,即会回调本自定义指令对应的元素或vue对象的input事件, 77 | // 即,模拟了v-model事件 78 | modelLink: function modelLink(link) { 79 | var el = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; 80 | 81 | return this.push(link).then(function (vm) { 82 | console.log('then', vm); 83 | vm.$on('input', function (value) { 84 | console.log('modellink.input', el, value); 85 | if (typeof el == 'function') { 86 | el(value); 87 | } else if ((typeof el === 'undefined' ? 'undefined' : _typeof(el)) == 'object') { 88 | if (el.$emit) { 89 | el.$emit('input', value); 90 | } else if (el.tagName) { 91 | el.value = value; 92 | var e = document.createEvent('HTMLEvents'); 93 | // e.initEvent(binding.modifiers.lazy?'change':'input', true, true); 94 | e.initEvent('input', true, true); 95 | el.dispatchEvent(e); 96 | } 97 | } 98 | }); 99 | return vm; 100 | }); 101 | }, 102 | clickElFun: function clickElFun(event) { 103 | var link = this.getAttribute('model-link'); 104 | if (link) { 105 | console.log(this); 106 | return routerThen.modelLink(link, this.vnode && this.vnode.componentInstance ? this.vnode.componentInstance : this); 107 | } 108 | return Promise.resolve(); 109 | } 110 | }; 111 | 112 | var moduleItem = {}; 113 | moduleItem.install = function (Vue) { 114 | 115 | Object.defineProperty(Vue.prototype, '$routerThen', { value: routerThen }); 116 | 117 | Vue.directive('model-link', function (el, binding, vnode) { 118 | el.binding = binding; 119 | el.vnode = vnode; 120 | el.setAttribute('model-link', binding.value); 121 | el.removeEventListener('click', routerThen.clickElFun); 122 | el.addEventListener('click', routerThen.clickElFun); 123 | }); 124 | 125 | Vue.mixin({ 126 | // 在路由跳转到下一个页面之前,为下一个页面注册回调事件。 127 | beforeRouteEnter: function beforeRouteEnter(to, from, next) { 128 | console.log('routerThen.resolve', routerThen.resolve); 129 | if (routerThen.resolve) { 130 | next(function (vm) { 131 | routerThen.resolve(vm); 132 | routerThen.resolve = null; 133 | }); 134 | } else { 135 | next(); 136 | } 137 | console.log('model-link.beforeRouteEnter', to, from, next); 138 | }, 139 | beforeRouteUpdate: function beforeRouteUpdate(to, from, next) { 140 | console.log('routerThen.resolve', routerThen.resolve); 141 | if (routerThen.resolve) { 142 | routerThen.resolve(this); 143 | routerThen.resolve = null; 144 | } 145 | next(); 146 | console.log('model-link.beforeRouteUpdate', to, from, next); 147 | } 148 | }); 149 | }; 150 | 151 | moduleItem.initRouter = function (router) { 152 | routerThen.$router = router; 153 | }; 154 | 155 | if (typeof module !== 'undefined' && (typeof exports === 'undefined' ? 'undefined' : _typeof(exports)) === 'object' && define.cmd) { 156 | module.exports = moduleItem; 157 | } else if (typeof define === 'function' && define.amd) { 158 | define(function () { 159 | return moduleItem; 160 | }); 161 | } else { 162 | this.moduleName = moduleItem; 163 | if (window.Vue) { 164 | Vue.use(moduleItem); 165 | } 166 | window.$routerThen = moduleItem; 167 | } 168 | }).call(function () { 169 | return this || (typeof window !== 'undefined' ? window : global); 170 | }); --------------------------------------------------------------------------------