理解vue中less的scoped和/deep/工作原理
理解vue中less的scoped和/deep/工作原理
- scoped
- /deep/
- 实战
- 总结
scoped
vue项目一般是单页面、多组件,整个项目共用一个css样式表,有时候我们在写组件的过程中并不希望组件的样式污染全局作用域(毕竟不同组件之间重名的class很正常),因此我们会在组件的样式标签上加上scoped,例如下面这个最基本vue组件框架:
<template>
...
</template><script>
import ...
export defualt {data(){...}...
}
</script><style lang="less" scoped>
...
</style>
那么这个scoped是什么意思呢?其实就是给每条样式的 最后面 加上一个属性选择器[哈希值]
,这个哈希值在项目里全局唯一,代表了当前这个组件。例如当前组件用到了 haha.vue , 那么在打包的时候就会编译出一个data-v-5cfc4ef6
来唯一代表这个组件。注意一个vue文件里可能有多个哈希值,因为一个组件里还可能嵌套了其他组件。
废话不多说,直接看scoped是怎么工作的。例如:
<style lang="less" scoped>.a{.b{background-color:#bfa}}
</style>
则打包编译后这个属性会变成这样:
.a .b[data-v-5cfc4ef6]
注意了,.a和.b之间有空格,表示父子元素;.b和[data-v-5cfc4ef6]无空格,表示并集。那么这条css语句什么意思呢?class为a
的元素下的 class为b
且具有data-v-5cfc4ef6
属性的元素。这样就做到了css样式只针对本组件(哈希值为data-v-5cfc4ef6
)的元素
/deep/
那么deep是什么呢?博主找遍全网,找到的信息大意都是:“能够让被scoped限制住的样式属性穿透到子组件”,简直tm在坑爹!这话是不错,但是说了等于没说:为什么平时写项目,同样都是引用自组件,有些地方用/deep/有些地方不用呢?经过我自己的摸索,发现/deep/的工作规律是这样的:
/deep/ === [哈希值]
啥意思呢?还是刚才那个例子,加一个deep:
<style lang="less" scoped>.a{/deep/.b{background-color:#bfa}}
</style>
那么编译后的结果就会是:
.a[data-v-5cfc4ef6] .b
注意这个.a
和[data-v-5cfc4ef6]
之间没有空格,表示并集;.a[data-v-5cfc4ef6]
和.b
之间是有空格的,表示子元素。
结合less的嵌套语法,我们发现是这样的:
/deep/某个属性前,表示父元素要拥有 哈希值
这个属性,而如果没有写/deep/,这个 哈希值
是会被scoped到叶子元素上的(最深的子元素,就像上一个例子所演示的那样)。
再举个例子:
/deep/div
会被打包编译成
[data-v-5cfc4ef6] div
注意有空格,表示父元素有 哈希值
这个属性的所有div元素,也就是这个组件下的所有div元素了。
实战
有同学会问了,既然scoped会自己帮我们把哈希值放在叶子元素上,为什么还要自己写/deep/来调整哈希值的位置呢?我曾经也有这样的疑问,直到我用了antd…
话不多说,直接看代码:
<template><div class="user-detail-wrap"><a-card :bodyStyle="{padding:'20px'}"><a-row:gutter="8"><a-col :sm="5" :xs="5" class="title">编辑角色<a @click="goBack"><img:src="returnIcon"style="height: 18px" /></a></a-col><a-col :sm="3" :xs="3" style="float:right;"><a-button type="primary" style="width:80px;float:right;" v-action:save @click="goSave">保存</a-button><a-modal:visible="confirmVisible"@cancel="handleCancel"><p class="title"><img :src="warningIcon" alt="" class="warning-icon"><span class="confirm-title">{{ confirmTitle }}</span></p><p class='confirm-text'>{{ confirmText }}</p><template slot="footer"><a-button key="back" @click="handleCancel">取消</a-button><a-button key="submit" type="primary" :loading="confirmLoading" @click="handleConfirm">修改</a-button></template></a-modal></a-col></a-row></a-card><a-card :bodyStyle="{padding:'20px'}" class="table-card"><a-row:gutter="8"><a-col :sm="5" :xs="5" class="title">基础信息</a-col></a-row><a-card-gridstyle="width:25%;padding:10px"v-for="(record, index) in roleInfoColums":key="index">{{ record.title }}: {{ roleInfo[record.dataIndex] }}</a-card-grid></a-card><a-card :bodyStyle="{padding:'20px'}" class="table-card"><a-row:gutter="8"><a-col :sm="5" :xs="5" class="title">权限信息</a-col></a-row><permission-tree:treeData="treeData":disableAll="false"@onSelectChange="onSelectChange"></permission-tree></a-card></div>
</template>
打包之后呈现出的部分DOM树是这样的:
可以看到,父元素ant-modal-root有哈希值,而子元素ant-modal-footer却没有,但是ant-modal-footer的两个button自元素又有哈希值了(可能是因为ant-modal-footer是我插入的另一个template slot的根元素)
<template slot="footer"><a-button key="back" @click="handleCancel">取消</a-button><a-button key="submit" type="primary" :loading="confirmLoading" @click="handleConfirm">修改</a-button></template>
这时候,如果不写deep,而是让scoped自己来的话
.ant-modal-root {.ant-modal-footer {border-top: 0;overflow: hidden;padding: 32px;padding-top:18px;}
}
就会编译出这样的css样式:
.ant-modal-root .ant-modal-footer[data-v-5cfc4ef6]
可是我tm上哪里找有data-v-5cfc4ef6属性的ant-modal-footer…
写上deep:
.ant-modal-root {/deep/.ant-modal-footer {border-top: 0;overflow: hidden;padding: 32px;padding-top:18px;}
}
就编译成了:
.ant-modal-root[data-v-5cfc4ef6] .ant-modal-footer
这下就能选中了。
总结
用到第三方组件的时候,经常会自己定义插槽slot来替换原组件里的内容,这时候就很容易遇到要手动用/deep/的问题。遇到这类问题的时候,不要盲目地用!important来提高优先级(这样不管用),甚至不加scoped写样式,或者直接通过import .less 引入外部样式来污染全局了(这样会有副作用)
理解vue中less的scoped和/deep/工作原理相关推荐
- vue中style的scoped属性这样用,修改第三方组件iview 或 element 样式
vue中style的scoped属性这样用,修改第三方组件iview 或 element 样式 文章目录 vue中style的scoped属性这样用,修改第三方组件iview 或 element 样式 ...
- vue中style的scoped属性的设计方式
vue中style的scoped属性这里是怎实现的呢? scoped三条渲染规则 给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性 在每句css选 ...
- [Vue][面试]你怎么理解vue中的diff算法?
你怎么理解vue中的diff算法? #####源码分析1:必要性,lifecycle.js–mountComponent() vue中一个组件一个watcher实例,而组件中可能存在很多个data中的 ...
- 深入理解vue中的slot与slot-scope (简单易懂)
走在前端的大道上 插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示.以及怎样显示由父组件来决定. 实际上,一个slot最核心的两个问题在这里就点出来了,是显示不显示和怎样显示. 由于 ...
- 前端面试 vue生命周期钩子是如何实现的?理解vue中模板编译原理?
生命周期钩子在内部会被vue维护成一个数组(vue 内部有一个方法mergeOption)和全局的生命周期合并最终转换成数组,当执行到具体流程时会执行钩子(发布订阅模式),callHook来实现调用. ...
- 如何理解vue中 同步异步
如何理解vue中 同步异步 同步异步 , 举个例子来说,一家餐厅吧来了5个客人,同步的意思就是说,来第一个点菜,点了个鱼,好, 厨师去捉鱼杀鱼,过了半小时鱼好了给第一位客人,开始下位一位客人,就这样一 ...
- 理解vue中的slot-scope=“scope“
理解vue中的slot-scope="scope" slot是插槽,slot-scope="scope"相当于一行的数据 <el-table-column ...
- 探讨Vue 数据监测原理-第五节-展开介绍 Vue中监测-【数组】数据的原理
文章目录 探讨一下Vue 数据监测的原理 本次探讨共的第五个章节 第五节:展开介绍 Vue中监测-[数组]数据的原理 1. 案例 1.1. 页面案例 2. 数组形式|对象形式爱好的区别 2.1. 页面 ...
- CPU CACHE中的VIPT与PIPT的工作原理
转自CPU CACHE中的VIPT与PIPT的工作原理_Linux与SoC的博客-CSDN博客 启动信息描述 内核启动过程中有如下打印信息: CPU: PIPT / VIPT nonaliasing ...
最新文章
- 【SQL Server】系统学习之一:表表达式
- 从“诺奖级”成果到“非主观造假”,时隔6年,韩春雨带着原一作,再发高分文章!...
- linux(ubuntu) 查看系统设备信息 命令
- 【Python】Pyecharts数据可视化模块练习
- uwsgi指定python路径_uWsgi服务器(2)--安装配置
- 高起专计算机应用基础试题及答案,重庆大学网络教育高起专计算机应用基础入学考试模拟题及答案(二)...
- 吉林大学不如温州大学,泰晤士最新世界大学排名引发争议
- 中科院回应木兰语言造假:当事人已停职;中国软件业务收入百强:华为蝉联十八冠;Ionic 5.0.0-beta.5 发布|极客头条...
- 你们都用什么反编译工具?
- (转载)Web各大服务器区分(整理)
- html英文书籍推荐,Html英文
- 基于WizFi220的Cosmo WiFi扩展板
- 使用Raspberry Pi搭建迅雷离线下载机
- iOS常见崩溃以及总结
- 小程序中自定义组件、父子传值的具体步骤(秒懂)
- flex android开发中关于请求报文技术操作问题
- 纯css画一个月亮的天气图标
- 物联网智慧物流平台开发
- scala特质 对比java的接口 使用方法
- curl命令发送Post请求