iview-admin之showTitle改造与useI18n

iview-admin之showTitle与useI18n

越来越被自己的无知征服,写了这么长时间的iview-admin竟然不知道useI18n的用途,为什么要说这个呢?还是源于一个需求,就是不同的模块有相同的功能项,比如说个人中心和流程管理里面都有我的流程这个子页面,这时点击任何一个我的流程菜单项都会跳转到位置靠前的路由里面,后面的不会跳转,这是为什么呢?看到这你肯定会说这不合理啊,菜单的名字虽然相同但是对应的跳转路由应该不同啊?是啊,我也是这么想的,因为是从别人手里接受的项目,所以就沿用之前人的写法,而之前人的useI18n设置的是true,这种设置会导致什么结果呢?嗯,没错,会导致你的菜单显示的名字大概率会是你router.js里面的name属性的值(为什么说是大概率呢,后面揭晓),而这个值就是路由跳转的标识,所以就出现了之前的那种状况,即使你的meta.title设置了也不会显示,这也是我纳闷的地方,这种情况我早就发现了,但是原来没有这种同名子菜单的情况,所以就把他给忽略了(按理说name应该起个英文名,但我为了显示中文,苟且的给这个name属性值全都赋了中文值),如今不得不把他给解决掉,在写了一下午bug后兜兜转转的发现了useI18n的秘密,也算是没瞎干一场。

你肯定会问我:干了一下午都干什么了呢?嗯,我告诉你,我是怎么干的,你可不许笑话我,既然meta里的title不好使,那我索性就把每个路由加上一个title属性,赋成中文值,也就是之前name里的值,再把name属性赋了唯一的英文名,像这样

 
/*router.js*/
{path: 'split_pane_page',name: 'split_pane_page',title:'分割窗口'meta: {icon: 'md-pause',title: '分割窗口'},component: () => import('@/view/components/split-pane/split-pane.vue')},

用来做路由标识然后把showtitle方法做了个改造(改造方法放后面),稀里糊涂的改了好长时间也就是在这个过程中对这个useI18n产生了兴趣,于是仔细地读了一下代码,并发现了useI18n的秘密。

这个useI18n到底是干什么的呢?,其实原来我原来看过这个东东,在这个地方@/config/index.js

 * @description 是否使用国际化,默认为false*              如果不使用,则需要在路由中给需要在菜单中展示的路由设置meta: {title: 'xxx'}*              用来在菜单中显示文字*/useI18n: true,

我一看国际化三个字就直接绕过了,这三个字和我实在没什么关系,但实际上却是大有关系,注释里只是说用来在菜单里显示文字,这里说的很笼统只说了如果设置了false就需要设置meta里的title,而且也没说不设置会怎样(会显示name里的文字),也没说设置为true之后会怎样,只给出了三个字‘国际化’,(大概率还是菜单里显示name里的文字,后面揭晓原因)呵呵。那这个useI18n是怎么决定菜单文字显示的呢,没错就是这个showTitle

现在让我们来好好的看一下这个showTitle,让真相彻底大白吧

之前为什么说设置为true大概率会显示name里的文字,看我手写的true下面的前两个if,第一个

  if (title.includes('{{') && title.includes('}}') && useI18n)

这种情况对应的是

  {path: 'i18n_page',name: 'i18n_page',meta: {icon: 'md-planet',title: 'i18n - {{ i18n_page }}'},component: () => import('@/view/i18n/i18n-page.vue')}

meta里的title是一个带插值的字符串的情况然后执行这个

title = title.replace(/({{[\s\S]+?}})/, (m, str) => str.replace(/{{([\s\S]*)}}/, (m, _) => vm.$t(_.trim())))

用这个$t来实现国际化也就是语言的切换
 

第二个

  else if (__titleIsFunction__) title = item.meta.title

这种情况对应的是

  {path: 'params/:id',name: 'params',meta: {icon: 'md-flower',title: route => `{{ params }}-${route.params.id}`,notCache: true,beforeCloseName: 'before_close_normal'},component: () => import('@/view/argu-page/params.vue')},

title是一个函数的运算结果

也就是路由传参的情况,

以上这两种很少用到,所以我说是大概率会是下面这种

 else title = vm.$t(item.name)
也就造成了菜单显示文字和路由的名字混而为一的情况

再看false这种情况

 else title = (item.meta && item.meta.title) || item.name

熟悉js的同学应该能看懂(我就不解释了,看不懂的去看一下js逻辑运算中的短路相关知识点)

如果存在meta和meta.title的话就显示meta.title里的文字,否则显示name里的文字

也就是说我的需求到这就可以实现了,那为什么还要改造呢?

再说回我的改造过程,如果只给路由添加title属性(我自己加的那个name下面的title,不是meta里的)是没用的还需要改一个地方@/libs/util.js


export const getMenuByRouter = (list, access) => {let res = []forEach(list, item => {if (!item.meta || (item.meta && !item.meta.hideInMenu)) {let obj = {icon: (item.meta && item.meta.icon) || '',name: item.name,meta: item.meta,//我添加的title:item.title}if ((hasChild(item) || (item.meta && item.meta.showAlways)) && showThisMenuEle(item, access)) {obj.children = getMenuByRouter(item.children, access)}if (item.meta && item.meta.href) obj.href = item.meta.hrefif (showThisMenuEle(item, access)) res.push(obj)}})return res
}

故名思意,这个方法是用来生成菜单的,通过谁生成呢,通过Router,所以要再把title引出去,看到这你肯定会说你这不是脱了那啥那啥吗?人家meta里的title已经可以用来做菜单显示文字了,你这简直是多此一举。是的,但是你忽略了一点,就是这个showTitle不仅用来生成菜单的文字,还有其他两个用途------windows标签和导航栏里的标签

菜单因为有父级菜单所以相同的子菜单不会造成混淆,但是标签是没有父级标签的,(如果不看面包屑的话)

所以我这种改造方法真正的意义在这里-----就是让标签和菜单里的文字不同,如何做到呢?还是继续看代码

看菜单模块

/*side-Menu-item*/

 

/*side-Menu*/

你看显示什么其实靠的就是showTitle,所以我的方法其实就是加一个showTItlemine方法只不过show的是我加的这个title,把这两个模块里的所有showTitle替换成showTItlemine方法

export const showTitlemine = (item, vm) => {let { title, __titleIsFunction__ } = item.metaif (!title) returnif (useI18n) {if (title.includes('{{') && title.includes('}}') && useI18n) title = title.replace(/({{[\s\S]+?}})/, (m, str) => str.replace(/{{([\s\S]*)}}/, (m, _) => vm.$t(_.trim())))else if (__titleIsFunction__) title = item.meta.title//else title = vm.$t(item.name)改成else title = vm.$t(item.Title)//} else title = (item.meta && item.meta.title) || item.name改成} else title = (item.meta && item.meta.title) || item.title
return title
}

这样就达到了增加一个显示的目的(不影响windows标签和导航栏标签)。(以上纯属个人行为请勿模仿,如有闪失概不负责)


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部