看了网上文章学习了下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. 微信小程序云开发-列表下拉刷新

    一.json文件开启页面刷新 开启页面刷新.在页面的json文件里配置两处: "enablePullDownRefresh": true, //true代表开启页面下拉刷新 &qu ...

  2. chcod炸弹

    [题目描述] 话说Cpp国和Pas国发生了战争, Pas国派出了强大的飞机战队, Cpp国于是使出了炸弹CHCOD 来反击Pas国的飞机舰队.然而CHCOD的发射器,只能逐渐往上打.所以Cpp国现在只 ...

  3. Linux + NodeJS 常用命令

    Linux系统常用命令 1.su 由当前用户切换至root用户: 2. su username 切换至某一用户: 3.chmod u+w /etc/sudoers 为/etc/sudoers文件添加写 ...

  4. 13Java进阶——IO、线程

    1 字节缓冲流 BufferInputStream 将创建一个内部的缓冲区数组,内部缓冲区数组将根据需要从包含的输入流中重新填充,一次可以读取多个字节 BufferOutputStream 该类实现缓 ...

  5. C++第三十四篇 -- 安装Windows Driver后,编译以前项目出现打不开lib文件

    VS2017默认是没有安装WDK的,但是我们写驱动文件的话需要用到WDK.不过安装了WDK后,发现以前一些正常的项目在Release模式下编译会报LINK1104,无法打开.lib的错误 针对这个错误 ...

  6. 第二十六篇 -- wifi学习

    参考网址:https://blog.csdn.net/zwl1584671413/article/details/77936950 https://blog.csdn.net/Righthek/art ...

  7. 如何用C++自己实现mysql数据库的连接池?

    为什么是mysql? 现在几乎所有的后台应用都要用到数据库,什么关系型的.非关系型的:正当关系的,不正当关系的:主流的和非主流的, 大到Oracle,小到sqlite,以及包括现在逐渐流行的基于物联网 ...

  8. [WinError 10013]以一种访问权限不允许的方式做了一个访问套接字的尝试

    Django报错截图如下: 原因分析:出现这种情况在Windows中很常见,就是端口被占用 解决步骤: 1:进入windows中的命令行窗口(win+R之后输入cmd就可以进去)   2:输入 net ...

  9. ThinkPHP5 SQL注入漏洞 && 敏感信息泄露

    访问看到用户名被显示了 http://192.168.49.2/index.php?ids[]=1&ids[]=2 访问http://your-ip/index.php?ids[0,updat ...

  10. 图文实例解析,InnoDB 存储引擎中行锁的三种算法

    前文提到,对于 InnoDB 来说,随时都可以加锁(关于加锁的 SQL 语句这里就不说了,忘记的小伙伴可以翻一下上篇文章),但是并非随时都可以解锁.具体来说,InnoDB 采用的是两阶段锁定协议(tw ...