看了网上文章学习了下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. MySQL -- 表联结

    创建联结:(使用WHERE联结)SELECTvend_name,prod_name,prod_priceFROMvendors,productsWHEREvendors.vend_id=product ...

  2. 超详细!搭建本地大数据研发环境(16G内存+CDH)

    工欲善其事必先利其器,在经过大量的理论学习以后,需要有一个本地的研发环境来进行练手.已经工作的可以不依赖于公司的环境,在家也可以随意的练习.而自学大数据的同学,也可以进行本地练习,大数据是一门偏实践的 ...

  3. VSCode 使用

    运行时,如何弹出cmd命令窗口:将launch.json文件中的 externalConsole设置为true,并按F5运行(不要按右上角的运行按钮) 如何cin:先再命令窗口通过g++ *.cpp生 ...

  4. 动静态web项目(三)

    在Eclipse中将web项目分为了Dynamic Web Project和Static Web Project. 那么这两种有什么区别呢? 其实这里的Dynamic和Static是通过页面来区分的. ...

  5. 简单图解OSI七层网络模型

    Open Systems Interconnection(OSI)定义了一个网络框架:其以层为单位实现了各种协议,同时会将控制权逐层传递. 目前OSI主要作为教学工具被使用,其在概念上将计算机网络结构 ...

  6. Python自动化测试面试题-Python基础篇

    目录 Python自动化测试面试题-经验篇 Python自动化测试面试题-用例设计篇 Python自动化测试面试题-Linux篇 Python自动化测试面试题-MySQL篇 Python自动化测试面试 ...

  7. php中英文字符串转字母转大小写

    <?php //转小写 function lowercase($a){ $b = str_split($a, 1); $r = ''; foreach($b as $v){ $v = ord($ ...

  8. Hadoop 3.1.1 - Yarn 服务 - 总览

    YARN 服务 总览 Yarn 服务框架为在 Yarn 原生环境里长时间运行的服务,提供了一流的支持和接口.简言之,它扮演了容器编排系统的角色,统一管理 Yarn 上运行的容器化服务.它同时支持 Do ...

  9. DC-9 靶机渗透测试

    DC-9 渗透测试 冲冲冲,好好学习 DC系列的9个靶机做完了,对渗透流程基本掌握,但是实战中出现的情况千千万万,需要用到的知识面太广了,学不可以已. 靶机IP: 172.66.66.139 kali ...

  10. scrapy 错误:Missing scheme in request url: %s' % self._url

    先说报错原因:使用了和start_urls同名的参数 我通过scral crawl projename -a start_urls=http:example.com来传start_urls,然后想在项 ...