注意:使用 element-ui 时, 遇到过 Vue 版本未固定, 小版本升级导致页面出现问题的
原版本 vue 2.7.14 , element-ui": "2.13.0 , 遇到的问题是:
- 升级到 2.7.15 导致 popper 错位
- 升级到 2.7.16 导致 dialog 无法编辑…
只作用于本页面, 甚至不作用于页面引入的组件, 所以想让页面既不影响其他页面, 又能改变组件的样式, 可以使用 深度作用选择器;
iView 框架里的组件的样式无法在 里改, 但是用这个就可以, 当然, 自己写的其他组件也一样;
注意:
-
预处理器有可能不支持 , 可以用 或 代替
搜了下, 关于 和 有几种说法:
- 在某些时候会报错, 更保险并且编译速度更快.
- 针对的是 dart-sass 的 npm 包的, node-sass 用
不知道哪种说法是对的, 我本地项目两个都可以(装的是 node-sass 4.13.1), 出错了的话就换一种试试吧
-
不要在预处理器中嵌套写 /deep/ , 本身这种写法是错误的, 嵌套中的 /deep/ 不会被解析, 大部分客户端做了兼容不会出错, 但苹果不支持 /deep/错误嵌套用法导致的ios移动端真机样式失效问题( >>>、 /deep/、::v-deep)
-
Chrome89 也不再兼容嵌套 /deep/ 了 /deep/的使用与导致样式失效问题处理
-
less 文件里写 /deep/ , @import 它时加上 scoped , 好像可以 scoped , 参见Vue style里面使用scoped属性并@import引入外部css, 作用域是全局的解决方案
使用 方法,这个方法好像是让其内部的函数在 DOM 更新后再调用(具体没查);
有时想刷新一个页面, 常常用这个, 比如先把动态组件置空,然后在此方法中再把此组件还原回去;
使用 刷新组件和页面也是一样;
-
不要在 中使用 请求数据
-
computed 属性为对象数组, 可以直接改对象的属性(v-model 绑定也可以)
1. deep
要监控对象属性的变化,需要使用 , 详见 官方教程
2. val 和 oldVal 一模一样
监控对象时, 和 一模一样,官网上关于这点的解释好像是在 那一部分;
变通方法: 可以直接 watch 对象的某个属性
3. immediate 属性
第一次绑定时是不会执行的, 加上这个 就可以了. 用法: 比如一个 使用了 绑定了父组件某个属性, 那么 ``immediateModalwatch` 到外部传递给它的相关属性.
4. 直接使用函数的字面量名称为 handler
标签包裹组件后,只有第一次加载组件才会触发 生命周期,后面再切换就是 和
- 不同于组件和 prop,事件名不存在任何自动化的大小写转换
- 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),因此,推荐始终使用 kebab-case 的事件名。
1.参考文章:
vue2父子组件间相互通信
Vue 组件通信之 Bus
Vue使用EventBus传递数据的坑
vue组件间通信六种方式(完整版)
2. 注意 eventBus 监听的时机
使用 机制传递数据时,要注意监听事件的时机,不然有可能出现----跳转前的页面发送事件带参数过去时,对方还没来得及绑定监听事件,
举例: 我在跳转后的页面的 里加上了发送 的 事件, 当跳转前的页面接收到此事件才会传参数过去,因为两个页面被 标签包裹,所以也不用担心跳转后发不了事件
3. inheritAttrs, $attrs, $listeners
-
inheritAttrs
所有父组件传入子组件, 但未被子组件 props 注册的变量, 都会变成普通 html 元素属性, 作用到子组件根元素上; 在子组件声明时, 加上 , 就能避免此行为
-
$attrs
所有未被子组件 props 注册的变量(非 props 属性)都会放入 $attrs 中 (class 和 style 除外), 子组件使用 获取父组件传入变量, 也可以使用 传给孙组件, 曾孙组件…
-
$listeners
:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=“$listeners” 传入内部组件
-
应用
我在项目中实际中用到的地方, 是无限嵌套 Drawer — 用户点击表格行打开详情页, 在详情页又点击按钮打开新的详情页, 一层层嵌套;
此时, 如果使用 props 和 $emit , 就要一层层传递数据/数据, 这显然很麻烦; 此时使用 $attrs , 就能让最新的详情页直接获取最外层的数据, 使用 $listeners , 就能直接让最外层执行方法, 方便很多(虽然也要一层层 v-bind v-on)
4. inject provide
这个只看了文档, 没咋用过, 略
场景: 做任务计划模块,计划有提醒模块,到时间后提醒
实现:
1. 提交要创建的任务
2. 最外层页面实现提醒
3. 在 Vuex 中设置好 taskChangeObj
1. Vuex
2. Vue-Router
3. this.$route
这个可以用 router.currentRoute 来获取当前路由信息对象
4. prototype
自己在 Vue.prototype 上定义一个方法(别用箭头函数), 在 Vue 文件中调用, 这时根据"一般情况下, 谁调用此函数, 函数里的 this 就指向谁"规则, this 和 Vue 文件里的 this 等价…
-
首先我们都知道 axios 中有拦截器, 在请求回来发现 token 过期时, 我们需要在 success拦截器函数中, 中断后续的请求处理逻辑, 并跳转到登录页重新登录, 并显示错误提示.
-
假定后台返回的数据格式如下:
-
可能有多个请求受到 token 过期的影响, 为了防止错误提示弹出多次, 在 Vuex 定义一个变量, 比如;
它初始时为 , 当发现后台返回 时, 如果当前它为,
说明这是第一个被拦截下来的函数, 这时, 我们把它赋值为 ;
这样, 设置一个 就能拦截下后面的请求(具体在 Vuex 里怎么存看自己的代码结构), 避免弹出多次错误提示.
跳转到登录页面后, 在 的回调函数中, 再把 赋值回
-
但是实际发现, 本来会弹出多次的错误提示, 现在变成只弹两次, 而不是只弹一次, 猜想可能是这样:
前面几个都被拦截下来了, 但是到了某次请求返回结果时, 已经跳到了登录页面, 已经变回 了, 于是通过了 语句, 但是因为已经在登录页了, 实际上没有跳转, 也就没有触发它的回调函数, 从此变为 , 还会影响到后续的拦截
所以, 需要加上判断——当前页面是否在登录页.
-
最后是发现过期后如何中断请求, 直接看下面的代码吧:
-
最终拦截器代码如下:
场景: 短时间内发送多个筛选表格数据请求(筛选条件不同), 想要的是最后一次请求得到的筛选数据, 然而可能最后一次请求完成时间反而比前面的更早, 最后一次请求写入的数据被更早的请求(但请求完成时间靠后)覆盖了, 导致筛选出来的数据(更早的)和筛选条件(当前的)不对应;
解决方案: 其他的当然也有, 但是看到 axios 有一个相关的设置, 就用这个了:
场景:
部分接口海外客户不可用, 于是需要在客户无法某域名时动态切换到其他域名
解决方案:
- 设置定时器, 定时请求不同域名下的同一个健康检查接口, 谁先返回就设定该线路为最优线路, 相关接口走该线路请求
- 在 axios 的 request 拦截器中, 判断请求 url 是否要走健康检查逻辑, 要走的话, 替换原域名为当前最优线路域名
转载: vue-cli3内存溢出,JavaScript heap out of memory
为啥小组里只有我一个人有这毛病…
转载: Vue 里怎样在 Render 中使用 $refs
在 render 函数体里把 h 改为 this.$createElement 例如:
大佬厉害!
- 父组件把要传递的函数写在 export default 外部 (function 形式, 不能是箭头函数)
- 父组件在 data 中定义一个变量 myFunc , 值为 myFunc
- v-bind 传递上一步定义的变量 myFunc 给子组件
- 子组件定义计算属性, 里面 , 即可得到函数
问题: 节流和防抖函数生成函数并返回, 想把这个直接设置为 watch 的 handler , 发现 会报错
解决方法: 在 created 中使用 $watch 注册监听函数, 并在 destroyed 时销毁
主要是vuex和组件通信
在模板中, 父组件通过 这种形式监听
ps: 我看也有人写可以通过 或者 监听, 猜测是不是可以用 $parent , $children , $refs 来获取组件实例, 再调用 $on , 还没实际尝试
新建空白路由 refresh , 带参数 $router.replace 到 refresh 页后, 在 refresh 的 beforeRouteEnter 中再 replace 到指定 name
注意: 地址栏会有闪动, 另外, replace 时 title 记得别改 title , 避免 title 闪动
https://cn.vuejs.org/v2/guide/plugins.html
使用插件统一管理 vue.protoType.methods , vue.methods , mixins , filters , directives
https://cli.vuejs.org/zh/guide/mode-and-env.html
使用环境变量和模式来指定相关地址等数据
https://cn.vuejs.org/v2/guide/render-function.html#JSX
https://github.com/vuejs/jsx
可以考虑使用 jsx 来更方便地 render VNode
统一管理接口调用
-
本体
-
避免触发子元素 click 事件
-
避免 onmouseup 失效
pauseEvent
-
备注:
- 还有边界判断之类的没加, 可以继续优化
- 可以改成不使用指令的方式给非 vue 项目使用
- 注意 , 很奇怪的是, 第一次 时, 哪怕没有移动鼠标, 也会触发其内部定义的 , 这有可能导致 BUG , 因此, 加上了 来确保鼠标真的是有位移
问题定位:
-
axios.created 创建的 ajax 配置底下加了个莫名其妙的 cancelToken , 用的同一个 axios.cancelToken , 传的cancelToken.source().token
逐个代码块注释解注, 发现在某个请求之后出现内存问题, 控制台打快照对比切换前后变化(有个选项可以看到在快照 2 和快照 1 之间被分配的数据), 发现就一个 cancelToken 看着眼熟
跳到该请求 ajax 配置定义处, 发现比之前多了一个 cancelToken (其他同事加的), 上 Google 搜索这个是否会导致内存泄漏, 搜索栏自动联想"axios canceltoken memory leak", 应该就是这个了 -
频繁切换组件后, 使用 vue-i18n, this.$t 可能取不到 this 导致报错
定位问题时, 我是注释大块代码后在左侧目录快速切换子组件 50 次看看内存上升多少, 发现在这种情况下控制台经常报错"TypeError: Cannot read property ‘_t’ of null", 这时内存有变化
搜了下, 找到一个回答
https://stackoverflow.com/questions/54666293/vue-i18n-cannot-read-property-t-of-undefined-at-proxy-vue-t
照着这个, 在 new Vue 之后加上了 ‘Vue.prototype._i18n = i18n;’ , 提示语消失了, 不过之后又有出现, 只是频率降低很多, 有兴趣的可以继续看看 -
某组件绑定事件后未解绑事件
最后一路解注释到这块儿, 加上解绑后整体解决
可以使用 {{ ‘xa0’ }} 代替
背景:
登录页加载了两个 1m 以上的 js , 太大了, 打开非常简单的登录页需要 7 - 9s
优化方向:
-
webpack 配置优化
-
主要是打包增加 gzip 压缩 — 前端加上 compress-webpack-plugin 设置好, 也需要后端配合设置好
效果, 两个 js 文件大小瞬间减少了一半还多
-
加上 webpack-bundle-analyzer 插件, 打包后看看各文件里还有哪些模块占大头的, 能不能拆分之类的
-
其他…网上搜相关文章 + 对照着 webpack 官方文档慢慢尝试
-
-
之前没有走按需加载的路由组件统一改为走按需加载
-
非常坑的是, 之前做过按需加载, 但这次排查时, 发现实际上只有初始化二级路由时才用了按需加载, 根据目录权限接口的返回生成一级路由时, 一级路由的 component (按需加载 Main.vue)不是走的按需加载, 还有个别新增的不从属于 Main.vue 的单页也没走按需加载
改为按需加载, 两个 js 文件大小再次降低一半多
-
-
将 main.js 内大部分不需要在登录页加载的引入挪到 Main.vue 中, 减轻首屏 js 文件大小(相应地, main.vue 对应的 js 文件变大)
其他非 Main.vue 界面(登录页, 忘记密码页, 中转页, 邮件单页)中使用的全局 api 可能有缺失, 需要调整引入方式- 微前端引了一堆组件, 改成从 main.js 挪到 mian.vue mounted 中
- 大部分 Vue.component , Vue.mixin , Vue.filter , Vue.protoType.xxxx = YYYY 之类的, 都从 main.js 里去掉, 放到 main.vue created 里
-
将 index.html 里没必要第一时间引入的资源, 往后移动, 或者加上 async 或者 defer , fetchPriority="low"之类的
- index.html 里大部分的静态 script 标签改为在相应页面动态插入 script 元素 — 动态插入默认是 async , 注意是否要设置好 script 元素的上面这些属性再插入
- 百度地图埋点使用了 document.write , 这种不能动态插入, 只能在 document.write 还可用时同步引用代码, 写到 前吧, 避免阻塞
- 从控制台 Network 看, 音频资源也会造成阻塞, 耗时较长, 可以设置 preload=“none” 避免第一时间加载音频资源造成阻塞
-
去掉冗余的引入, 各种 import 了没使用的都注释掉
-
其他非主体框架页面(Main.vue), 比如 login 页面, 忘记密码页面, 各类单页等, 如果有用到全局 component , api 等, 需要检查一遍是否还有效, 无效了最好自己单独引入
结果:
首页加载的最大的两个文件 , appXXXX.js 和 chunk-vendorXXXX.js , 降到了 200 多 K , 300 多 K
google 网址测速, pc 首屏显示时间为 1.5s 左右, 移动端首屏显示时间为 6s 左右
未来方向:
- 经过优化, 登录页和主体框架页面(Main.vue)的 js 大小大概从 5:5 变为了 2:8 , 开启 gzip 压缩后, 主体框架页面仍然有 1.3M 大小, 还是太大了;
通过 bundle 插件, 该 js 里还是有一些大的外部模块, 可以单独提取出来的, 比如通过 CDN 加载, 或者通过 webpack.DllPlugin 把多个静态库打包成一个文件, 这样更能把握 js 大小和数量之间的平衡 - 实际上可以把登录页改造成单独的 html 页面, 登录页本身也不复杂, 不使用或者少使用 Vue 和那些 UI 框架, 应该能大大加快速度
- 发现一篇文章, https://juejin.cn/post/7188894691356573754 , 提到 Vue 文件引入子组件也可以按需加载, 以及这里说的骨架屏插件, 感觉也不错, 之后可以试试
参考资料
- vue单页面项目SEO优化问题
- 预渲染 prerender-spa-plugin 避坑指南
- prerender-spa-plugin预渲染踩坑
实现思路
参考资料 1 中提出的几条路线(服务端渲染, 打包预渲染, ), 因为是改造现有应用, 所以综合下来选了 prerender-spa-plugin 路线;
此路线大意为: 此插件可以在页面渲染后再打包生成静态页面, 生成的页面因为有了内容, 可以被 Google 收录
具体步骤
-
安装 prerender-spa-plugin 插件(当前 ^3.4.0)
-
修改 Vue.config.js , 应用上述 plugin
-
在 new Vue 的 mounted 函数中加上触发自定义的加载完成事件
该事件通知到 plugin : 页面渲染完毕, 可开始生成静态页; 也可以换成在其他处触发此事件 — 但有文章提到:“不是在根组件中设置此事件无效”
-
修改 Vue-router 配置
-
打包, 上传页面到 Google 收录, 确定当前可以收录
访问 请求(重新)编入索引, 按操作将要收录的页面收录到 Google , 已收录后, 去 Google 搜索下页面标题/网址, 看能否搜索到
-
可使用 Vue-meta-info 组件添加 meta 信息
注意事项
- mode 从 hash 改为 history 还需要关注下有没有问题
- 修改 mode 后, 微前端配置也要改
- 修改 mode 后, 各页面跳转地址是否有变化,
参照:
[反馈]使用qiankun时,vue-devtools无法调试子项目
实现:
参照:
如何在生产环境排查 Vue 应用问题
为生产构建的Vue应用强制开启Vue Devtools
以及, 第一篇文章末尾有提到Vue force dev插件可以直接用
实现:
背景:
Vue3 项目 - 时间轴组件 - 遍历渲染单个时间轴条目组件 - 条目组件遍历渲染显示字段, 编辑某个条目后, 会重新请求数据列表替换原数据数组重新渲染, 偶现此报错
排查:
条目组件内容较简单, 注释怀疑的代码块, 排查问题, 发现是如下代码导致问题:
将 :key 放到 template 上解决
(之前这么写是因为 vue2 项目里, :key 到 template 上, 编辑器会标红, 但现在修改后也不会标红了)
iView 因为多个组件有内存泄漏问题, 且官方不处理问题直接关闭 issue , 现已放弃, 改为使用 Element-UI
iView 框架的 组件直接使用 有问题(国际时间和本地时间的问题),可以使用 和 ,手动赋值,这样显示就完全正常;
- 如果页面上有多个 组件,可以使用 ,在其中设置好唯一标志本次打开的 的属性,然后再在 中处理
- 但是要注意,使用这种方法,直接改 并不会让 组件的显示也跟着改
iView 中有些组件可以绑定的一些事件,其本身不需要传入参数,只需要在定义事件方法时写入形参就能取到,但如果在传入时附加参数,就取不到默认参数了
1. $event
此时可以使用 , 此时 就是默认参数
2. arguments
某些函数默认带有两个参数, 此时用 只能取到第一个(**查了一下好像是原生事件 event`
就 组件而言(其他的没观察), 它的 属性, 是把组件的气泡放到全局 中.
这种情况下, 在本页面的样式中操作无用, 只有在全局中调整才可以, 但是要使用 绑定类名到 组件才行
但是也要注意, 在这种情况下, 触发气泡的元素(trigger)还在组件中, 使用深度选择器在 中选择 即可
-
场景: iView , 三个 组件,第一个的 会动态改变第二个的 数组,以及第三个的类型( 或 ), 它的使用场景是填写筛选条件, 比如第一项选 最近更新时间,那第二项就会是 , 第三项变为 , 第一项选 客户星级,那第二项就是 , 第三项变为
问题: 改变首项筛选条件时, 前后若根据首项获取的二项的 数组前后 相等(如,都有三个选项), 那么选择二项时,虽然实际上可以正确筛选,但文字总是显示成 change 前的选项.
解决:直接用 取数据,当 组件的 上的 不等于 时, 的方法直接把 赋给前者
需要注意: 中写的 取到的值是个数组,具体到我当时的实例中,是个只有一项的数组,用 取组件数据
-
场景: 做邮件系统,选择收件人,需要既可以显示候选账号进行下拉选择,又可以直接手动输入账号,但是 iView 本身没有符合需求的组件
思路:
- 首先想到的是一个伪装成输入框的 ,在其中加入 系列,后面追加一个 , 再用隐藏的 实现 的动态变长(在这过程中我还找到了 这个可以让 可编辑的属性),这一步我是直接用的 + 的 组件生成的 代码
- 随后同事提醒我, 何不在 前再加一个 , 再把 长度限制到只能显示一个光标, 动态填入输入内容到前面的 ,这样就不用变长,也不用担心溢出和让 换行
- 最后同事又说,原来的 + 的 组件已经可以了,稍作调整就行.
实现:
- 观察 + 的 组件生成的代码结构, 时,为输入框绑定 事件,根据 判断输入值是否已在下拉列表( 数组),是否已被选中,如果没有,则 进去
- 在 的 中,询盘判断当前数组各项是否正则校验邮箱(推荐 Regulex ----正则可视化工具+邮箱正则表达式)通过,如果通过,则通过 绑定对应位置的 字体标黑(通过的情况也要显式操作,不然也可能变红),不通过标红
-
场景: 使用 级联组件,要求动态加入一级目录,点击一级目录后的请求二级目录还是用组件自带的搜索+动态加载功能
实现:
-
首先想的是直接请求一级目录动态添加,但是组件本身的机制是,使用筛选后得到的值点击后就直接被认定为完成选择,跟我想的点击动态生成的一级目录就会请求二级目录不同
-
于是我使用 slot ,在其中定义一个 Input 组件,这样看上去和原来一样,也能运行,但是会报错
-
在 Input 组件上绑定 @input.native ,
Cascader 组件上 @on-change 做回填到 Input 用,
@on-visible-change , 本意是想要让它在关闭 panel 时检测是否已经有选中的选项,有的话就回填
避免用户已选择选项后又输入字符,没有匹配到就关闭了 cascader ,这时没有触发 cascader 的 on-change 函数,所以没有回填,这时其实 cascader 是有数据的,但是 input 里却仍然显示之前没匹配到时输入的字符
结果发现 on-visible-change 好像只检测到了 visible 为 true 的情况,
控制台报错,因为组件源码里定义的 slot 默认内容中的 input 被 slot 中的 input 组件替换了,后面用到默认 input 时就会报错,不知道是不是因为这个原因才没检测到 visible 为 false 的情况,报错的时机和 panel 关闭时间相合
不得已只能在展开时清空 cascader 的 v-model 了,毕竟展开就说明是要搜索,这也说的过去
-
-
直接把 iView 的 GitHub 仓库下载下来
-
改动代码后,可以 npm run dev 查看效果, npm run dist 重新编译
-
编译完成之后,用新的 dist 文件把原来的框架中的 node_modules 中的 iView 文件夹的 dist 代码覆盖掉, 如果需要引用 iview 里的组件, 把 src 也替换掉(一般也只会改 src 吧?)
-
如果不想每次编译那么麻烦, 可以直接把下载下来的 iview src 文件夹复制到项目中, 引用的时候直接按路径引它而不是安装好的 iview 包;
但是这样也有麻烦:
- 一开始运行不了, 报错, 安装了 iview package.json里面的一些依赖(主要是 babel 相关, 另外还有 babel 配置文件也要改)才跑起来
- 想上线时你会发现, 安装了那些包, 修改了 babel 配置文件后, 不能按需加载了(打包/运行时使用 webpack-bundle-analyzer 发现), 且体积也变大了
所以最后还是放弃直接引入了, 只在早期开发阶段不急着上线时用
-
多选:
-
使用 Cascader 的 自定义显示 功能, 用带 multiple 的 Select 替换掉组件自身的文本框
-
修改 Select 相关样式
-
为 Cascader 组件绑定 on-change 事件
当事件传入的已选项数据不为空时, 取出已选项数据, 格式化后填入 Select 的 option 列表和 v-model 绑定的数组
-
为 Cascader 组件绑定 on-visible-change 事件
每次 visible-change 时, 都通过给 Cascader 设置的 ref 来清空 Cascader 的已选项
-
- 查看源码, 发现代码写的是只有全选选中才能触发 on-select-all 事件, 现在觉得要么是自己改源码, 要么是自定义表头然后绑定相应的事件
- 最简单的当然是直接改 iview.js , 然后检测选中数量为 0 就是取消全选, 反之就是全选, 但是这样不好维护, 听说可以打个 iview 的分支改动后同步到这个分支上, 但是没弄
- 第二个想法是, 隐藏表头, 用 slot=“header” 来当表头, 暂且搁置
- 最终采用: render 和 renderHeader, 在这两个函数里渲染 Checkbox , 用计算属性得到表头全选 Checkbox 的 value , 两种 Checkbox 都使用 on-change 改变 _checked 属性,
-
直接 Ctrl + B (webstorm 下)跳转到组件的定义处, 就能发现源码中也是 export 组件在引用使用的, 于是照着来:
参考webpack+iview 在数据导出csv格式数据时变为科学计数问题
- 问题: exportCsv 时, 如果数据以 开头, 则会被 Excel 识别为公式, 错误显示.
- 像参考文章中那样, 遍历数据然后在前面加上 (注意双引号) 就行了
- 还有表格中有 的内容被分割成多列的情况, 用 iView 文档中说的 给数据统一包裹上就行了
- open 属性始终为 true , 保证始终展开
- 内部 slot 加一个不占位的元素做触发器, 相当于隐藏掉了上面的框
但是注意, 这样展示的 Datepicker 仍然会触发 on-open-change 事件, 造成后果和解决方案参看下方
-
上面 Datepicker 的 open 始终打开, 但仍会触发 on-open-change 事件造成阻塞, 导致: 点击其它地方时会先触发 on-open-change(false) 随后不再执行, 导致第一次点击无效
-
另外, 上 GitHub 看了下, iview 项目有人提 issue 表示, Select 展开情况下, 点击别处想执行操作不会生效, 因为跟上面一样要先关闭 Select , 官方表示就是这么设计的
-
解决方法: 在第一次渲染(open 变为 true)时就点击一下(选不会影响页面行为的地方点击, 比如这里选的是 Datepicker 的父级 Poptip 的 $el)提前触发这个 on-open-change(false), 之后就不会阻塞了
以后这类情况(Datepicker, open 始终打开)都要这么弄, 类似的弹出型出现同样的问题应该也可以这么弄
场景: 表格页点击进入详情页, 详情页又有一些的关联的详情页, 比如 商品列表 => 商品详情页 => 商品厂家详情页 => 厂家下别的商品的详情页 => …
实现:
详情页分开写成组件, 用一个中间层总体处理 Drawer 和 详情页, 外部直接引用这个中间层.
中间层大致代码:
如果发现 Select 高度消失或者选项不显示, 看看是不是 placeholder 为空或者没写 label
-
自定义滚动条样式后, 若水平和数值滚动条宽度不一致, 可能会有样式上的错误, 原因是 Table 组件只计算一边(忘了哪边了)的宽度, 随后拿这个宽度来调整宽高.
自己定制 iview 框架, 找到地方(Table.vue 里面的 scrollBarWidth 之类的)修改一路"跳转到定义", 修改成各按各的来.
-
Table 的 columns 配置 tooltip 属性后, 鼠标不能移上去 tooltip 复制上面的文字
我提的修改方案: [Feature Request]I am trying to solve this problem: use the table column property tooltip, the mouse cannot be moved to the contents. #5867
另外, 表格有些时候需要 render , 这时候想要兼顾 render 和 tooltip 配置, 只能自定义一个 Tooltip 组件(先按上面的修改方案改好 Table 组件了才能用这个), 把要 render 的元素放到新组件的 slot 里, 代码如下:
复杂筛选的拼合
原因
内部 transfer 了, 点击其浮层, 就相当于点击 body 中其他元素, 所以会关闭 Poptip
解决方案
-
简单行为, 如: Poptip 里又有一个 transfer 的 Poptip, 点击其内部, 最外的 Poptip 消失
-
复杂行为, 如: Poptip 里有 DatePicker 组件, 点击 DatePicker 内部进行选择
不定制 iview 组件的理由:
本来是想着干脆改了 Poptip 组件, 弄一个类似 disableCloseUnderTransfer 的 prop 在 Poptip handleClose 时阻止其关闭, 但是这样一来, 正常点击空白页面, 也不能关闭 Poptip 了, 所以还是一个个地在内部 transfer 的组件上加上修改 disableCloseUnderTransfer 的相应代码
背景:
之前已有了单独的表格筛选组件, 公司要求直接对表格顶部进行筛选, 方便用户操作
思路:
使用 element 表格 tableColumn 的 renderHeader 属性, 其内部绑定全局注册的筛选框组件, 传 column 的值给筛选框组件, 筛选框组件根据条件渲染不同的下拉框
代码实现:
-
renderHeader_filter 函数
-
筛选组件
-
其他
其他还有表格页对排序和筛选的各种处理, 筛选框的隐藏显示问题, 样式问题, 筛选完成后显示筛选标签在顶部方便用户查看筛选条件和快速删除筛选条件, 这里略过
pl-table el-bigdata-table
问题背景:
客户报 BUG : 多选 select (比如产品分类)选中三个或四个以上选项(每个选项只占都只有一行, 未换行)时, select 会不停抖动;
重现:
正常情况下未重现, 缩放浏览器(我是缩放到 110%)后重现
解决:
网上搜了下说可能是 tag 的问题, 于是定位;
发现之前为了让标签换行, 给 tag 加上了自定义样式 , 去掉了 后问题解决; 但是去掉之后又会换行, 于是加回来了, 再加了一句 , 问题解决;(24px 是不加 height: auto 时 tag 的固定高度)
通过 vue 调试工具查看, 发现触发了一个 input 事件, 其 payload 数据正常, 于是改 为 , 为 (在 input 时间 handler 中修改 value 值)
看同事的代码, 直接在渲染时返回 template 格式的代码, 而不是用 h , 问了下同事, 说这么弄没问题, 不过自己还没试20
背景:
需要做一个多选下拉组件, 与多选 select 类似, 但下拉框中是 tree 而不是 option
解决:
- 直接用多选 select 做 reference 元素, 使用 popover-class 属性隐藏 select 框
- 选中树节点时, 更新 select 的 option 数组和 select 的 value (主要是图 select 的多选标签效果, 也可以自己实现)
- 在 select value 变化时, setTimeout 调用 this.$refs.popover的ref的属性.updatePopover , 更新弹出框位置, 避免 select 多选换行之后, popover 位置不变导致遮挡(如果部分情况下不奏效, 适当调节 setTimeout 的毫秒数, 我用的 50 ms)
其他:
本来看 elemnet-ui 文档后, 想从它说的 popover.js 找解决方法, 但没找到, 直接看 element-ui 源码, 看了 popover.js 和 vue-popper.js , 没啥头绪, 干脆去看 select , 发现 select-dropdown 文件很简单很直观, 发现了这个 updatePopover 方法, 试了下确实可以
以后遇到类似的, 其他用了 mixin: [import 的 vue-popper] 的组件, 应该也可以如此解决
背景:
需要做一个多选下拉组件, 与多选 select 类似, 但下拉框中是 tree 而不是 option
解决:
从源码可以看出, trigger=“click” 时, 组件是在监控 document 的点击事件, 判断点击事件是否发生在 popover 之外
于是想到, 给相关弹框加上 @click.native.stop , 阻止它向上传递 click 到 document , 问题就解决了
ps: 要注意下会不会有其他问题, 比如全局在追踪一些按钮的点击事件, 不传递了会不会追踪失败这之类的, 要结合具体功能看
背景:
请求接口获取会话列表, 每个会话有一个"客户最后回复时间", 是以"距今时间差"形式返回毫秒数, 前端定时每秒给时间差 + 1000ms , 更新这个时间差, 做到实时显示哪些会话是活跃会话(距今 x 小时内), 是的话就加上相关样式
结果给会话头像加上 样式计算逻辑之后, 与头像无关的"会话最后一条消息"等其他数据, 也会每秒就重新计算一次
解决:
不知道原因
思路上, 认为这是会话数据对象被更新导致重新计算, 于是, 转变为"给 class 绑上不会经常变的变量"