放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 前端

    • 前端 概览
    • 前端汇总

    • front 博文

    • front 项目总结

    • front 高级

    • front tools

  • vue

    • vue 概览
    • vue 汇总

    • vue 博文

    • vue 项目总结

    • vue 高级

      • vue 原理汇总
      • vue3新特性
      • watch原理
      • computed原理
      • vue响应式原理
      • vue双向数据绑定
      • key原理
      • 虚拟DOM
      • diff算法
      • keep-alive原理
      • nextTick原理
      • scoped原理
        • scoped 原理
          • scoped 的作用及优缺点
          • scoped 的实现原理
          • scoped 穿透
      • vue模板编译
      • vue渲染机制
      • vue api原理
      • vue实例方法原理
      • vue源码
  • html

    • html 概览
    • html 汇总

    • html 博文

  • css

    • css 概览
    • css 汇总

    • css 博文

    • sass

    • less

  • js

    • javascript 概览
    • JS 汇总

    • ES6

    • JS 博文

    • JS 工具

  • node

    • node 概览
    • node 汇总

    • node 框架

    • node 博文

  • react

    • react 概览
    • react 汇总

    • react 博文

    • react 高级

  • 微信小程序

    • 微信小程序 概览
    • 微信小程序总结
    • 微信小程序文章
    • 微信小程序 博文

    • 微信小程序 高级

  • 微信公众号

    • 微信公众号 概览
    • 微信公众号总结
    • 微信公众号文章
  • 多端开发

    • 多端开发
    • dsbridge 概览
    • jsbridge 概览
    • webview
    • uniapp

      • uniapp 概览
    • taro

      • taro 概览
    • flutter

      • flutter 概览
      • flutter 环境搭建
    • electron

      • electron 概览
  • front
放肆青春
2021-09-16

scoped原理

# scoped 原理

# scoped 的作用及优缺点

实现组件的私有化, 当前 style 属性只属于当前模块.

scoped 的缺点:

  1. scoped CSS 里每个样式的权重加重了(由于添加了 data 属性选择器),理论上我们可以修改某一个样式,但是却需要更高的权重去覆盖这个样式;

  2. 无论父组件样式的权重多大,也可能无法修改子组件的样式,除了子组件的根节点。

  3. 使用标签选择器时 scoped 会严重降低性能,而使用 class 或 id 则不会。

# scoped 的实现原理

scopeId 的生成方式:

(1)id 根据文件路径名和内容 hash 生成,通过组合形成 scopeId。每个 Vue 文件都将对应一个唯一的 id

(2)编译 template(使用 templateLoader) 标签时,会为每个标签添加了当前组件的 scopeId

在 templateLoader 中,会通过 vue-template-compiler 将 template 转换为 render 函数,在此过程中,

会将传入的 scopeId 追加到每个标签的 segments 上,最后作为 vnode 的配置属性传递给 createElemenet 方法, 在 render 函数调用并渲染页面时,会将 scopeId 属性作为原始属性渲染到页面上

(3)编译 style (使用 stylePostLoader)标签时,会根据当前组件的 scopeId 通过属性选择器和组合选择器输出样式

在 stylePostLoader 中,通过 PostCSS 解析 style 标签内容,同时通过 scopedPlugin 为每个选择器追加一个[scopeId]的属性选择器

总结:在 DOM 结构中可以发现,vue 通过在 DOM 结构以及 css 样式上加了唯一标记,达到样式私有化,不污染全局的作用,

可以看出,加上 scoped 后的组件里的会多 data-v-5db9451a 属性, css 样式中可以看出;

  1. 给 DOM 节点加一个不重复属性 data-v-5db9451a 标志唯一性.

  2. 使每个样式选择器后添加类似于"不重复属性"的字段, 类似于作用域的作用,不影响全局.

  3. 如果组件内部还有组件,只会给最外层的组件里的标签加上唯一属性字段,不影响组件内部引用的组件.

谨慎使用:

  1. 父组件无 scoped 属性,子组件带有 scoped,父组件是无法操作子组件的.

  2. 父组件有 scoped 属性,子组件无 scoped.父组件也无法设置子组件样式.因为父组件的所有标签都会带有 data-v-5db9451a 唯一标志,但子组件不会带有这个唯一标志属性.

  3. 父子组件都有,同理也无法设置样式,更改起来增加代码量.

# scoped 穿透

  1. 穿透 scoped

stylus 的样式穿透 使用 >>>

sass 和 less 的样式穿透 使用/deep/

  1. 添加单独的 style 标签

参考:刨根问底,揭开 Vue 中 Scope CSS 实现的幕后(原理) (opens new window) 浅析 Vue scoped 底层原理 (opens new window) 从 vue-loader 源码分析 CSS Scoped 的实现 (opens new window)

更新时间: 2/24/2022, 7:37:44 PM
nextTick原理
vue模板编译

← nextTick原理 vue模板编译→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式