Vue中scoped工作原理以及使用情景

为什么要使用scoped

vue中为了让样式私有化,不至于当前组件的css样式对全局造成污染,添加了scoped属性,但同时也要慎重的使用,因为一旦出现问题,排查起来可能会很麻烦。

scoped工作原理

我们平时开发vue的时候可能会比较好奇,经常会看到data-v-asf23235kd33k在dom元素中出现,其实这就是scoped做的事情,比如我们一个button组件,我们定义了如下scoped样式,给按钮添加一个边框弧度。

<template>
	<button class="button">text</button>
</template>
<style scoped>
.button {
    border-raduis: 1px;
}
</style>

这样最终渲染出来的页面代码应该是这样的

<button class="button" data-v-123lsdfasi32>
    text
</button>
.button[data-v-123lsdfasi32]{
	border-raduis: 1px;
}

可以看到这样一来,本页面定义为scoped下的样式属性,仅可能作用于当前组件,即使该组件被引用,也不会和其他的button属性产生冲突。

总结:

  1. 给DOM节点添加一个标志属性
  2. 给渗透DOM节点的样式属性添加一个属性选择器。(间接提升了样式的权重)

对上述情况做一下补充说明,css属性会叠加,类属性和属性选择权重为 0 0 1 0,叠加后权重变为0 0 2 0,所以通过一个简单的类属性可能无法覆盖了,需要一个id选择器或者内联样式。

实际使用

在引用组件到页面中的时候,总是会有需求说本页面修改一下组件的样式吧,但是由于scoped属性产生的data-v-12jfsjjj只会作用于组件DOM元素的最外层标签,所以父组件的样式不会渗透到子组件中去【这里要自行理解一下为什么无法渗透,不做举例】。如果不使用scoped又怕样式渗透到全局?可以使用渗透scoped穿透,个人理解这样的工作原理为沿用子组件生成的序列号,不重新生成。

.outer /deep/ .button {  // outer为组件外层属性样式名称,没有的话也可以不加
    border-raduis: 1px;
}

注意,如果使用stylus,渗透符号为 >>>

动态生成的DOM类名可能在scoped中也不会有作用,这个时候也可以添加/deep/来让样式生效。

问题回顾

在之前的项目中,有一次样式污染导致了一个比较严重的后果,我的自定义的一个折叠框,当项目一开始运行的时候不会出问题,但是项目运行一段时间之后,折叠框的内容就都看不到了,DOM节点都是有的,样式却变成了

opacity: 0;

这个问题当时我通过行内样式设置为!important解决掉了,由于开发的是移动端,结果发现这个问题耗费了很长的时间,当时没有细究,今天学习后发现有一个组件使用过程中定义了一个和我一样的class属性,但是他却没有把这个属性放到<scoped>中(当然了,作为一个公共组件组件这样使用肯定是不合理的),直接导致了他的样式合并到了同名的我的样式中,导致了这个问题,希望大家引以为戒。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值