Browse Source

抽离util公共方法

zhaihaoyi 6 years ago
parent
commit
cb6412a015

+ 15 - 9
README.md

@@ -1,20 +1,26 @@
 # Vue Router Tab
 
+<!-- <p align="center">
+  <a href="https://npmcharts.com/compare/vue-router-tab?minimal=true"><img src="https://img.shields.io/npm/dm/vue-router-tab.svg" alt="Downloads"></a>
+  <a href="https://www.npmjs.com/package/vue-router-tab"><img src="https://img.shields.io/npm/v/vue-router-tab.svg" alt="Version"></a>
+  <a href="https://www.npmjs.com/package/vue-router-tab"><img src="https://img.shields.io/npm/l/vue-router-tab.svg" alt="License"></a>
+</p> -->
+
 Vue Router Tab 是基于 `Vue Router` 的路由页签组件。
 
 > 由于 Vue 内置的 `<keep-alive>` 只能根据组件的 `name` 来缓存页面,难以实现同一个组件对应多个页签的缓存,本组件定制了 `<router-alive>` 缓存组件
 
 ## 功能
 
-- [x] 根据路由变化新增或切换页签,不同的页签缓存独立的页面
-- [x] 页签关闭和刷新,支持右键操作菜单批量操作
+- [x] 响应路由变化新增或切换页签,不同的页签缓存独立的页面
+- [x] 页签关闭和刷新,右键菜单批量操作
 - [x] [全局](#alive-key)和[针对特定路由](#meta.aliveKey)的页签缓存规则配置
-- [x] [配置初始展示页签](#tabs),页签可设置为不可关闭
-- [x] [页签和页面过渡效果配置 (已内置过渡效果)](#tab-transition)
-- [x] [自定义页签模板](#自定义页签模板)
+- [x] [初始展示页签](#tabs),页签可设置为不可关闭
+- [x] [内置页签和页面过渡效果,支持自定义配置](#tab-transition)
+- [x] [自定义页签模板](#自定义页签模板)
 - [x] [动态更新页签信息 (标题/图标/提示)](#动态更新页签信息)
 - [x] [路由页面离开 (页签关闭/刷新/替换) 前确认](#路由页面离开前确认)
-- [x] 国际化:zh-CN (默认) / en
+- [x] [国际化](#i18n):zh-CN (默认) / en,自定义语言
 
 ---
 
@@ -24,7 +30,7 @@ Vue Router Tab 是基于 `Vue Router` 的路由页签组件。
 
 ``` bash
 # npm
-npm install vue-router-tab -S
+npm i vue-router-tab -S
 
 # yarn
 yarn add vue-router-tab
@@ -43,7 +49,7 @@ import Router from 'vue-router'
 import RouterTab from 'vue-router-tab'
 import 'vue-router-tab/dist/lib/vue-router-tab.css'
 
-Vue.use(RouterTab)
+vue-router-tab.use(RouterTab)
 ```
 
 Template:
@@ -217,7 +223,7 @@ export default {
 }`
 
 
-### 自定义页签模板
+### 自定义页签模板
 
 ``` html
 <router-tab>

+ 2 - 51
src/lib/RouterTab/components/RouterAlive.js

@@ -1,46 +1,4 @@
-// 空对象和数组
-export const emptyObj = Object.create(null)
-export const emptyArray = []
-
-function isDef (v) {
-  return v !== undefined && v !== null
-}
-
-function getFirstComponentChild (children) {
-  if (Array.isArray(children)) {
-    for (let i = 0; i < children.length; i++) {
-      const c = children[i]
-      if (
-        isDef(c) &&
-        (isDef(c.componentOptions) || isAsyncPlaceholder(c))
-      ) {
-        return c
-      }
-    }
-  }
-}
-
-function isAsyncPlaceholder (node) {
-  return node.isComment && node.asyncFactory
-}
-
-// 获取路由不带hash的路径
-const getPathWithoutHash = route => route.hash
-  ? route.fullPath.replace(route.hash, '')
-  : route.fullPath
-
-// 是否相似路由
-export const isAlikeRoute = function isAlikeRoute (route1, route2) {
-  return getPathWithoutHash(route1) === getPathWithoutHash(route2)
-}
-
-// 获取路由页面组件
-const getRouteComponent = ({ matched }) => matched[matched.length - 1].components.default
-
-// 路由是否共用组件
-function isSameComponentRoute (route1, route2) {
-  return getRouteComponent(route1) === getRouteComponent(route2)
-}
+import { emptyObj, getAliveKey, getFirstComponentChild, isAlikeRoute, isSameComponentRoute } from '../util'
 
 export default {
   name: 'router-alive',
@@ -121,14 +79,7 @@ export default {
   },
 
   methods: {
-    // 获取缓存key
-    getAliveKey (route = this.$route) {
-      let aliveKey = (route.meta && route.meta.aliveKey) || this.aliveKey || 'path'
-      if (typeof aliveKey === 'function') {
-        return aliveKey.bind(this)(route)
-      }
-      return route[aliveKey]
-    },
+    getAliveKey,
 
     // 设置缓存项
     set (key, item) {

+ 3 - 35
src/lib/RouterTab/components/RouterTab.js

@@ -1,39 +1,7 @@
 import Vue from 'vue'
-import RouterAlive, { isAlikeRoute, emptyObj, emptyArray } from './RouterAlive'
+import RouterAlive from './RouterAlive'
 import langs from '../lang'
-
-// 滚动
-function scrollTo ($el, left = 0, top = 0) {
-  if ($el.scrollTo) {
-    $el.scrollTo({ left, top, behavior: 'smooth' })
-  } else {
-    $el.scrollLeft = left
-    $el.scrollTop = top
-  }
-}
-
-// 防抖
-function debounce (fn, delay = 200) {
-  let timeout = null
-  return function () {
-    let context = this
-    let args = arguments
-    clearTimeout(timeout)
-    timeout = setTimeout(() => {
-      fn.call(context, args)
-    }, delay)
-  }
-}
-
-// 队列执行promise
-function promiseQueue (promises, isFinally = true) {
-  let queue = Promise.resolve()
-  const type = isFinally ? 'finally' : 'then'
-  for (let item of promises) {
-    queue = queue[type](item)
-  }
-  return queue
-}
+import { emptyObj, emptyArray, scrollTo, debounce, promiseQueue, getAliveKey, isAlikeRoute } from '../util'
 
 export default {
   name: 'router-tab',
@@ -203,7 +171,7 @@ export default {
   },
 
   methods: {
-    getAliveKey: RouterAlive.methods.getAliveKey,
+    getAliveKey,
 
     // 页面离开导航守卫
     routerPageLeaveGuard (to, from, next) {

+ 100 - 0
src/lib/RouterTab/util.js

@@ -0,0 +1,100 @@
+// 空对象和数组
+export const emptyObj = Object.create(null)
+export const emptyArray = []
+
+// 是否定义
+export function isDef (v) {
+  return v !== undefined && v !== null
+}
+
+// 防抖
+export function debounce (fn, delay = 200) {
+  let timeout = null
+  return function () {
+    let context = this
+    let args = arguments
+    clearTimeout(timeout)
+    timeout = setTimeout(() => {
+      fn.call(context, args)
+    }, delay)
+  }
+}
+
+// 队列执行promise
+export function promiseQueue (promises, isFinally = true) {
+  let queue = Promise.resolve()
+  const type = isFinally ? 'finally' : 'then'
+  for (let item of promises) {
+    queue = queue[type](item)
+  }
+  return queue
+}
+
+// 滚动
+export function scrollTo ($el, left = 0, top = 0) {
+  if ($el.scrollTo) {
+    $el.scrollTo({
+      left,
+      top,
+      behavior: 'smooth'
+    })
+  } else {
+    $el.scrollLeft = left
+    $el.scrollTop = top
+  }
+}
+
+/* 组件方法 */
+
+// 获取第一个子组件
+export function getFirstComponentChild (children) {
+  if (Array.isArray(children)) {
+    for (let i = 0; i < children.length; i++) {
+      const c = children[i]
+      if (
+        isDef(c) &&
+        (isDef(c.componentOptions) || isAsyncPlaceholder(c))
+      ) {
+        return c
+      }
+    }
+  }
+}
+
+// 获取缓存key
+export function getAliveKey (route = this.$route) {
+  let aliveKey = (route.meta && route.meta.aliveKey) || this.aliveKey || 'path'
+  if (typeof aliveKey === 'function') {
+    return aliveKey.bind(this)(route)
+  }
+  return route[aliveKey]
+}
+
+/* 路由方法 */
+
+// 是否异步占位
+export function isAsyncPlaceholder (node) {
+  return node.isComment && node.asyncFactory
+}
+
+// 获取路由不带hash的路径
+export function getPathWithoutHash (route) {
+  return route.hash
+    ? route.fullPath.replace(route.hash, '')
+    : route.fullPath
+}
+
+// 是否相似路由
+export function isAlikeRoute (route1, route2) {
+  return getPathWithoutHash(route1) === getPathWithoutHash(route2)
+}
+
+// 获取路由页面组件
+export function getRouteComponent ({ matched }) {
+  return matched[matched.length - 1].components.default
+}
+
+// 路由是否共用组件
+export function isSameComponentRoute (route1, route2) {
+  return getRouteComponent(route1) === getRouteComponent(route2)
+}