diff --git a/.editorconfig b/.editorconfig
index 7053c49a045c91bd8b3015c1cf3d1f6da21660d8..647c488ad8c9c84869ca12c8e2e3bd064f28eaaf 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 a9a19052c715aa3a25c4016f51f1348391d603b1..787c1c24a8f5b2439eac5ff1a0f406ead26a351f 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,3 +2,4 @@
/config/
/dist/
./*.js
+/example/router.js
diff --git a/.gitignore b/.gitignore
index ad46b30886fa350c1f59761b100e5e4b01f9a7ec..ad4f14a517ae9d536c6044f8f5d8eaddcbb8032e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,8 @@
+# Editor
+.idea
+.vscode
+.vs
+
# Logs
logs
*.log
diff --git a/README.md b/README.md
index ae71176773da47971ec495f37ca3bde5d379217d..0be2ea46eb4e795a481a88721f378b6c4012d1ec 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 162e0c90439b7051c666b4382ea179ac55e999e5..57cc8d9725576ba35bc350ec9ce32e330e5e5020 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/App.vue b/example/App.vue
new file mode 100644
index 0000000000000000000000000000000000000000..f1024453ebbc49e4dedec399c673d13b43489a96
--- /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 0000000000000000000000000000000000000000..4af7e546eba1f0b245c7d60a1c004b6a6765aafe
--- /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 0000000000000000000000000000000000000000..3f183174242c22344a3dd18719768ee4c790c67f
--- /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 0000000000000000000000000000000000000000..7cd71a937bc20a07634029dd21166d74b18e256c
--- /dev/null
+++ b/example/pages/CharactersIntro.vue
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+ 查看{{ name }}
+ 返回列表
+
+
+
+
+
+
+
diff --git a/example/pages/Home.vue b/example/pages/Home.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c42a2b41b1ce328a355c83e035d87c816a6eed05
--- /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 0000000000000000000000000000000000000000..0624fd5674ec07c5132edefac0593f08978b04b3
--- /dev/null
+++ b/example/pages/article/ArticlePage.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+ Hello VuePageStack!
+
+ 不要抱怨生活给予了太多的磨难,不必抱怨生命中有太多的曲折。把每—次的失败都归结为一次尝试,不去自卑;把每一次的成功都想象成一种幸运,不去自傲。
+ 就这样,微笑着弹奏从容的弦乐,去面对挫折,去接受幸福,去品味孤独,去战胜忧伤。微笑面对生活带给我们的一切。
+
+ 路是脚踏出来的,历史是人写出来的。人的每一步行动都在书写自己的历史。
+
+
+
+
+
+
+
+
+
diff --git a/example/pages/article/List.vue b/example/pages/article/List.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1f9638c7bf28d0184ca91dedc88d9888f207dadc
--- /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 0000000000000000000000000000000000000000..042b187178b47f51ce8af2df97a8e410264e6d14
--- /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 440de7bddf242c932a9af0bf8a21e09daf9722c4..e7b9808b372c3fee2fdbb07b02ea0cfbfd98af04 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 87f39dbf4a8e40e7b95856e3e1d7fa29a4cfc13d..c6dc11e38ca9db691f874600ded92cb3e5a6ad82 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 4d1d8565f6ade83e973550f31b316d56d2d2124c..2eaa8eb11c0addfdbb4db5694eb1abe0ef0e4ed2 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 0f25484d6de3c1e95c0d5241ca9d5806b173081b..076068a8d79e89171a0304026593984c34fdac1c 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 a781440053c6a51c2c9dd48975465c4e8139ba15..5416b8b408313ed0528c4badfd81eada76a62eca 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/vue.config.js b/vue.config.js
index 9caf12e76cffe59c81174ea01a2ccfb1cc8f0632..ebb5891684ae1265d46276e87d8c457d5cee2b14 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,6 +1,6 @@
module.exports = {
- css: {
- extract: false
+ css: {
+ extract: false
},
productionSourceMap: true,
configureWebpack: {
diff --git a/yarn.lock b/yarn.lock
index 4b65ffe8bc4f7d343bd7a3e03ac94afbc8a8776b..fc71b0ed4a2f74d53ff0a93a2de3a876ef25212c 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==