首页 > 编程知识 正文

vue中的意思,scoped属性

时间:2023-05-03 19:09:50 阅读:160654 作者:3307

在' vue组件中,将scoped属性添加到" style "标签中,以表明该样式影响了当前模块,从而很好地实现了样式的私有化。 这是非常好的机制。 但是为什么要慎重使用呢? 在实际工作中,经常对常见组件的样式进行精细调整,添加scoped属性会使样式更难修改。 最初写这篇文章的时候,我没有找到解决这个问题的好办法,后来经过大家的解答,我才恍然大悟。'

谨慎使用,不是不用,而是要有眼光。 scoped一定解决了风格私有化的问题,但同时也引入了新的问题。 样式难以修改,往往需要对公共组件的样式进行微调。 所以我说要慎重使用

解决方案首先要说明的问题是,最初我觉得这是个bug或者弊端,不理解scoped的真正作用,所以勇敢地提出了issue。 然后,像理所当然的那样被关闭了。 关闭的理由是,scoped设计的初衷是使样式私密,不影响其他任何地方的样式。 但是,由于我在工作中经常遇到需要修改具有scoped属性的组件,所以我写了一篇记录此问题的文章,希望您慎重使用此属性。

但事实再次证明了我的愚蠢,在vue-loader文档中已经详细分析了这个问题,并为我遇到这个问题提供了解决方法。 vue-loader的深度作用选择器。

我不深刻理解这些问题,这篇文章注定要被大家敲打吗? 是什么? 是什么? 是什么? 是什么? 是什么?

解决方案: vue-loader的scoped-css

scoped实现私有化风格的原理为什么说会增加复杂性? 那么,从实现的模块的原理开始吧。 为了方便起见,我们假设这样的组件称为模块专用组件,没有其他scoped的称为模块通用组件。

通过查看DOM结构发现,vue通过对DOM结构和css样式进行唯一、不重复的标记,保证了唯一性,达到了样式的私有化模块化。 通过一个例子说明具体的渲染结果是什么样的。

公共组件button组件button添加了scoped属性以实现样式模块化。

//button.vuetemplatedivclass=' button-warp ' button class=' button ' text/button/div/template . style scoped 字体大小: 12px; border-radus: 2px; }/style浏览器渲染的button组件button组件浏览器渲染的html部分和css部分分别为:

div data-v-2311 c06 aclass=' button-warp ' button data-v-2311 c06 aclass=' button ' text/button/div.button-war 字体大小: 12px; border-radus: 2px; }从上面的文字可以看出,添加了scoped属性的组件要实现组件样式的模块化,需要执行以下两个操作:

在HTML的DOM节点中添加非重复的data属性以表示他的唯一性,例如data-v-2311c06a

通过将当前组件的data属性选择器(例如[data-v-2311c06a] )添加到每个语句的css选择器末尾(编译后生成的css语句)来将样式个性化

众所周知,css样式有优先权。 scoped的这个操作虽然达到了组件样式模块化的目的,但是每个样式的权重会变重。 理论上,修改这种风格需要更高的权重。 这是增加复杂性的维度之一。

其他组件引用了button组件,并分析了各个组件呈现的结果,但是在组件相互调用后会出现什么结果呢? 具体地说,模块一般组件引用模块专用组件(本质上与模块专用组件引用模块一般组件相同); 模块的专用组件引用模块的专用组件。

例如,如果在组件content.vue中使用button组件,则在content.vue组件中添加scoped属性进行渲染的结果会有什么区别呢?

//content.vuetemplatedivclass=' content ' pclass=' title '/p! -- v-button假设是上面定义的组件-- v-button/v-button /divg

t;</template>...<style> .content{ width: 1200px; margin: 0 auto; } .content .button{ border-raduis: 5px; }</style>

模块一般组件(未添加scoped)引用模块私有组件
如果style上没有加scoped属性,那么渲染出来html和css分别就是:

