看了网上文章学习了下vue的抽象组件,感觉就跟react的高阶组件一样的使用场景,只是更加面向vue的底层编程

,网上介绍的抽象组件一般有2种用法,1 用来加防抖和节流 2 用来控制按钮是否允许点击做权限效验,这2个对于

目前我所做的一些项目用处不大,这里先介绍下我用抽象组件的使用场景,总不能说学习了抽象组件不管是否适用就

强行加到项目里吧。。。

1. 基本上公司项目所有用到动态地址的地方都要做2个效验,1 判断这个从后台返回的url是否为空,相信大家
经常写这种代码 :src="imgUrl|| defUrl", 2 如果这个地址存在,那么还要做验证,防止地址报错,这个
代码大家也经常写吧 @error="fixUrl"。 如果每个用动态img的地方都这么写,一个项目下来我都要吐了。 2. 就算你愿意这么写,还是有一个问题,在 @error="fixUrl"里,一般的处理方式是在方法里把imgUrl替换成
defUrl,这样就会有另一个问题,显示的图片是出来了,但是如果你的imgUrl不仅用来展示要在其他地方用,你总不能
拿替换过的imgUrl用在其他地方吧,针对这种情况,大部分人(之前的我)的处理情况就是要2套数据放到data里,一套用来
展示,一套用来内部传值使用,很不优雅对吧。 3. 我也想过,做一个组件,然后所有需要验证的地方都不用img都用这个img组件,但是img的样式,和绑定的方法,这些你都要
从外边取,然后绑定到真实img上,我只想处理个图片验证啊,怎么还有这么多需要兼容的地方要关注,好麻烦啊。

所以遇到了抽象组件,稍微思考了一下,觉得可以完美解决以上3个问题。真香,直接看抽象组件的代码吧。


<script>
export default {
name: "imgFix",
abstract: true, //标记为抽象组件
props: {
// 要替换的图片,如果是服务器下的写url地址,public目录下的写地址记得加process.env.BASE_URL,原因请看
// https://www.cnblogs.com/wzcsqaws/p/11283228.html
// assets 目录下,记得用require包裹一下
replaceImg: {
type: String
}
},
created() {
// 为了解决如果replaceImg 也报错就会重复死循环调用error方法
this.replaceObj = {
originalSrc: "",
isReplace: false
};
},
render() {
let replaceObj = this.replaceObj; // 闭包在错误函数里锁住这个对象
let replaceImg = this.replaceImg; // 要替换的图片
let vnode = this.$slots.default[0]; // 子组件的vnode
let that = vnode.context; // 子组件的vm也就是this
let on = vnode.data.on || (vnode.data.on = {}); // 获取img标签的vnode上的绑定事件,没有绑定会为空
let error = on.error; // 获取报错事件
let originalSrc = vnode.data.attrs.src;
if (!originalSrc) {
// 如果动态获取的url为空,这里之间替换为replaceImg
console.log("url is null");
vnode.data.attrs.src = replaceImg;
} // 写一个error事件防止报错,图片没有替换
function errorFix(e) {
// 已经替换过了,还报错,说明替换的url也有问题,就renturn,避免再次赋值死循环
if (
replaceObj.isReplace &&
replaceObj.originalSrc === originalSrc
) {
console.log("replaceImg is also error");
return;
}
console.log(e, "url is error");
// 注意这里是之间改变dom上的src没有修改vue里的
// 值。就可以解决我上面说的第二个问题
vnode.elm.src = replaceImg;
replaceObj.isReplace = true;
replaceObj.originalSrc = originalSrc;
if (error) {
// 做个兼容,如果原文件也绑定了error事件,在替换图片后也会触发,并且手动绑定上下文和event
// 如果原error事件也改变了url,那么会以原文件的url来显示
error.call(that, e);
}
}
on.error = errorFix;
return vnode;
}
};
</script>

功能上还有一个细节没有处理到位,就是我在抽象组件里改了url,原文件的error事件也改了url,那么如果抽象

组件的url加载快会先显示出来,等error事件的url加载好了再替换,这样子就会闪一下,体验不好,目前的解决

办法是使用抽象组件的开发者通过规范不这么做,但是从代码角度解决最好.

