Vue 组件间的样式冲突污染


Posted in Javascript onAugust 31, 2017

一、污染是如何产生的?

得益于 Vue-loader,在 Vue 中可以使用类似于 Web Component 的组件化写法, <template></template><style></style><script></script> ,在大多数情况下,我们希望组件间定义的样式是相互隔离的,在 Weex 当中的确如此,组件天生隔离,可是在 Vue 当中,运行的载体还是浏览器,所有的样式类还是会通过 style 标签插入头部,影响全局,交叉污染

二、增加 Scoped 标识

依然是 Vue-loader,通过为组件中的 style 标签增加一个 scoped 标识,Vue-loader 在编译的过程中会为组件每一个元素节点增加 scopeId 作为属性,同时为所有的样式类加上属性选择器 scopeId,从而达到隔离的效果,大概是下面的样子:

每个组件有唯一的 scopeId,按理说,这样应该能够做到样式隔离了,实际上, 这种方式其实表现已经足够好了,除了以下这种情况~~

三、ScopeId 的继承

我们把上面的例子再完善下:

// 父组件
<template>
  <div>
    <div class="bg"></div>
    <Sub></Sub>
  </div>
</template>
<script>
  import Sub from './sub';
  export default {
    components: { Sub }
  };
</script>
<style scoped>
.bg {
  background-color: #000;
  width: 100px;
  height: 100px;
}
</style>

// 子组件
<template>
  <div class="bg">
  </div>
</template>
<script>
  export default {
  };
</script>
<style scoped>
.bg {
  width: 300px;
  height: 300px;
  margin-top: 5px;
}
</style>

由于我们使用了 scoped 标识进行样式隔离,子组件的 div 不应该有任何背景颜色,可是现实总在狠狠的打脸~~

Vue 组件间的样式冲突污染

不知道你的媚眼看到问题的所在了没:

子元素的 根元素 会继承父元素的 ScopeId!

子元素的 根元素 会继承父元素的 ScopeId!

子元素的 根元素 会继承父元素的 ScopeId!(说了三遍的话,肯定很重要)

由于子元素的 根元素 除了拥有自己的 ScopeId 属性,还继承了父元素的 ScopeId 属性,所以父元素的样式类 bg 对其依然有效

四、怎么破?

破解的方式也很简单,为每一个组件的根元素提供一个另类一点的样式名(如果有的话),例如就不要每个组件都命名为:wrap,根据业务名为:b1-wrap、b2-wrap 等

组件中的非根元素,类名不管怎么命名,怎么重名,都是不会发生污染的,这个自己领悟~~

五、这应当属于 Vue-loader 的一个 bug

没错,这应该是一个 bug,如果是我应该会怎么解呢,编译的时候不是增加属性,而是直接根据 scopeId 修改类名,嘿嘿~~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
兼容IE/Firefox/Opera/Safari的检测页面装载完毕的脚本Ext.onReady的实现
Jul 14 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
Jan 11 Javascript
js从Cookies里面取值的简单实现
Jun 30 Javascript
js事件绑定快捷键以ctrl+k为例
Sep 30 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
Mar 23 Javascript
js实现类似MSN提示的页面效果代码分享
Aug 24 Javascript
JS组件Bootstrap ContextMenu右键菜单使用方法
Apr 17 Javascript
Angular-Touch库用法示例
Dec 22 Javascript
Bootstrap中data-target 到底是什么
Feb 14 Javascript
Vue Promise的axios请求封装详解
Aug 13 Javascript
通过实例解析vuejs如何实现调试代码
Jul 16 Javascript
如何用vue实现网页截图你知道吗
Nov 17 Vue.js
js实现加载页面就自动触发超链接的示例
Aug 31 #Javascript
JavaScript基础之流程控制语句的用法
Aug 31 #Javascript
jquery操作ul的一些操作笔记整理(干货)
Aug 31 #jQuery
浅谈在fetch方法中添加header后遇到的预检请求问题
Aug 31 #Javascript
浅谈vue的踩坑路
Aug 31 #Javascript
对存在JavaScript隐式类型转换的四种情况的总结(必看篇)
Aug 31 #Javascript
[js高手之路]HTML标签解释成DOM节点的实现方法
Aug 31 #Javascript
You might like
php简单中奖算法(实例)
2017/08/15 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
PHP+Mysql分布式事务与解决方案深入理解
2021/02/27 PHP
js 纯数字不重复排列的另类方法
2010/07/17 Javascript
JavaScript学习笔记(一) js基本语法
2011/10/25 Javascript
JavaScript 参数中的数组展开 [译]
2012/09/21 Javascript
通过javascript获取iframe里的值示例代码
2013/06/24 Javascript
浅析js中的浮点型运算问题
2014/01/06 Javascript
javascript 实现子父窗体互相传值的简单实例
2014/02/17 Javascript
Html5的placeholder属性(IE兼容)实现代码
2014/08/30 Javascript
node.js中的url.parse方法使用说明
2014/12/10 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
AngularJS 使用 UI Router 实现表单向导
2016/01/29 Javascript
JS访问DOM节点方法详解
2016/11/29 Javascript
Json按某个键的值进行排序
2016/12/22 Javascript
Vue的Class与Style绑定的方法
2017/09/01 Javascript
vue.js 使用axios实现下载功能的示例
2018/03/05 Javascript
vue框架制作购物车小球动画效果实例代码
2019/09/26 Javascript
[57:16]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第二场
2014/05/26 DOTA
Python爬取Coursera课程资源的详细过程
2014/11/04 Python
Python2.x版本中maketrans()方法的使用介绍
2015/05/19 Python
python中快速进行多个字符替换的方法小结
2016/12/15 Python
python中利用xml.dom模块解析xml的方法教程
2017/05/24 Python
Pyinstaller将py打包成exe的实例
2018/03/31 Python
在Pycharm中项目解释器与环境变量的设置方法
2018/10/29 Python
python的移位操作实现详解
2019/08/21 Python
python-OpenCV 实现将数组转换成灰度图和彩图
2020/01/09 Python
python集合的新增元素方法整理
2020/12/07 Python
CSS3属性box-sizing使用指南
2014/12/09 HTML / CSS
Lacoste美国官网:经典POLO衫品牌
2016/10/12 全球购物
日本化妆品植村秀俄罗斯官方网站:Shu Uemura俄罗斯
2020/02/01 全球购物
Brasty罗马尼亚:购买手表、香水、化妆品、珠宝
2020/04/21 全球购物
工程造价专业大专生求职信
2013/10/06 职场文书
中医专业应届生求职信
2013/11/17 职场文书
森林防火工作方案
2014/02/14 职场文书
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
2021/06/26 MySQL