<div class="content"> <p class="title"></p> <!-- v-button假设是上面定义的组件 --> <div data-v-2311c06a class="button-warp"> <button data-v-2311c06a class="button">text</button> </div></div>/*button.vue渲染出来的css*/.button-warp[data-v-2311c06a]{ display:inline-block;}.button[data-v-2311c06a]{ padding: 5px 10px; font-size: 12px; border-radus: 2px;}/*content.vue渲染出来的css*/.content{ width: 1200px; margin: 0 auto;}.content .button{ border-raduis: 5px;}

可以看出,虽然在content组件中,修改了button的border-raduis属性,但是由于权重关系,生效的依然是组件内部的样式(此时是外部的样式被覆盖)。所以如果要达到修改样式的目的,就必须加重我们要修改样式的权重(增加选择器层级,ID选择器,并列选择器,impotant等)

模块私有组件(添加scoped)引用模块私有组件

如果加了scoped属性呢?按照开始分析出来的规则(事实也是这么的):
首先是在所有的DOM节点加上data属性
然后在css选择器尾部加上data属性选择器

那么渲染出来html和css分别就是:

<div data-v-57bc25a0 class="content"> <p data-v-57bc25a0 class="title"></p> <!-- v-button假设是上面定义的组件 --> <div data-v-57bc25a0 data-v-2311c06a class="button-warp"> <button data-v-2311c06a class="button">text</button> </div></div>/*button.vue渲染出来的css*/.button-warp[data-v-2311c06a]{ display:inline-block;}.button[data-v-2311c06a]{ padding: 5px 10px; font-size: 12px; border-radus: 2px;}/*content.vue渲染出来的css*/.content[data-v-57bc25a0]{ width: 1200px; margin: 0 auto;}.content .button[data-v-57bc25a0]{ border-raduis: 5px;}

对于上面的两种情况,可以明显看出来渲染后的结果大不相同。
虽然我们在content添加了想要修改button组件的样式的代码,但是仔细看,由于.content .button这句在末尾加的是content组件的scoped标记,最后这句其实根本作用不到我们想要的DOM节点上,所以这种情况我们在content内部写的任何样式都不会影响到button.vue组件,所以这就尴尬了。。。。
当然这个问题也是可以解决的,就是直接加全局样式可以修改到,但这势必会影响全部地方的组件;所以需要另外一种方法在content.vue组件内再加一个不带scoped属性的style标签,也就意味着要加两个style,一个用于私有样式,一个用于共有样式。这肯定是有点shit的,并且这两种解决方案都回避不了一个问题:权重!!!

//content.vue<template> <div class="content"> <p class="title"></p> <!-- v-button假设是上面定义的组件 --> <v-button></v-button> </div></template>...<style scoped> .content{ width: 1200px; margin: 0 auto; }</style><style> .content .button{ border-raduis: 5px; }</style>

这样符合规范么?貌似没看到不能这么写,并且这么写也确实生效了。。。但这样确实增加了思维的复杂度,有点苦恼啊。

总结scoped的渲染规则

总结一下scoped三条渲染规则

给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性
在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式
如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性

解决方案

对于引用的三方库,如果对方使用了scoped,我们无力改变什么,如果确实需要修改他的样式最能在不加scoped的组件中修改样式,或者全局样式直接修改,这很粗暴!
对于自己维护的组件,一定要想清楚,组件的样式能否满足所有的情况。如果确实需要加,无疑会增加使用这个组件的开发同学的工作!

当然对于这个问题,如果诸君有更好的解决方案,请诸君TELL ME一下下!

趣事

在使用scoped一定要谨慎scoped的这个特性,本人以为这是一个BUG,就去提了issue ,结果尤大很霸气的回复
scoped设计的初衷就是不能让当前组件的样式修改其他任何地方的样式,因为设计如此。所以理所当然的这个issue已被干掉。。。??????

本文转载地址

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。