This commit is contained in:
zhigang.li 2018-08-17 16:06:48 +08:00
commit a129472828
9 changed files with 263 additions and 35 deletions

View File

@ -187,3 +187,29 @@ export const off = (function () {
}
}
})()
/**
* 判断一个对象是否存在key如果传入第二个参数key则是判断这个obj对象是否存在key这个属性
* 如果没有传入key这个参数则判断obj对象是否有键值对
*/
export const hasKey = (obj, key) => {
if (key) return key in obj
else {
let keysArr = Object.keys(obj)
return keysArr.length
}
}
/**
* @param {*} obj1 对象
* @param {*} obj2 对象
* @description 判断两个对象是否相等这两个对象的值只能是数字或字符串
*/
export const objEqual = (obj1, obj2) => {
const keysArr1 = Object.keys(obj1)
const keysArr2 = Object.keys(obj2)
if (keysArr1.length !== keysArr2.length) return false
else if (keysArr1.length === 0 && keysArr2.length === 0) return true
/* eslint-disable-next-line */
else return !keysArr1.some(key => obj1[key] != obj2[key])
}

View File

@ -1,7 +1,7 @@
import Cookies from 'js-cookie'
// cookie保存的天数
import config from '@/config'
import { forEach, hasOneOf } from '@/libs/tools'
import { forEach, hasOneOf, objEqual } from '@/libs/tools'
export const TOKEN_KEY = 'token'
@ -166,14 +166,18 @@ export const getParams = url => {
* @param {Array} list 标签列表
* @param {String} name 当前关闭的标签的name
*/
export const getNextName = (list, name) => {
let res = ''
export const getNextRoute = (list, route) => {
console.log(list, route)
let res = {}
if (list.length === 2) {
res = 'home'
} else {
if (list.findIndex(item => item.name === name) === list.length - 1) res = list[list.length - 2].name
else res = list[list.findIndex(item => item.name === name) + 1].name
console.log(list.findIndex(item => routeEqual(item, route)), list.length)
const index = list.findIndex(item => routeEqual(item, route))
if (index === list.length - 1) res = list[list.length - 2]
else res = list[index + 1]
}
console.log(res)
return res
}
@ -184,7 +188,7 @@ export const getNextName = (list, name) => {
export const doCustomTimes = (times, callback) => {
let i = -1
while (++i < times) {
callback()
callback(i)
}
}
@ -270,3 +274,28 @@ export const findNodeDownward = (ele, tag) => {
export const showByAccess = (access, canViewAccess) => {
return hasOneOf(canViewAccess, access)
}
/**
* @description 根据name/params/query判断两个路由对象是否相等
* @param {*} route1 路由对象
* @param {*} route2 路由对象
*/
export const routeEqual = (route1, route2) => {
const params1 = route1.params || {}
const params2 = route2.params || {}
const query1 = route1.query || {}
const query2 = route2.query || {}
return (route1.name === route2.name) && objEqual(params1, params2) && objEqual(query1, query2)
}
/**
* 判断打开的标签列表里是否已存在这个新添加的路由对象
*/
export const routeHasExist = (tagNavList, routeItem) => {
let len = tagNavList.length
let res = false
doCustomTimes(len, (index) => {
if (routeEqual(tagNavList[index], routeItem)) res = true
})
return res
}

View File

@ -191,6 +191,25 @@ export default [
}
]
},
{
path: '/tools_methods',
name: 'tools_methods',
meta: {
hide: true
},
component: Main,
children: [
{
path: 'tools_methods_page',
name: 'tools_methods_page',
meta: {
icon: 'ios-hammer',
title: '工具方法'
},
component: () => import('@/view/tools-methods/tools-methods.vue')
}
]
},
{
path: '/directive',
name: 'directive',
@ -261,6 +280,34 @@ export default [
},
]
},
{
path: '/argu',
name: 'argu',
meta: {
hideInMenu: true
},
component: Main,
children: [
{
path: 'params/:id',
name: 'params',
meta: {
icon: 'md-flower',
title: '动态路由'
},
component: () => import('@/view/argu-page/params.vue')
},
{
path: 'query',
name: 'query',
meta: {
icon: 'md-flower',
title: '带参路由'
},
component: () => import('@/view/argu-page/query.vue')
}
]
},
{
path: '/401',
name: 'error_401',

View File

@ -1,4 +1,4 @@
import { getBreadCrumbList, setTagNavListInLocalstorage, getMenuByRouter, getTagNavListFromLocalstorage, getHomeRoute } from '@/libs/util'
import { getBreadCrumbList, setTagNavListInLocalstorage, getMenuByRouter, getTagNavListFromLocalstorage, getHomeRoute, routeHasExist } from '@/libs/util'
import routers from '@/router/routers'
export default {
state: {
@ -20,10 +20,13 @@ export default {
setTagNavListInLocalstorage([...list])
} else state.tagNavList = getTagNavListFromLocalstorage()
},
addTag (state, item, type = 'unshift') {
if (state.tagNavList.findIndex(tag => tag.name === item.name) < 0) {
if (type === 'push') state.tagNavList.push(item)
else state.tagNavList.unshift(item)
addTag (state, { route, type = 'unshift' }) {
if (!routeHasExist(state.tagNavList, route)) {
if (type === 'push') state.tagNavList.push(route)
else {
if (route.name === 'home') state.tagNavList.unshift(route)
else state.tagNavList.splice(1, 0, route)
}
setTagNavListInLocalstorage([...state.tagNavList])
}
},

View File

@ -0,0 +1,17 @@
<template>
<div>
<Card>
<h2>ID: {{ $route.params.id }}</h2>
</Card>
</div>
</template>
<script>
export default {
name: 'argu_page'
}
</script>
<style>
</style>

View File

@ -0,0 +1,17 @@
<template>
<div>
<Card>
<h2>ID: {{ $route.query.id }}</h2>
</Card>
</div>
</template>
<script>
export default {
name: 'query'
}
</script>
<style>
</style>

View File

@ -26,14 +26,14 @@
<transition-group name="taglist-moving-animation">
<Tag
type="dot"
v-for="item in list"
v-for="(item, index) in list"
ref="tagsPageOpened"
:key="`tag-nav-${item.name}`"
:key="`tag-nav-${index}`"
:name="item.name"
@on-close="handleClose"
@on-close="handleClose(item)"
@click.native="handleClick(item)"
:closable="item.name !== 'home'"
:color="item.name === value.name ? 'primary' : 'default'"
:color="isCurrentTag(item) ? 'primary' : 'default'"
>{{ showTitleInside(item) }}</Tag>
</transition-group>
</div>
@ -42,7 +42,7 @@
</template>
<script>
import { showTitle } from '@/libs/util'
import { showTitle, routeEqual } from '@/libs/util'
export default {
name: 'TagsNav',
props: {
@ -61,6 +61,12 @@ export default {
outerPadding: 4
}
},
computed: {
currentRouteObj () {
const { name, params, query } = this.value
return { name, params, query }
}
},
methods: {
handlescroll (e) {
var type = e.type
@ -94,20 +100,16 @@ export default {
this.$emit('on-close', res, 'all')
} else {
// home
let currentName = ''
let res = this.list.filter(item => {
if (item.name === this.value.name) currentName = item.name
return item.name === this.value.name || item.name === 'home'
})
let res = this.list.filter(item => routeEqual(this.currentRouteObj, item) || item.name === 'home')
this.$emit('on-close', res, 'others')
setTimeout(() => {
this.getTagElementByName(currentName)
this.getTagElementByName(this.currentRouteObj.name)
}, 100)
}
},
handleClose (e, name) {
let res = this.list.filter(item => item.name !== name)
this.$emit('on-close', res, undefined, name)
handleClose (item) {
let res = this.list.filter(item => !routeEqual(this.currentRouteObj, item))
this.$emit('on-close', res, undefined, item)
},
handleClick (item) {
this.$emit('input', item)
@ -115,6 +117,9 @@ export default {
showTitleInside (item) {
return showTitle(item, this)
},
isCurrentTag (item) {
return routeEqual(this.currentRouteObj, item)
},
moveToView (tag) {
const outerWidth = this.$refs.scrollOuter.offsetWidth
const bodyWidth = this.$refs.scrollBody.offsetWidth

View File

@ -40,7 +40,7 @@ import User from './components/user'
import Fullscreen from './components/fullscreen'
import Language from './components/language'
import { mapMutations, mapActions } from 'vuex'
import { getNewTagList, getNextName } from '@/libs/util'
import { getNewTagList, getNextRoute, routeEqual } from '@/libs/util'
import minLogo from '@/assets/images/logo-min.jpg'
import maxLogo from '@/assets/images/logo.jpg'
import './main.less'
@ -92,33 +92,41 @@ export default {
...mapActions([
'handleLogin'
]),
turnToPage (name) {
turnToPage (route) {
let { name, params, query } = {}
if (typeof route === 'string') name = route
else {
name = route.name
params = route.params
query = route.query
}
if (name.indexOf('isTurnByHref_') > -1) {
window.open(name.split('_')[1])
return
}
this.$router.push({
name: name
name,
params,
query
})
},
handleCollapsedChange (state) {
this.collapsed = state
},
handleCloseTag (res, type, name) {
const nextName = getNextName(this.tagNavList, name)
handleCloseTag (res, type, route) {
this.setTagNavList(res)
let openName = ''
if (type === 'all') {
this.turnToPage('home')
openName = 'home'
} else if (this.$route.name === name) {
this.$router.push({ name: nextName })
openName = nextName
} else if (type === 'other' && routeEqual(this.$route, route)) {
this.$router.push(getNextRoute(this.tagNavList, route))
openName = route.name
}
this.$refs.sideMenu.updateOpenName(openName)
},
handleClick (item) {
this.turnToPage(item.name)
this.turnToPage(item)
}
},
watch: {
@ -132,7 +140,9 @@ export default {
* @description 初始化设置面包屑导航和标签导航
*/
this.setTagNavList()
this.addTag(this.$store.state.app.homeRoute)
this.addTag({
route: this.$store.state.app.homeRoute
})
this.setBreadCrumb(this.$route.matched)
//
this.setLocal(this.$i18n.locale)

View File

@ -0,0 +1,74 @@
<template>
<div>
<Card shadow>
<Row>
<i-col span="4">
<Button @click="createTagParams">添加一个标签</Button>
</i-col>
<i-col span="20">
<p>动态路由添加params</p>
</i-col>
</Row>
</Card>
<Card shadow style="margin-top: 10px;">
<Row>
<i-col span="4">
<Button @click="createTagQuery">添加一个标签</Button>
</i-col>
<i-col span="20">
<p>动态路由添加query</p>
</i-col>
</Row>
</Card>
</div>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
name: 'tools_methods_page',
methods: {
...mapMutations([
'addTag'
]),
createTagParams () {
const id = parseInt(Math.random() * 100000)
const route = {
name: 'params',
params: {
id
},
meta: {
title: `动态路由-${id}`
}
}
this.addTag({
route: route,
type: 'push'
})
this.$router.push(route)
},
createTagQuery () {
const id = parseInt(Math.random() * 100000)
const route = {
name: 'query',
query: {
id
},
meta: {
title: `参数-${id}`
}
}
this.addTag({
route: route,
type: 'push'
})
this.$router.push(route)
}
}
}
</script>
<style>
</style>