小猿圈HTML5学习之基于iview的router常用控制方式

对于互联网发展的今天,IT行业慢慢变成大多数年轻人发展的目标,不仅前景好,薪资也是越来越高的,而web前端是行业中需要的技术,也促进了大多数朋友在学习html5,今天小猿圈讲师给你分享基于iview的router常用控制方式,在学的过程中不浪费时间少走弯路。

1、iview的router控制需求

最近在使用iview框架写项目,遇到了一些路由控制上的问题,解决过程中也有一些心得,故在此记录下来.

每个项目在开发时,对于类似tags(标签页)的控制需求都不尽相同,故以下先列出本文所述项目对标签页的控制要求(如有不同需求,本文当也可提供一些思路):

对于同名(name)的路由标签页,不能打开多个.譬如说从商品列表中打开商品展示标签页,如果已经有在打开的商品编辑页面,则替换之.新打开的,未保存,已保存的标签页,同时只能存在一个(即不同params相同name的route只能有一个);

替换掉一个新的页面时,通过切换的方式切换回来(先切到其他标签页再切换回来),仍是原来页面的内容(即实际记录的params在替换后应变化).类似的情况,还应包含单据从未保存到已保存,以及保存并新增功能;

2、基于vue的router控制

iview是基于vue的框架,故vue本身自带的router控制方法是必然可行的.

vue变更路由的常用方式参考以下(该方法在官方api中有更详细的介绍):

//变更当前路由(有历史记录,建议使用此方式)

this.$router.push({

  name:'routerName',

  params:routerParam

})

//变更当前路由(无历史记录)

this.$router.replace({

  name:'routerName',

  routerParam

})

官方路由变更确实可以正常打开标签页,但在实现1中所提到的各种需求的时候,就有些不满足需求了.为此,需要参考3中,如何基于iview的outer控制.

3、基于iview的router控制

iview在控制路由的时候,使用vuex中的app.js来记录标签页路由信息,如果对vuex还是很了解的话,可以通过这篇博文来先打一下基础.

3.1如何实现需求1.1

想要实现不同params相同name的route在iview中只能有一个,关键是改变iview对路由相等的判断方法,即'/src/libs/util.js'里的routeEqual方法:

/**

* @description 根据name/params/query判断两个路由对象是否相等

* @param {*} route1 路由对象

* @param {*} route2 路由对象

*/

export const routeEqual = (route1, route2) => {

return route1.name === route2.name

// 此处改变相同路由的判断方式,改为name相同即认为相同

// 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)

}

这里稍微解释下(如果不关注原因,可以直接看3.2).当改变路由时,'src\components\main\main.vue'作为近乎顶层的组件控制着近乎所有的全局逻辑,其中就有对路由的监控:

...

<side-menu

accordion

ref="sideMenu"

:active-name="$route.name"

:collapsed="collapsed"

@on-select="turnToPage"

:menu-list="menuList"

>

...

  //此方法隶属于methods,用以监控side-menu的选择事件,即平时从左侧菜单打开标签页的逻辑

  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,

    params,

    query

  })

  },

...

watch: {

  // 检测route的变化

  $route (newRoute) {

  const { name, query, params, meta } = newRoute

  this.addTag({

    route: { name, query, params, meta },

    type: 'push'

  })

  this.setBreadCrumb(newRoute)

  this.setTagNavList(getNewTagList(this.tagNavList, newRoute))

  this.$refs.sideMenu.updateOpenName(newRoute.name)

  }

},

...

从以上代码可推测出,main.vue通过turnToPage方法实现打开标签页的逻辑,但方法内部并没有体现便签页显示效果变化(包含内部数据变化,以下同)的逻辑,这是由于显示效果变化的逻辑,由对$router的监控实现.

这样,不止从左侧菜单打开新标签页可以实现显示变化效果,其他只要使用vue的原版push等方法改变router的方法,均可监测到.

逐步查看下各个方法,其中影响当前标签页显示效果的,是'src/store/module/app.js'的addTag方法.