用vue的抽象组件来做一个防止img标签url为空或url地址出错的验证的更多相关文章

  1. Vue.js 入门:从零开始做一个极简 To-Do 应用

    Vue.js 入门:从零开始做一个极简 To-Do 应用 写作时间:2019-12-10版本信息:Vue.js 2.6.10官网文档:https://cn.vuejs.org/ 前言  学习 Vue ...

  2. 使用ant design vue的日历组件,实现一个简单交易日与非交易日的切换

    使用ant design vue的日历组件,实现一个简单交易日与非交易日的切换 需求: 日历区分交易日.非交易日 可以切换面板查看整年交易日信息 可以在手动调整交易日.非交易日 演示实例 序--使用软 ...

  3. Vue+ElementUI: 手把手教你做一个audio组件

    目的 本项目的目的是教你如何实现一个简单的音乐播放器(这并不难) 本项目并不是一个可以用于生产环境的element播放器,所以并没有考虑太多的兼容性问题 本项目不是ElementUI的一个音频插件,只 ...

  4. 用vue的自定义组件写了一个拖拽 组件,局部的 只能在自定义元素内的

    简单实现 没有做兼容<!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. vue怎么将一个组件引入另一个组件?

    项目是由的vue-cli搭建 1.这里有两个组件,需求是把newComponents.vue里面的东西引入到helloWorld里面 2.index.js里面的配置 3.newComponents里面 ...

  6. 手把手从零开始---封装一个vue视频播放器组件

    现在,在网页上播放视频已经越来越流行,但是网上的资料鱼龙混杂,很难找到自己想要的,今天小编就自己的亲身开发体验,手把手从零开始---封装一个vue视频播放器组件. 作为一个老道的前端搬砖师,怎么可能会 ...

  7. Vue 入门之组件化开发

    Vue 入门之组件化开发 组件其实就是一个拥有样式.动画.js 逻辑.HTML 结构的综合块.前端组件化确实让大的前端团队更高效的开发前端项目.而作为前端比较流行的框架之一,Vue 的组件和也做的非常 ...

  8. [js高手之路] vue系列教程 - 组件定义与使用上部(7)

    组件是vue框架比较核心的内容,那么什么是组件呢? 通俗点讲:组件是由一堆html, css, javascript组成的代码片段, 作用是为了实现模块的重用 组件的基本用法: <div id= ...

  9. Vue.js使用-组件(下篇)

    上一节,我们定义了组件的基本使用,下面我们看看组件其他的一些特性. 1.组件作用域 同时在Vue对象和组件中定义一个属性,显示结果是怎样的呢? <!DOCTYPE html> <ht ...

随机推荐

  1. Leetcode13. 罗马数字转整数Leetcode14. 最长公共前缀Leetcode15. 三数之和Leetcode16. 最接近的三数之和Leetcode17. 电话号码的字母组合

    > 简洁易懂讲清原理,讲不清你来打我~ 输入字符串,输出对应整数 ![在这里插入图片描述](https://img-blog.csdnimg.cn/63802fda72be45eba98d9e4 ...

  2. 微信小程序云开发-云存储-上传、下载、打开文件文件(word/excel/ppt/pdf)一步到位

    一.wxml文件 <!-- 上传.下载.打开文件一步执行 --> <view class="handle"> <button bindtap=&quo ...

  3. 开源框架是如何使用设计模式的-MyBatis缓存机制之装饰者模式

    写在前面 聊一聊MyBatis是如何使用装饰者模式的,顺便回顾下缓存的相关知识,可以看看右侧目录一览内容概述. 装饰者模式 这里就不了它的概念了,总结下就是套娃.利用组合的方式将装饰器组合进来,增强共 ...

  4. javascript学习笔记-(三)

    ES6标准新增了一种新的函数:Arrow Function(箭头函数) 案例: 为什么叫Arrow Function?因为它的定义用的就是一个箭头: x => x * x 上面的箭头函数相当于: ...

  5. [源码解析] 机器学习参数服务器ps-lite (1) ----- PostOffice

    [源码解析] 机器学习参数服务器ps-lite 之(1) ----- PostOffice 目录 [源码解析] 机器学习参数服务器ps-lite 之(1) ----- PostOffice 0x00 ...

  6. 【原创】case、casez和casex谁是谁

    在Verilog中case语句经常用于多分支表决的结构,case后的表达式会与各分支表达式"全等"那么对应的分支会被执行.其基本结构如下: case(expression) exp ...

  7. vscode安装ESlint配置

    先安装插件ESLint,后面在设置setting.json中配置加入代码: { "files.autoSave": "afterDelay", "ed ...

  8. Apereo CAS 4.1 反序列化命令执行漏洞

    命令执行 java -jar apereo-cas-attack-1.0-SNAPSHOT-all.jar CommonsCollections4 "touch /tmp/success&q ...

  9. msf反弹

    转载https://www.cnblogs.com/xishaonian/p/7721584.html msf 生成反弹 Windows Shell msfvenom -p windows/meter ...

  10. etcd raft 处理流程图系列1-raftexample

    最近在看raft相关的代码和实现,发现etcd的raft模块在实现上还是比较灵活的,但缺点就是需要用户实现比较多的功能,如存储和网络等,同时带来的优点就是不会对用户的存储和传输作限制.网上对该模块的描 ...