最近在写项目时,用到了 amazeui 最为国内数一数二的框架,也免不了在使用时出现一些问题
问题的出现
在用 amazeui 时,出现了一个状况, 那就是在跳转到子路由时, 新页面的事件失效了。
问题大概是这样的:
正常点击完成 触发事件的结果应该是这样的 :
点击消息,出现下拉框。
而在跳转子路由后,是这样的:
事件失效了
类似的还有:
下拉框正常应该是这样的
但下拉框失效是这样的
而在刷新后,下拉框和事件才会显示正常。
简单分析
不妨对这个问题进行简单分析。
首先写一个正常的 html 文件,在浏览器里面看一下。
这样一看,很正常的一个 select 下拉组件。
然而事件并非这么简单…
我们右键审查元素,控制台中查看一下是这样的:
这才是问题,
select 标签被自动添加了一个display: none;
select 标签并不是 select 了
我们用到的是另一个 div。
可我们在写代码时可是这样写的:
<select data-am-selected><option value="a">Apple</option><option value="b" selected>Banana</option><option value="o">Orange</option><option value="m">Mango</option><option value="d" disabled>禁用鸟</option></select>
可为啥就变成这样了呢 ?
我们不妨把 select 的display: none;
属性去,结果变成了这样:
正是 vue 跳转后的 下拉框。
我们再去看一下 vue 渲染失效的标签的具体信息:
而成功的是这样的:
很显然,css 的属性计算没有成功,既然css 如此,js 也是一样。
通常在我们写js 的代码的时候都会加入
window.onload()
再onload 函数中写代码,这样做的意义就是能够在文档加载完成之后才执行js 代码。
而在用 jquery 时, 通常用的是 $(function () {}) 这样写的作用和onload 函数差不多,都是在文档加载完成之后自动执行。
问题出现了:
这就导致了函数的执行条件是文档加载完成时才会触发函数。
而在 vue 中,为了节省资源,vue-router 在跳转页面时,实际上是不跳转页面的,而仅仅是在原页面上改变一些内容,所以说,在 vue 中, 跳转到子路由,页面是不会刷新的,也就是说,onload的条件没有被触发。
而 amazeui 是基于jquery 的,jQuery 的 $(function () {}) 也是一样,在跳转到子路由时, 并没有刷新页面,也就是没有加载 amaze.min.js 的函数。
其实在模板里面, 也能看到一个现象,在刷新页面时,也能看到一闪而过的一个 大的
显然,amazeui 把select 重写了,但是并没有将原生的 select 标签改变,而是将其隐藏,
狸猫换太子,将一个新的 div 放在原来的 select 标签位置, 而在其中起重要作用的就是 js
但是 js 文件并没有重新加载,就导致了 select 标签并没有被替换成新的 select 控件。
解决方案
我所想到的解决方案目前有两种:
第一种方法:
在充当导航的组件中添加一个 method ,使router 在跳转子路由时, 刷新页面。
简单实现:
首先在充当导航跳转组件的 methods 里增加一个函数:
this.$router.go(0) 的意思是刷新页面。
然后在跳转的 router-link 标签上绑定事件函数:
这样, 在页面跳转之后,会刷新页面,页面内的外部资源重新加载,成功渲染。
第二种方法:
通过钩子函数 mounted ,在页面加载完成之后加载新的外部文件,
大概是这样:
对dom 进行操作,增加一个新的 script 标签,再次引入外部 文件。