addTag (state, { route, type = 'unshift' }) {

let router = getRouteTitleHandled(route)

if (!routeHasExist(state.tagNavList, router)) {

  if (type === 'push') state.tagNavList.push(router)

  else {

  if (router.name === homeName) state.tagNavList.unshift(router)

  else state.tagNavList.splice(1, 0, router)

  }

  setTagNavListInLocalstorage([...state.tagNavList])

}

},

尽管方法内部仍调用了很多,其中一个很重要的判断,就是routeHasExist(路由是否存在),这个方法也是判断是否为相同标签页的一个关键节点(该方法同样在util.js):

/**

* 判断打开的标签列表里是否已存在这个新添加的路由对象

*/

export const routeHasExist = (tagNavList, routeItem) => {

let len = tagNavList.length

let res = false

doCustomTimes(len, (index) => {

  if (routeEqual(tagNavList[index], routeItem)) res = true

})

return res

}

明显可以看出,这个方法内调用routeEqual,就是用以判断是否为相同路由的实际方法(当然是通过比较新路由与已有路由进行比较),如此,仅需改变routeEqual即可.

以防万一,全局搜索下调用这个routeEqual的所有方法,发现所有调用的地方再routeEqual在改变后不会出现新的问题.

3.2如何实现需求1.2

在进行3.1的操作后,问题得到了部分解决.余下的问题在于需求1.2没有得到实现和解决.

首先是,如何实现从列表中打开或新建的,替换原来的标签页,在来回切换后不会回到原来的标签页.只需在app.js中注册改变标签页参数的方法:

// 变更指定路由的参数

changeTagParams (state, route) {

let routeOldIndex = state.tagNavList.findIndex(m => routeEqual(m, route))

if (routeOldIndex !== -1) {

  let routeOld = state.tagNavList[routeOldIndex]

  routeOld.params = route.params

  state.tagNavList.splice(routeOldIndex, 1, routeOld)

  setTagNavListInLocalstorage([...state.tagNavList])

}

},

然后在main.vue中对$route的监控最后引用即可.

watch: {

  // 检测route的变化

  $route (newRoute) {

  const { name, query, params, meta } = newRoute

  this.addTag({

    route: { name, query, params, meta },

    type: 'push'

  })

  this.setBreadCrumb(newRoute)

  this.setTagNavList(getNewTagList(this.tagNavList, newRoute))

  this.$refs.sideMenu.updateOpenName(newRoute.name)

  // 增加路由参数变更环节

  this.changeTagParams(newRoute)

  }

},

其次,如果出现像保存并新增,或者从未保存到已保存,这两种情况来回切换后不会回到原来的情况.

保存并新增,关键是"新增"效果:

// 清空数据,该方法在保存后调用

clearData () {

//该部分是用来清除当前route的参数

this.$router.push({

  params: Object.assign(this.$route.params, { id: undefined })

})

//这部分代码是用来清空当前页面内容,每个模块都不尽相同,不必模仿

this.mOtherExpense = JSON.parse(JSON.stringify(this.mOtherExpenseInitial))

this.tableData = [{}]

this.loadCode()

this.mOtherExpense.openingDate = new Date()

},

从未保存到已保存,关键同样是如何让route记住新的id(或其他参数):

// 设置路由id,该方法在第一次保存后调用

setData (id) {

//这里的id是保存后从后台传来的新id

this.$router.push({

  params: Object.assign(this.$route.params, { id })

})

}

文中已将本人常用的iviewrouter控制方式提出,或有未涉及者,根据以下了解大概也可解决:

app.js中的state.tagNavList是标签页中显示的标签集合;如果要改变一些内容,main.vue中对$route的监控是事件发起的开端,可考虑从这里修改;

以上就是小猿圈web前端讲师对于基于iview的router常用控制方式的介绍,记住一定要练习,多学多看多练这才是学习一门新技术好的开始,如果没有系统的视频可以观看小猿圈,里面有更完善更全的视频。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容