深入理解vue-cli的组件化开发中scoped的底层原理

简介: > 持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,[点击查看活动详情](https://juejin.cn/post/7147654075599978532 "https://juejin.cn/post/7147654075599978532")# 引言在 vue-cli组件化开发中,有时候注册使用的组件会渲染到index.html中指定的div区域中,这就导致了样式间可能会因重名或等等原因发生**样式冲突**接下来我们简单回顾一下组件开发及样式冲突问题。## 组件化开发中的样式冲突我们初始化了一个vue-cli 项目,并在compone
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天, 点击查看活动详情

引言

在 vue-cli组件化开发中,有时候注册使用的组件会渲染到index.html中指定的div区域中,这就导致了样式间可能会因重名或等等原因发生样式冲突

接下来我们简单回顾一下组件开发及样式冲突问题。

组件化开发中的样式冲突

我们初始化了一个vue-cli 项目,并在components目录下创建up.vue(上组件),down.vue(下组件)和all.vue

上组件代码

<template>
    <div class="upStyle">
        {{updata}}
    </div>
  </template>
  
  <style lang="less">
    .upStyle {
        width: 300px;
        height: 300px;
        background-color: greenyellow;
    }
  </style>
  
  <script>
    export default {
        data(){
            return {
                updata:"这是上组件"
            }
        }
    }
  </script>

下组件代码

<template>
    <div class="downStyle">
        {{downdata}}
    </div>
  </template>
  
  <style lang="less">
    .downStyle {
        width: 300px;
        height: 300px;
        background-color: rebeccapurple;
    }
  </style>
  
  <script>
    export default {
        data(){
            return {
                downdata:"这是下组件"
            }
        }
    }
  </script>

全局组件代码

<template>
    <div>
        <div class="data">
            {{allData}}
        </div>
    </div>
</template>

<style scoped>
    div {
        color: brown;
    }
    .data {
        width: 60px;
        height: 60px;
    }
</style>

<script>
export default {
    data(){
        return {
            allData:"All组件"
        }
    }
}
</script>

接下来我们在App.vue中注册左右组件

<script>
import  up  from "@/components/up.vue";
import  down  from '@/components/down.vue';
export default {
  components:{
    up,down
  }
}
</script>

上面是注册的核心代码,引入并注册之后就可以将 up 和 down 作为标签在template中使用。

import all from '@/components/all.vue';

Vue.component('MyCount',all);

main.js的全局注册及使用如上,

接下来我们开始先简单解释一下,因为我们这里主要目的是剖析scoped的底层原理,这里我们不详细解释删去scoped和加上的区别。只是在下面附上冲突和解决样式冲突后的对比图。

这是冲突的效果

image.png

可以看到下部分字体依旧是黑色,并没有因全局组件的引入而改变颜色,也就是没有发生样式冲突。

接下来我们删去scoped,看看效果。

image.png

可以看到发生了样式冲突吗,下组件并没有引入这个全局组件all.vue但是同样字体颜色发生了改变。

这就是样式冲突,有时候样式冲突会非常影响我们的开发。

scoped的底层原理

接下来我们不使用scoped,来通过纯粹的css来解决这个问题。

先回忆一下css中几个选择器。

组合 Combinators
名称 语法 说明 示例

直接组合        AB        满足A同时满足B              input.error, a.error
后代组合        A B       选中B,如果他是A的子孙       nav a   b 在 a里面 只要所有的a标签 出现在 nav下面 不管隔了多少级 都会被选中
亲子组合        A>B       选中B,如果他是A的子元素     section>p   必须直接
兄弟选择器      A~B       选中B,如果他在A后且和A同级   h2~p      同级 同一个父级 并列
相邻选择器      A+B       选中B,如果他紧跟A后面        h2+p      紧跟着的兄弟选择器

我们简单回顾一下选择器,可能很多聪明的基础很好的同学已经猜到了其中的底层原理。

没错,我们就是通过组合Combinators来选择指定的样式。

从而解决我们的样式冲突问题。

接下来我们开始操作。

接下来我们开始改变我们的all.vue组件

<template>
    <div>
        <div class="data">
            {{allData}}
        </div>
    </div>
</template>

<style>
    .allStyle div {
        color: brown;
    }
    .allStyle .data {
        width: 60px;
        height: 60px;
    }
</style>

<script>
export default {
    data(){
        return {
            allData:"All组件"
        }
    }
}
</script>

改变的部分:

image.png

可以看到,这里我们并没有使用 scoped属性,只是单纯的使用了css的Combinators组合来进行选择,这里我们使用的后代选择器。

up.vue中我们也需要做一点点改动。

代码如下:

<template>
    <div class="upStyle">
        {{updata}}
        <MyCount class="allStyle"></MyCount>来了
    </div>
  </template>
  
  <style lang="less">
    .upStyle {
        width: 300px;
        height: 300px;
        background-color: greenyellow;
    }
  </style>
  
  <script>
    export default {
        data(){
            return {
                updata:"这是上组件"
            }
        }
    }
  </script>

我们重点看一下改变的部分

我们先简单观察一下代码,我们在上组件中引入的全局组件,结合之前的我们做的后代选择器,所以这里我们需要加上之前加的 allStyle

这样我们赋予特定属性的元素才会被选择到,而其他的并不会被选到(受到影响)

image.png

可以看到,我们的额外又加入了allStyle类,让他被我们选择到

那么我们可以发现scoped的底层原理了,每个加入scoped的属性的组件,都会赋予一个独特的,关键词,本质上其实就是css的组合选择器。

这就是scoped的底层原理。

相关文章
|
2月前
|
监控 JavaScript 前端开发
使用Vue.js开发员工上网行为监控的实时数据展示页面
使用Vue.js开发的实时员工上网行为监控页面,展示员工访问的网站、应用和时间等数据。页面响应式设计,适应不同设备。通过Vue组件显示实时数据,如`&lt;li v-for=&quot;activity in activities&quot;&gt;`循环渲染。数据定时更新,利用Vue的生命周期钩子和axios从服务器获取并自动刷新,确保数据的时效性。该页面有助于管理者即时了解员工网络活动,保障企业网络安全和资源管理。
163 5
|
4天前
|
JavaScript 算法 编译器
vue3 原理 实现方案
【8月更文挑战第15天】vue3 原理 实现方案
16 1
|
12天前
|
Web App开发 人工智能 JavaScript
开发时遇到的问题以及一些实用小技巧(vue)
开发时遇到的问题以及一些实用小技巧
|
4天前
|
JavaScript API
Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)
这篇博客文章讲解了Vue中列表排序的方法,使用`filter`、`sort`和`indexOf`等数组方法进行数据的过滤和排序,并探讨了Vue检测数据变化的原理,包括Vue如何通过setter和数组方法来实现数据的响应式更新。
Vue学习之--------列表排序(ffilter、sort、indexOf方法的使用)、Vue检测数据变化的原理(2022/7/15)
|
4天前
|
JavaScript
Vue学习之--------列表渲染、v-for中key的原理、列表过滤的实现(2022/7/13)
这篇博客文章详细介绍了Vue中列表渲染的基础知识、`v-for`指令的使用、`key`的原理和列表过滤的实现。通过代码实例和测试效果,展示了如何遍历数组和对象、使用`key`属性优化渲染性能,以及如何实现列表的动态过滤功能。
Vue学习之--------列表渲染、v-for中key的原理、列表过滤的实现(2022/7/13)
|
9天前
|
JavaScript 前端开发 算法
vue底层原理实现方案
【8月更文挑战第10天】vue底层原理实现方案
25 2
|
11天前
|
JavaScript UED
强制 Vue 重新渲染组件的5种方法,解决你开发过程中数据和视图无法同步的Bug。
强制 Vue 重新渲染组件的5种方法,解决你开发过程中数据和视图无法同步的Bug。
|
22天前
|
JavaScript
Vue 开发技巧·1
Vue 开发技巧
33 7
|
10天前
|
JavaScript 前端开发 搜索推荐
揭秘 Vue 3 的 Teleport 特性,让你实现跨组件传输内容,使得开发变得更加得心应手!!
揭秘 Vue 3 的 Teleport 特性,让你实现跨组件传输内容,使得开发变得更加得心应手!!
|
18天前
|
SQL 开发框架 前端开发
基于SqlSugar的开发框架循序渐进介绍(29)-- 快速构建系统参数管理界面-Vue3+ElementPlus
基于SqlSugar的开发框架循序渐进介绍(29)-- 快速构建系统参数管理界面-Vue3+ElementPlus