From 17be5ba61f0a66739896581dd30c93b26fa3fa1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violet=5FIce=E7=B4=AB=E5=86=B0?= Date: Mon, 14 Oct 2019 15:42:49 +0800 Subject: [PATCH 1/3] Fix ignore Editor && vue.config lint --- .gitignore | 5 +++++ vue.config.js | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index ad46b30..ad4f14a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# Editor +.idea +.vscode +.vs + # Logs logs *.log diff --git a/vue.config.js b/vue.config.js index 9caf12e..ebb5891 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,6 +1,6 @@ module.exports = { - css: { - extract: false + css: { + extract: false }, productionSourceMap: true, configureWebpack: { -- Gitee From 04dee9e166db479f5730030451e0df08a9b6fbe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violet=5FIce=E7=B4=AB=E5=86=B0?= Date: Mon, 14 Oct 2019 16:12:56 +0800 Subject: [PATCH 2/3] =?UTF-8?q?Fix=20=E6=96=B0=E7=A4=BA=E4=BE=8B=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD=20clearPush/backReplace=EF=BC=8C?= =?UTF-8?q?=E6=96=B0=E6=96=B9=E6=B3=95=20setStack/clearStack?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 8 +- .eslintignore | 1 + example/App.vue | 27 +++++++ example/index.html | 15 ++++ example/main.js | 12 +++ example/pages/CharactersIntro.vue | 104 ++++++++++++++++++++++++ example/pages/Home.vue | 50 ++++++++++++ example/pages/article/ArticlePage.vue | 111 ++++++++++++++++++++++++++ example/pages/article/List.vue | 42 ++++++++++ example/router.js | 14 ++++ package.json | 5 +- src/components/VuePageStack.js | 18 ++++- src/config/config.js | 2 + src/index.js | 8 +- src/mixin.js | 66 ++++++++++++--- yarn.lock | 50 +++++++++++- 16 files changed, 511 insertions(+), 22 deletions(-) create mode 100644 example/App.vue create mode 100644 example/index.html create mode 100644 example/main.js create mode 100644 example/pages/CharactersIntro.vue create mode 100644 example/pages/Home.vue create mode 100644 example/pages/article/ArticlePage.vue create mode 100644 example/pages/article/List.vue create mode 100644 example/router.js diff --git a/.editorconfig b/.editorconfig index 7053c49..647c488 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,9 @@ -[*.{js,jsx,ts,tsx,vue}] +root = true + +[*] indent_style = space -indent_size = 2 trim_trailing_whitespace = true insert_final_newline = true + +[*.{js,jsx,ts,tsx,vue,html}] +indent_size = 2 diff --git a/.eslintignore b/.eslintignore index a9a1905..787c1c2 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,3 +2,4 @@ /config/ /dist/ ./*.js +/example/router.js diff --git a/example/App.vue b/example/App.vue new file mode 100644 index 0000000..f102445 --- /dev/null +++ b/example/App.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/example/index.html b/example/index.html new file mode 100644 index 0000000..4af7e54 --- /dev/null +++ b/example/index.html @@ -0,0 +1,15 @@ + + + + + + + VuePageStack - Example + + + +
+ + + diff --git a/example/main.js b/example/main.js new file mode 100644 index 0000000..3f18317 --- /dev/null +++ b/example/main.js @@ -0,0 +1,12 @@ +import Vue from 'vue'; +import App from './App.vue'; +import router from './router'; +import VuePageStack from '../src'; + +Vue.config.productionTip = false; +Vue.use(VuePageStack, { router }); + +window.vm = new Vue({ + router, + render: h => h(App) +}).$mount('#app'); diff --git a/example/pages/CharactersIntro.vue b/example/pages/CharactersIntro.vue new file mode 100644 index 0000000..7cd71a9 --- /dev/null +++ b/example/pages/CharactersIntro.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/example/pages/Home.vue b/example/pages/Home.vue new file mode 100644 index 0000000..c42a2b4 --- /dev/null +++ b/example/pages/Home.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/example/pages/article/ArticlePage.vue b/example/pages/article/ArticlePage.vue new file mode 100644 index 0000000..931d8a1 --- /dev/null +++ b/example/pages/article/ArticlePage.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/example/pages/article/List.vue b/example/pages/article/List.vue new file mode 100644 index 0000000..1f9638c --- /dev/null +++ b/example/pages/article/List.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/example/router.js b/example/router.js new file mode 100644 index 0000000..042b187 --- /dev/null +++ b/example/router.js @@ -0,0 +1,14 @@ +import Vue from 'vue' +import VueRouter from 'vue-router' + +Vue.use(VueRouter) + +export default new VueRouter({ + mode: 'hash', + routes: [ + {path: '/', name: 'Home', component: () => import('./pages/Home')}, + {path: '/characters-intro/:name', name: 'CharactersIntro', component: () => import('./pages/CharactersIntro')}, + {path: '/article', name: 'List', component: () => import('./pages/article/List')}, + {path: '/article/:id', name: 'Article', component: () => import('./pages/article/ArticlePage')} + ] +}) diff --git a/package.json b/package.json index 440de7b..e7b9808 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,12 @@ "description": "Routing and navigation for your Vue SPA. Vue 单页应用导航管理器", "author": "hezf", "scripts": { + "dev": "vue-cli-service serve ./example/main.js", "test:unit": "vue-cli-service test:unit", "build": "vue-cli-service build --target lib --name vue-page-stack ./src/index.js", "lint": "vue-cli-service lint" }, - "main": "dist/vue-page-stack.common.js", + "main": "src/index.js", "dependencies": {}, "devDependencies": { "@vue/cli-plugin-babel": "^3.11.0", @@ -22,6 +23,8 @@ "babel-jest": "^23.6.0", "eslint": "^5.16.0", "eslint-plugin-vue": "^5.0.0", + "less": "^3.10.3", + "less-loader": "^5.0.0", "vue": "^2.6.10", "vue-router": "^3.1.3", "vue-template-compiler": "^2.6.10" diff --git a/src/components/VuePageStack.js b/src/components/VuePageStack.js index 87f39db..c6dc11e 100644 --- a/src/components/VuePageStack.js +++ b/src/components/VuePageStack.js @@ -20,7 +20,7 @@ function getFirstComponentChild(children) { } } -const stack = []; +let stack = []; function getIndexByKey(key) { for (let index = 0; index < stack.length; index++) { @@ -53,6 +53,9 @@ let VuePageStack = keyName => { if (!vnode) { return vnode; } + if (history.action === config.clearPushName) { + clearStack(); + } let index = getIndexByKey(key); if (index !== -1) { vnode.componentInstance = stack[index].vnode.componentInstance; @@ -81,4 +84,15 @@ function getStack() { return stack; } -export { VuePageStack, getIndexByKey, getStack }; +function setStack(list) { + stack = list; +} + +function clearStack() { + for (const item of stack) { + item.vnode.componentInstance.$destroy(); + } + stack = []; +} + +export { VuePageStack, getIndexByKey, getStack, setStack, clearStack }; diff --git a/src/config/config.js b/src/config/config.js index 4d1d856..2eaa8eb 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -4,6 +4,8 @@ export default { pushName: 'push', goName: 'go', replaceName: 'replace', + clearPushName: 'clearPush', + backPushName: 'backPush', backName: 'back', forwardName: 'forward' }; diff --git a/src/index.js b/src/index.js index 0f25484..076068a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,4 @@ -import { VuePageStack, getIndexByKey, getStack } from './components/VuePageStack'; +import { VuePageStack, getIndexByKey, getStack, setStack, clearStack } from './components/VuePageStack'; import mixin from './mixin'; import history from './history'; import config from './config/config'; @@ -32,9 +32,11 @@ VuePageStackPlugin.install = function(Vue, { router, name = config.componentName throw Error('\n vue-router is necessary. \n\n'); } Vue.component(name, VuePageStack(keyName)); - + Vue.prototype.$pageStack = { - getStack + getStack, + setStack, + clearStack }; mixin(router); diff --git a/src/mixin.js b/src/mixin.js index a781440..5416b8b 100644 --- a/src/mixin.js +++ b/src/mixin.js @@ -1,5 +1,6 @@ import history from './history'; import config from './config/config'; +import { getStack, setStack } from './components/VuePageStack'; let eventRegister = function(router) { const routerPush = router.push.bind(router); @@ -8,8 +9,7 @@ let eventRegister = function(router) { const routerBack = router.back.bind(router); const routerForward = router.forward.bind(router); - router.push = (location, onResolve, onReject) => { - history.action = config.pushName; + const _push = function(location, onResolve, onReject) { if (onResolve || onReject) { return routerPush(location, onResolve, onReject); } @@ -19,14 +19,7 @@ let eventRegister = function(router) { } }); }; - - router.go = n => { - history.action = config.goName; - routerGo(n); - }; - - router.replace = (location, onResolve, onReject) => { - history.action = config.replaceName; + const _replace = function(location, onResolve, onReject) { if (onResolve || onReject) { return routerReplace(location, onResolve, onReject); } @@ -37,6 +30,59 @@ let eventRegister = function(router) { }); }; + router.push = (location, onResolve, onReject) => { + history.action = config.pushName; + _push(location, onResolve, onReject); + }; + + router.clearPush = (location, onResolve, onReject) => { + history.action = config.clearPushName; + _push(location, onResolve, onReject); + }; + + router.replace = (location, onResolve, onReject) => { + history.action = config.replaceName; + _replace(location, onResolve, onReject); + }; + + router.backReplace = (location, onResolve, onReject) => { + history.action = config.replaceName; + + const list = getStack(); + let len = 0; + for (const i in list) { + if (list.hasOwnProperty(i)) { + const vnode = list[i].vnode; + if (vnode.componentOptions.Ctor.extendOptions.name === 'List') { + len = i; + } + } + } + + let arr = []; + for (const i in list) { + if (list.hasOwnProperty(i)) { + const vnode = list[i].vnode; + if (i > len) { + vnode.componentInstance.$destroy(); + } else { + arr.push({ + key: list[i].key, + vnode + }); + } + } + } + + setStack(arr); + _replace(location, onResolve, onReject); + }; + + router.go = n => { + history.action = config.goName; + routerGo(n); + }; + router.back = () => { history.action = config.backName; routerBack(); diff --git a/yarn.lock b/yarn.lock index 4b65ffe..fc71b0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1572,6 +1572,11 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.npm.taobao.org/asn1.js/download/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -2493,7 +2498,7 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" -clone@2.x: +clone@2.x, clone@^2.1.1, clone@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= @@ -3494,7 +3499,7 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4" integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== -errno@^0.1.3, errno@~0.1.7: +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "http://registry.npm.taobao.org/errno/download/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" integrity sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg= @@ -4965,6 +4970,11 @@ ignore@^5.0.2: resolved "http://registry.npm.taobao.org/ignore/download/ignore-5.0.5.tgz#c663c548d6ce186fb33616a8ccb5d46e56bdbbf9" integrity sha1-xmPFSNbOGG+zNhaozLXUbla9u/k= +image-size@~0.5.0: + version "0.5.5" + resolved "https://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz?cache=0&sync_timestamp=1569841504754&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimage-size%2Fdownload%2Fimage-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -6145,6 +6155,31 @@ left-pad@^1.3.0: resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== +less-loader@^5.0.0: + version "5.0.0" + resolved "https://registry.npm.taobao.org/less-loader/download/less-loader-5.0.0.tgz#498dde3a6c6c4f887458ee9ed3f086a12ad1b466" + integrity sha1-SY3eOmxsT4h0WO6e0/CGoSrRtGY= + dependencies: + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^4.0.1" + +less@^3.10.3: + version "3.10.3" + resolved "https://registry.npm.taobao.org/less/download/less-3.10.3.tgz#417a0975d5eeecc52cff4bcfa3c09d35781e6792" + integrity sha1-QXoJddXu7MUs/0vPo8CdNXgeZ5I= + dependencies: + clone "^2.1.2" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + mime "^1.4.1" + mkdirp "^0.5.0" + promise "^7.1.1" + request "^2.83.0" + source-map "~0.6.0" + leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" @@ -6517,7 +6552,7 @@ mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime@1.6.0: +mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -7915,6 +7950,13 @@ promise-inflight@^1.0.1: resolved "https://registry.npm.taobao.org/promise-inflight/download/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.npm.taobao.org/promise/download/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078= + dependencies: + asap "~2.0.3" + prompts@^0.1.9: version "0.1.14" resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" @@ -8338,7 +8380,7 @@ request-promise-native@^1.0.5, request-promise-native@^1.0.7: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0: +request@^2.83.0, request@^2.87.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== -- Gitee From 88edcedd6d73cc924850689f2b44d86cd56308b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Violet=5FIce=E7=B4=AB=E5=86=B0?= Date: Mon, 14 Oct 2019 20:03:03 +0800 Subject: [PATCH 3/3] =?UTF-8?q?Fix=20=E6=B8=85=E9=99=A4=E5=86=97=E4=BD=99?= =?UTF-8?q?=20&&=20=E7=BC=96=E8=BE=91=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 23 +++++++++++++++++++--- README.zh-cn.md | 25 ++++++++++++++++++++---- example/pages/article/ArticlePage.vue | 28 --------------------------- 3 files changed, 41 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index ae71176..0be2ea4 100644 --- a/README.md +++ b/README.md @@ -108,12 +108,29 @@ $route(to, from) { ``` [example](https://github.com/hezhongfeng/vue-page-stack-example/blob/master/src/App.vue) -### get current UI stack +### Methods +```javascript +this.$pageStack.getStack() +this.$pageStack.setStack() +this.$pageStack.clearStack() ``` -let UIStack = this.$pageStack.getStack(); +|Method|Description| +|:----:|:----| +|getStack|get stackList| +|setStack|set StackList| +|clearStack|clear StackList| +### Advanced usage +```javascript +// clear Stack then push +// is method clearStack +this.$router.clearPush({name: 'Home'}) + +// Finds the specified page in the stack, clears the subsequent stack, and then push +// is method setStack +this.$router.backReplace({name: 'List'}) ``` -[example code](https://github.com/hezhongfeng/vue-page-stack-example/blob/814f5ad8b8804e6fd81002f7254d266df3311770/src/views/main/MainList.vue#L30) + ## Notes ### keyName diff --git a/README.zh-cn.md b/README.zh-cn.md index 162e0c9..57cc8d9 100644 --- a/README.zh-cn.md +++ b/README.zh-cn.md @@ -116,11 +116,28 @@ $route(to, from) { [example](https://github.com/hezhongfeng/vue-page-stack-example/blob/master/src/App.vue) -### 获取当前UI栈 +### 方法 +```javascript +this.$pageStack.getStack() +this.$pageStack.setStack() +this.$pageStack.clearStack() +``` +|方法|说明| +|:----:|:----| +|getStack|获取页面栈| +|setStack|设置页面栈| +|clearStack|清空页面栈| + +### 高级用法 +```javascript +// 清空页面栈,然后 push +// 使用方法 clearStack +this.$router.clearPush({name: 'Home'}) + +// 找到指定页面,清除后续页面,然后 replace +// 使用方法 setStack +this.$router.backReplace({name: 'List'}) ``` -let UIStack = this.$pageStack.getStack(); -``` -[example code](https://github.com/hezhongfeng/vue-page-stack-example/blob/814f5ad8b8804e6fd81002f7254d266df3311770/src/views/main/MainList.vue#L30) ## 相关说明 diff --git a/example/pages/article/ArticlePage.vue b/example/pages/article/ArticlePage.vue index 931d8a1..0624fd5 100644 --- a/example/pages/article/ArticlePage.vue +++ b/example/pages/article/ArticlePage.vue @@ -40,34 +40,6 @@ this.$router.clearPush({name: 'Home'}) }, goList() { - // const list = this.$pageStack.getStack() - // let len = 0 - // for (const i in list) { - // if (list.hasOwnProperty(i)) { - // const vnode = list[i].vnode - // if (vnode.componentOptions.Ctor.extendOptions.name === 'List') { - // len = i - // } - // } - // } - // - // let arr = [] - // for (const i in list) { - // if (list.hasOwnProperty(i)) { - // const vnode = list[i].vnode - // if (i > len) { - // vnode.componentInstance.$destroy() - // } else { - // arr.push({ - // key: list[i].key, - // vnode - // }) - // } - // } - // } - - // this.$pageStack.setStack(arr) - // this.$router.replace({name: 'List'}) this.$router.backReplace({name: 'List'}) } }, -- Gitee